diff --git a/package.json b/package.json index 477f252edd2f9a..27ab3da8fb25c3 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,7 @@ "rollup-plugin-web-worker-loader": "^1.3.1", "selfsigned": "^1.10.8", "slash": "^3.0.0", + "systemjs": "^6.7.1", "vue": "^3.0.2", "ws": "^7.3.1" }, diff --git a/src/node/build/buildPluginHtml.ts b/src/node/build/buildPluginHtml.ts index da2f8739e9e4bc..e125c209f6224d 100644 --- a/src/node/build/buildPluginHtml.ts +++ b/src/node/build/buildPluginHtml.ts @@ -28,6 +28,7 @@ export const createBuildHtmlPlugin = async ( inlineLimit: number, resolver: InternalResolver, shouldPreload: ((chunk: OutputChunk) => boolean) | null, + useSystemJs: boolean | string, config: UserConfig ) => { if (!fs.existsSync(indexPath)) { @@ -80,11 +81,30 @@ export const createBuildHtmlPlugin = async ( } } + const injectSystemJs = (html: string) => { + let tag: string + if (typeof useSystemJs === 'string') { + tag = `` + } else { + const systemJsRuntime = fs + .readFileSync(require.resolve('systemjs/dist/s.min.js'), 'utf8') + .replace(/\n\/\/# sourceMappingURL=[^\n]+\n$/, '') + + tag = `` + } + if (/<\/head>/.test(html)) { + return html.replace(/<\/head>/, `${tag}\n`) + } + return tag + '\n' + html + } + const injectScript = (html: string, filename: string) => { filename = isExternalUrl(filename) ? filename : `${publicBasePath}${path.posix.join(assetsDir, filename)}` - const tag = `` + const tag = useSystemJs + ? `` + : `` if (/<\/head>/.test(html)) { return html.replace(/<\/head>/, `${tag}\n`) } else { @@ -105,7 +125,7 @@ export const createBuildHtmlPlugin = async ( } const renderIndex = async (bundleOutput: RollupOutput['output']) => { - let result = processedHtml + let result = useSystemJs ? injectSystemJs(processedHtml) : processedHtml for (const chunk of bundleOutput) { if (chunk.type === 'chunk') { if (chunk.isEntry) { diff --git a/src/node/build/index.ts b/src/node/build/index.ts index ce23db344d65a5..9a97aa2080765f 100644 --- a/src/node/build/index.ts +++ b/src/node/build/index.ts @@ -288,6 +288,7 @@ function prepareConfig(config: Partial): BuildConfig { rollupPluginVueOptions = {}, root = process.cwd(), shouldPreload = null, + useSystemJs = false, silent = false, sourcemap = false, terserOptions = {}, @@ -330,6 +331,7 @@ function prepareConfig(config: Partial): BuildConfig { rollupPluginVueOptions, root, shouldPreload, + useSystemJs, silent, sourcemap, terserOptions, @@ -365,6 +367,7 @@ export async function build( silent, sourcemap, shouldPreload, + useSystemJs, env, mode: configMode, define: userDefineReplacements, @@ -405,6 +408,7 @@ export async function build( assetsInlineLimit, resolver, shouldPreload, + useSystemJs, options ) @@ -592,7 +596,7 @@ export async function build( await bundle[write ? 'write' : 'generate']({ dir: resolvedAssetsPath, - format: 'es', + format: useSystemJs ? 'system' : 'es', sourcemap, entryFileNames: `[name].[hash].js`, chunkFileNames: `[name].[hash].js`, diff --git a/src/node/config.ts b/src/node/config.ts index 753e2eca6993af..96288179fa1e34 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -339,6 +339,30 @@ export interface BuildConfig extends Required { * @internal */ ssr?: boolean + /** + * Set to `false` will produce modular javascript code, + * which requires browser's native ES module support, + * other options will use SystemJS to load each module instead. + * Set to `true` will insert the SystemJS runtime to a inline script tag, + * set to string will load the SystemJS runtime via CDN you specified. + * + * Example `vite.config.js`: + * ```js + * module.exports = { + * // by default vite will not use SystemJS + * useSystemJs: false, + * + * // will insert a inline script tag contains SystemJS runtime + * useSystemJs: true, + * + * // will load SystemJS runtime via CDN + * useSystemJs: '//unpkg.com/systemjs@6/dist/s.min.js', + * } + * ``` + * + * @default false + */ + useSystemJs: boolean | string // The following are API / config only and not documented in the CLI. -------- /** diff --git a/yarn.lock b/yarn.lock index 84371e7b6d1d73..3d2ee5be841abc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6433,6 +6433,11 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +systemjs@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/systemjs/-/systemjs-6.7.1.tgz#3db5036f450180a0701e078fbb5b434a690026f0" + integrity sha512-Q78H/SYy9ErC8PH8r9vA/FcQ3X+Hf33dOpx2JKP/Ma6f2gHuSScPFuCKZH+6CIj7EsIJlzODxSG4mMIpjOh5oA== + tar-fs@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.0.tgz#d1cdd121ab465ee0eb9ccde2d35049d3f3daf0d5"