mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-16 13:48:13 +00:00
feat: natively parse and import async webpack chunks
This commit is contained in:
parent
e16aee43ba
commit
609796a944
@ -95,7 +95,7 @@ export const getRollupConfig = (options: SLSOptions) => {
|
|||||||
output: {
|
output: {
|
||||||
dir: options.targetDir,
|
dir: options.targetDir,
|
||||||
entryFileNames: options.outName,
|
entryFileNames: options.outName,
|
||||||
chunkFileNames: join(chunksDirName, '_[name].js'),
|
chunkFileNames: join(chunksDirName, '[name].js'),
|
||||||
inlineDynamicImports: options.inlineChunks,
|
inlineDynamicImports: options.inlineChunks,
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
exports: 'auto',
|
exports: 'auto',
|
||||||
@ -131,8 +131,6 @@ export const getRollupConfig = (options: SLSOptions) => {
|
|||||||
rollupConfig.plugins.push(dynamicRequire({
|
rollupConfig.plugins.push(dynamicRequire({
|
||||||
dir: resolve(options.buildDir, 'dist/server'),
|
dir: resolve(options.buildDir, 'dist/server'),
|
||||||
inline: options.node === false || options.inlineChunks,
|
inline: options.node === false || options.inlineChunks,
|
||||||
outDir: join(options.targetDir, chunksDirName),
|
|
||||||
prefix: './',
|
|
||||||
globbyOptions: {
|
globbyOptions: {
|
||||||
ignore: [
|
ignore: [
|
||||||
'server.js'
|
'server.js'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { resolve, dirname } from 'path'
|
import { resolve } from 'path'
|
||||||
import globby, { GlobbyOptions } from 'globby'
|
import globby, { GlobbyOptions } from 'globby'
|
||||||
import { copyFile, mkdirp } from 'fs-extra'
|
import type { Plugin } from 'rollup'
|
||||||
|
|
||||||
const PLUGIN_NAME = 'dynamic-require'
|
const PLUGIN_NAME = 'dynamic-require'
|
||||||
const HELPER_DYNAMIC = `\0${PLUGIN_NAME}.js`
|
const HELPER_DYNAMIC = `\0${PLUGIN_NAME}.js`
|
||||||
@ -15,17 +15,21 @@ interface Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Chunk {
|
interface Chunk {
|
||||||
name: string
|
|
||||||
id: string
|
id: string
|
||||||
src: string
|
src: string
|
||||||
|
name: string
|
||||||
|
meta?: {
|
||||||
|
id?: string
|
||||||
|
ids?: string[]
|
||||||
|
moduleIds?: string[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TemplateContext {
|
interface TemplateContext {
|
||||||
chunks: Chunk[]
|
chunks: Chunk[]
|
||||||
prefix: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dynamicRequire ({ dir, globbyOptions, inline, outDir, prefix = '' }: Options) {
|
export function dynamicRequire ({ dir, globbyOptions, inline }: Options): Plugin {
|
||||||
return {
|
return {
|
||||||
name: PLUGIN_NAME,
|
name: PLUGIN_NAME,
|
||||||
transform (code: string, _id: string) {
|
transform (code: string, _id: string) {
|
||||||
@ -34,6 +38,12 @@ export function dynamicRequire ({ dir, globbyOptions, inline, outDir, prefix = '
|
|||||||
resolveId (id: string) {
|
resolveId (id: string) {
|
||||||
return id === HELPER_DYNAMIC ? id : null
|
return id === HELPER_DYNAMIC ? id : null
|
||||||
},
|
},
|
||||||
|
// TODO: Async chunk loading over netwrok!
|
||||||
|
// renderDynamicImport () {
|
||||||
|
// return {
|
||||||
|
// left: 'fetch(', right: ')'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
async load (_id: string) {
|
async load (_id: string) {
|
||||||
if (_id !== HELPER_DYNAMIC) {
|
if (_id !== HELPER_DYNAMIC) {
|
||||||
return null
|
return null
|
||||||
@ -44,28 +54,30 @@ export function dynamicRequire ({ dir, globbyOptions, inline, outDir, prefix = '
|
|||||||
const chunks = files.map(id => ({
|
const chunks = files.map(id => ({
|
||||||
id,
|
id,
|
||||||
src: resolve(dir, id).replace(/\\/g, '/'),
|
src: resolve(dir, id).replace(/\\/g, '/'),
|
||||||
out: prefix + id,
|
name: '_' + id.replace(/[\\/.]/g, '_'),
|
||||||
name: '_' + id.replace(/[\\/.]/g, '_')
|
meta: getWebpackChunkMeta(resolve(dir, id))
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// Inline mode
|
|
||||||
if (inline) {
|
if (inline) {
|
||||||
return TMPL_ESM_INLINE({ chunks, prefix })
|
return TMPL_INLINE({ chunks })
|
||||||
|
} else {
|
||||||
|
return TMPL_LAZY({ chunks })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write chunks
|
|
||||||
await Promise.all(chunks.map(async (chunk) => {
|
|
||||||
const dst = resolve(outDir, prefix + chunk.id)
|
|
||||||
await mkdirp(dirname(dst))
|
|
||||||
await copyFile(chunk.src, dst)
|
|
||||||
}))
|
|
||||||
|
|
||||||
return TMPL_CJS_LAZY({ chunks, prefix })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function TMPL_ESM_INLINE ({ chunks }: TemplateContext) {
|
function getWebpackChunkMeta (src) {
|
||||||
|
const chunk = require(src) || {}
|
||||||
|
const { id, ids, modules } = chunk
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
ids,
|
||||||
|
moduleIds: Object.keys(modules)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function TMPL_INLINE ({ chunks }: TemplateContext) {
|
||||||
return `${chunks.map(i => `import ${i.name} from '${i.src}'`).join('\n')}
|
return `${chunks.map(i => `import ${i.name} from '${i.src}'`).join('\n')}
|
||||||
const dynamicChunks = {
|
const dynamicChunks = {
|
||||||
${chunks.map(i => ` ['${i.id}']: ${i.name}`).join(',\n')}
|
${chunks.map(i => ` ['${i.id}']: ${i.name}`).join(',\n')}
|
||||||
@ -76,18 +88,31 @@ export default function dynamicRequire(id) {
|
|||||||
};`
|
};`
|
||||||
}
|
}
|
||||||
|
|
||||||
function TMPL_CJS_LAZY ({ chunks, prefix }: TemplateContext) {
|
function TMPL_LAZY ({ chunks }: TemplateContext) {
|
||||||
return `const dynamicChunks = {
|
return `
|
||||||
${chunks.map(i => ` ['${i.id}']: () => require('${prefix}${i.id}')`).join(',\n')}
|
function asyncWebpackModule(promise, id) {
|
||||||
|
return function (module, exports, require) {
|
||||||
|
module.exports = promise.then(r => {
|
||||||
|
const realModule = { exports: {}, require };
|
||||||
|
r.modules[id](realModule, realModule.exports, realModule.require);
|
||||||
|
return realModule.exports;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function webpackChunk (meta, promise) {
|
||||||
|
const chunk = { ...meta, modules: {} };
|
||||||
|
for (const id of meta.moduleIds) {
|
||||||
|
chunk.modules[id] = asyncWebpackModule(promise, id);
|
||||||
|
};
|
||||||
|
return chunk;
|
||||||
|
};
|
||||||
|
|
||||||
|
const dynamicChunks = {
|
||||||
|
${chunks.map(i => ` ['${i.id}']: () => webpackChunk(${JSON.stringify(i.meta)}, import('${i.src}'))`).join(',\n')}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function dynamicRequire(id) {
|
export default function dynamicRequire(id) {
|
||||||
return dynamicChunks[id]();
|
return dynamicChunks[id]();
|
||||||
};`
|
};`
|
||||||
}
|
}
|
||||||
|
|
||||||
// function TMPL_CJS ({ prefix }: TemplateContext) {
|
|
||||||
// return `export default function dynamicRequire(id) {
|
|
||||||
// return require('${prefix}' + id);
|
|
||||||
// };`
|
|
||||||
// }
|
|
||||||
|
Loading…
Reference in New Issue
Block a user