chore(test): use esm output for Svelte files (#8614)

pull/8619/head
gtmnayan 1 year ago committed by GitHub
parent c2cec9597e
commit d6b02ed009
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -34,15 +34,9 @@ describe('css', () => {
const expected_warnings = (config.warnings || []).map(normalize_warning);
const dom = svelte.compile(
input,
Object.assign({}, config.compileOptions || {}, { format: 'cjs' })
);
const dom = svelte.compile(input, Object.assign({}, config.compileOptions || {}));
const ssr = svelte.compile(
input,
Object.assign({}, config.compileOptions || {}, { format: 'cjs', generate: 'ssr' })
);
const ssr = svelte.compile(input, Object.assign({}, config.compileOptions || {}));
assert.equal(dom.css.code, ssr.css.code);
@ -75,7 +69,7 @@ describe('css', () => {
// we do this here, rather than in the expected.html !== null
// block, to verify that valid code was generated
const load = create_loader({ ...(config.compileOptions || {}), format: 'cjs' }, cwd);
const load = create_loader({ ...(config.compileOptions || {}) }, cwd);
try {
ClientComponent = (await load('input.svelte')).default;
} catch (err) {
@ -83,10 +77,7 @@ describe('css', () => {
throw err;
}
const load_ssr = create_loader(
{ ...(config.compileOptions || {}), generate: 'ssr', format: 'cjs' },
cwd
);
const load_ssr = create_loader({ ...(config.compileOptions || {}), generate: 'ssr' }, cwd);
try {
ServerComponent = (await load_ssr('input.svelte')).default;
} catch (err) {

@ -103,6 +103,8 @@ export function show_output(cwd, options = {}) {
const svelte_path = fileURLToPath(new URL('..', import.meta.url)).replace(/\\/g, '/');
const AsyncFunction = /** @type {typeof Function} */ (async function () {}.constructor);
export function create_loader(compileOptions, cwd) {
const cache = new Map();
@ -110,46 +112,100 @@ export function create_loader(compileOptions, cwd) {
if (cache.has(file)) return cache.get(file);
if (file.endsWith('.svelte')) {
const options = {
...compileOptions,
filename: file
};
const compiled = compile(
// Windows/Linux newline conversion
fs.readFileSync(file, 'utf-8').replace(/\r\n/g, '\n'),
{
...compileOptions,
filename: file
}
options
);
const imports = new Map();
const __import = (id) => {
let resolved = id;
for (const match of compiled.js.code.matchAll(/require\("(.+?)"\)/g)) {
const source = match[1];
let resolved = source;
if (source.startsWith('.')) {
resolved = path.resolve(path.dirname(file), source);
if (id.startsWith('.')) {
resolved = path.resolve(path.dirname(file), id);
}
if (source === 'svelte') {
if (id === 'svelte') {
resolved = `${svelte_path}src/runtime/index.js`;
}
if (source.startsWith('svelte/')) {
resolved = `${svelte_path}src/runtime/${source.slice(7)}/index.js`;
if (id.startsWith('svelte/')) {
resolved = `${svelte_path}src/runtime/${id.slice(7)}/index.js`;
}
imports.set(source, await load(resolved));
}
function require(id) {
return imports.get(id);
return load(resolved);
};
const exports = [];
// We can't use Node's or Vitest's loaders cause we compile with different options.
// We need to rewrite the imports into function calls that we can intercept to transform
// any imported Svelte components as well. A few edge cases aren't handled but also
// currently unused in the tests, for example `export * from`and live bindings.
let transformed = compiled.js.code
.replace(
/^import \* as (\w+) from ['"]([^'"]+)['"];?/gm,
'const $1 = await __import("$2");'
)
.replace(
/^import (\w+) from ['"]([^'"]+)['"];?/gm,
'const {default: $1} = await __import("$2");'
)
.replace(
/^import (\w+, )?{([^}]+)} from ['"](.+)['"];?/gm,
(_, default_, names, source) => {
const d = default_ ? `default: ${default_}` : '';
return `const { ${d} ${names.replaceAll(
' as ',
': '
)} } = await __import("${source}");`;
}
)
.replace(/^export default /gm, '__exports.default = ')
.replace(
/^export (const|let|var|class|function|async\s+function) (\w+)/gm,
(_, type, name) => {
exports.push(name);
return `${type} ${name}`;
}
)
.replace(/^export \{([^}]+)\}(?: from ['"]([^'"]+)['"];?)?/gm, (_, names, source) => {
const entries = names.split(',').map((name) => {
const match = name.trim().match(/^(\w+)( as (\w+))?$/);
const i = match[1];
const o = match[3] || i;
return [o, i];
});
return source
? `{ const __mod = await __import("${source}"); ${entries
.map(([o, i]) => `__exports.${o} = __mod.${i};`)
.join('\n')}}`
: `{ ${entries.map(([o, i]) => `__exports.${o} = ${i};`).join('\n')} }`;
});
exports.forEach((name) => {
transformed += `\n__exports.${name} = ${name};`;
});
const __exports = {
[Symbol.toStringTag]: 'Module'
};
try {
const fn = new AsyncFunction('__import', '__exports', transformed);
await fn(__import, __exports);
} catch (err) {
console.error({ transformed }); // eslint-disable-line no-console
throw err;
}
const fn = new Function('require', 'exports', 'module', compiled.js.code);
const module = { exports: {} };
fn(require, module.exports, module);
cache.set(file, module.exports);
return module.exports;
cache.set(file, __exports);
return __exports;
} else {
return import(file);
}

@ -21,7 +21,6 @@ describe('hydration', async () => {
const compileOptions = Object.assign({}, config.compileOptions, {
accessors: 'accessors' in config ? config.accessors : true,
format: 'cjs',
hydratable: true
});

@ -56,7 +56,6 @@ async function run_test(dir) {
const cwd = path.resolve(`${__dirname}/samples/${dir}`);
const compileOptions = Object.assign({}, config.compileOptions || {}, {
format: 'cjs',
hydratable: hydrate,
immutable: config.immutable,
accessors: 'accessors' in config ? config.accessors : true

@ -3,7 +3,7 @@
import { create_loader } from '../helpers';
import { assert, it } from 'vitest';
const load = create_loader({ generate: 'dom', dev: true, format: 'cjs' }, __dirname);
const load = create_loader({ generate: 'dom', dev: true }, __dirname);
const { default: App } = await load('App.svelte');
it('fails if options.target is missing in dev mode', async () => {

@ -30,8 +30,7 @@ describe('ssr', async () => {
const compileOptions = {
...config.compileOptions,
generate: 'ssr',
format: 'cjs'
generate: 'ssr'
};
const load = create_loader(compileOptions, dir);

@ -33,8 +33,7 @@ function run_runtime_samples(suite) {
it_fn(dir, async () => {
const compileOptions = {
...config.compileOptions,
generate: 'ssr',
format: 'cjs'
generate: 'ssr'
};
const load = create_loader(compileOptions, cwd);

Loading…
Cancel
Save