diff --git a/rollup.config.mjs b/rollup.config.mjs index 56ebdaa7558f..d6a22733a401 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -14,136 +14,113 @@ const is_publish = !!process.env.PUBLISH; const ts_plugin = is_publish ? typescript({ - typescript: require('typescript') - }) + typescript: require('typescript'), + }) : sucrase({ - transforms: ['typescript'] - }); + transforms: ['typescript'], + }); -// The following external and path logic is necessary so that the bundled runtime pieces and the index file -// reference each other correctly instead of bundling their references to each other +fs.writeFileSync( + `./compiler.d.ts`, + `export { compile, parse, preprocess, walk, VERSION } from './types/compiler/index.js';` +); -/** - * Ensures that relative imports inside `src/runtime` like `./internal` and `../store` are externalized correctly - */ -const external = (id, parent_id) => { - const parent_segments = parent_id.replace(/\\/g, '/').split('/'); - // TODO needs to be adjusted when we move to JS modules - if (parent_segments[parent_segments.length - 3] === 'runtime') { - return /\.\.\/\w+$/.test(id); - } else { - return id === './internal' && parent_segments[parent_segments.length - 2] === 'runtime'; - } -} - -/** - * Transforms externalized import paths like `../store` into correct relative imports with correct index file extension import - */ -const replace_relative_svelte_imports = (id, ending) => { - id = id.replace(/\\/g, '/'); - // TODO needs to be adjusted when we move to JS modules - return /src\/runtime\/\w+$/.test(id) && `../${id.split('/').pop()}/${ending}`; -} +const runtime_entrypoints = Object.fromEntries( + fs + .readdirSync('src/runtime', { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => [dirent.name, `src/runtime/${dirent.name}/index.ts`]) +); /** - * Transforms externalized `./internal` import path into correct relative import with correct index file extension import + * @type {import("rollup").RollupOptions[]} */ -const replace_relative_internal_import = (id, ending) => { - id = id.replace(/\\/g, '/'); - // TODO needs to be adjusted when we move to JS modules - return id.endsWith('src/runtime/internal') && `./internal/${ending}`; -} - -fs.writeFileSync(`./compiler.d.ts`, `export { compile, parse, preprocess, walk, VERSION } from './types/compiler/index';`); - export default [ - /* runtime */ { - input: `src/runtime/index.ts`, - output: [ - { - file: `index.mjs`, - format: 'esm', - paths: id => replace_relative_internal_import(id, 'index.mjs') - }, - { - file: `index.js`, - format: 'cjs', - paths: id => replace_relative_internal_import(id, 'index.js') - } - ], - external, - plugins: [ts_plugin] - }, + input: { + ...runtime_entrypoints, + index: 'src/runtime/index.ts', + ssr: 'src/runtime/ssr.ts' + }, + output: ['es', 'cjs'].map( + /** @returns {import('rollup').OutputOptions} */ + (format) => { + const ext = format === 'es' ? 'mjs' : 'js'; + return { + entryFileNames: (entry) => { + if (entry.isEntry) { + if (entry.name === 'index') return `index.${ext}`; + else if (entry.name === 'ssr') return `ssr.${ext}`; - { - input: `src/runtime/ssr.ts`, - output: [ - { - file: `ssr.mjs`, - format: 'esm', - paths: id => replace_relative_internal_import(id, 'index.mjs') - }, - { - file: `ssr.js`, - format: 'cjs', - paths: id => replace_relative_internal_import(id, 'index.js') + return `${entry.name}/index.${ext}`; + } + }, + chunkFileNames: `internal/[name]-[hash].${ext}`, + format, + minifyInternalExports: false, + dir: '.', + }; } - ], - external, - plugins: [ts_plugin] - }, - - ...fs.readdirSync('src/runtime') - .filter(dir => fs.statSync(`src/runtime/${dir}`).isDirectory()) - .map(dir => ({ - input: `src/runtime/${dir}/index.ts`, - output: [ - { - file: `${dir}/index.mjs`, - format: 'esm', - paths: id => replace_relative_svelte_imports(id, 'index.mjs') + ), + plugins: [ + replace({ + preventAssignment: true, + values: { + __VERSION__: pkg.version, }, - { - file: `${dir}/index.js`, - format: 'cjs', - paths: id => replace_relative_svelte_imports(id, 'index.js') - } - ], - external, - plugins: [ - replace({ - __VERSION__: pkg.version - }), - ts_plugin, - { - writeBundle(_options, bundle) { + }), + ts_plugin, + { + writeBundle(options, bundle) { + if (options.format !== 'es') return; + + for (const entry of Object.values(bundle)) { + const dir = entry.name; + if (!entry.isEntry || !runtime_entrypoints[dir]) continue; + if (dir === 'internal') { - const mod = bundle['index.mjs']; + const mod = bundle[`internal/index.mjs`]; if (mod) { - fs.writeFileSync('src/compiler/compile/internal_exports.ts', `// This file is automatically generated\nexport default new Set(${JSON.stringify(mod.exports)});`); + fs.writeFileSync( + 'src/compiler/compile/internal_exports.ts', + `// This file is automatically generated\n` + + `export default new Set(${JSON.stringify(mod.exports)});` + ); } } - fs.writeFileSync(`${dir}/package.json`, JSON.stringify({ - main: './index', - module: './index.mjs', - types: './index.d.ts' - }, null, ' ')); + fs.writeFileSync( + `${dir}/package.json`, + JSON.stringify( + { + main: './index.js', + module: './index.mjs', + types: './index.d.ts', + }, + null, + ' ' + ) + ); - fs.writeFileSync(`${dir}/index.d.ts`, `export * from '../types/runtime/${dir}/index';`); + fs.writeFileSync( + `${dir}/index.d.ts`, + `export * from '../types/runtime/${dir}/index.js';` + ); } } - ] - })), - + } + ] + }, /* compiler.js */ { input: 'src/compiler/index.ts', plugins: [ replace({ - __VERSION__: pkg.version, - 'process.env.NODE_DEBUG': false // appears inside the util package + preventAssignment: true, + values: { + __VERSION__: pkg.version, + 'process.env.NODE_DEBUG': false // appears inside the util package + }, }), { resolveId(id) { @@ -152,7 +129,7 @@ export default [ if (id === 'util') { return require.resolve('./node_modules/util'); // just 'utils' would resolve this to the built-in module } - } + }, }, resolve(), commonjs({ @@ -177,6 +154,7 @@ export default [ ], external: is_publish ? [] - : id => id === 'acorn' || id === 'magic-string' || id.startsWith('css-tree') + : (id) => + id === 'acorn' || id === 'magic-string' || id.startsWith('css-tree') } ];