Skip to content

Commit

Permalink
refactor: ensureChunkDeps
Browse files Browse the repository at this point in the history
  • Loading branch information
hi-ogawa committed Dec 9, 2024
1 parent eb58c7c commit 7c53ede
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 73 deletions.
16 changes: 12 additions & 4 deletions packages/vite/misc/rolldown-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,14 +229,22 @@ self.__rolldown_runtime = {
}
}
},
/**
* @type {Record<string, string>}
*/
/** @type {{ chunks: Record<string, { fileName: string, imports: string[] }> }} */
manifest: {},
/**
* @param {string} chunkName
*/
async ensureChunk(chunkName) {
await import('/' + this.manifest[chunkName])
await this.ensureChunkDeps(chunkName)
const file = this.manifest.chunks[chunkName].fileName
await import(`/${file}`)
},
/**
* @param {string} chunkName
*/
async ensureChunkDeps(chunkName) {
for (const file of this.manifest.chunks[chunkName].imports) {
await import(`/${file}`)
}
},
}
132 changes: 63 additions & 69 deletions packages/vite/src/node/server/environments/rolldown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,9 @@ class RolldownEnvironment extends DevEnvironment {
} else {
// TODO: manifest
if (result.chunk) {
this.getRunner().evaluate(
await (
await this.getRunner()
).evaluate(
result.chunk.code,
path.join(this.outDir, result.chunk.fileName),
)
Expand All @@ -354,20 +356,20 @@ class RolldownEnvironment extends DevEnvironment {

runner!: RolldownModuleRunner

getRunner() {
async getRunner() {
if (!this.runner) {
const output = this.result.output[0]
const filepath = path.join(this.outDir, output.fileName)
this.runner = new RolldownModuleRunner()
const code = fs.readFileSync(filepath, 'utf-8')
this.runner.evaluate(code, filepath)
await this.runner.evaluate(code, filepath)
}
return this.runner
}

async import(input: string): Promise<unknown> {
if (this.outputOptions.format === 'experimental-app') {
return this.getRunner().import(input)
return (await this.getRunner()).import(input)
}
// input is no use
const output = this.result.output[0]
Expand Down Expand Up @@ -395,22 +397,22 @@ class RolldownModuleRunner {
return mod.exports
}

evaluate(code: string, sourceURL: string) {
async evaluate(code: string, sourceURL: string) {
// extract sourcemap and move to the bottom
const sourcemap = code.match(/^\/\/# sourceMappingURL=.*/m)?.[0] ?? ''
if (sourcemap) {
code = code.replace(sourcemap, '')
}
code = `\
'use strict';(${Object.keys(this.context).join(',')})=>{{${code}
'use strict';async (${Object.keys(this.context).join(',')})=>{{${code}
}}
//# sourceURL=${sourceURL}
//# sourceMappingSource=rolldown-module-runner
${sourcemap}
`
const fn = (0, eval)(code)
try {
fn(...Object.values(this.context))
await fn(...Object.values(this.context))
} catch (e) {
console.error('[RolldownModuleRunner:ERROR]', e)
throw e
Expand All @@ -421,86 +423,78 @@ ${sourcemap}
function patchRuntimePlugin(environment: RolldownEnvironment): rolldown.Plugin {
return {
name: 'vite:rolldown-patch-runtime',
renderChunk(code, chunk) {
// TODO: this magic string is heavy
// (append only so no need to generate sourcemap?)

if (chunk.name === 'hmr-update') {
const output = new MagicString(code)
output.append(`
self.__rolldown_runtime.patch(__rolldown_modules);
`)
return {
code: output.toString(),
map: output.generateMap({ hires: 'boundary' }),
}
}

if (chunk.isDynamicEntry) {
const output = new MagicString(code)
output.append(`
Object.assign(self.__rolldown_runtime.moduleFactoryMap, __rolldown_modules);
`)
return {
code: output.toString(),
map: output.generateMap({ hires: 'boundary' }),
}
}

if (chunk.isEntry) {
const output = new MagicString(code)
assert(chunk.facadeModuleId)
const stableId = path.relative(
environment.config.root,
chunk.facadeModuleId,
)
output.append(`
Object.assign(self.__rolldown_runtime.moduleFactoryMap, __rolldown_modules);
self.__rolldown_runtime.require(${JSON.stringify(stableId)});
`)

// inject runtime
const runtimeCode = fs.readFileSync(
path.join(VITE_PACKAGE_DIR, 'misc', 'rolldown-runtime.js'),
'utf-8',
)
output.prepend(runtimeCode)
if (environment.name === 'client') {
output.prepend(getRolldownClientCode())
}
if (environment.rolldownDevOptions.reactRefresh) {
output.prepend(getReactRefreshRuntimeCode())
}
return {
code: output.toString(),
map: output.generateMap({ hires: 'boundary' }),
}
renderChunk(code) {
// TODO: source map is broken otherwise
const output = new MagicString(code)
return {
code: output.toString(),
map: output.generateMap({ hires: 'boundary' }),
}
},
generateBundle(_options, bundle) {
// inject chunk manifest
const manifest = getChunkManifest(Object.values(bundle))
for (const chunk of Object.values(bundle)) {
if (chunk.type === 'chunk' && chunk.isEntry) {
chunk.code += `
if (chunk.type === 'chunk') {
if (chunk.isEntry) {
chunk.code +=
'\n;' +
fs.readFileSync(
path.join(VITE_PACKAGE_DIR, 'misc', 'rolldown-runtime.js'),
'utf-8',
)
if (environment.name === 'client') {
chunk.code += getRolldownClientCode()
}
if (environment.rolldownDevOptions.reactRefresh) {
chunk.code += getReactRefreshRuntimeCode()
}
chunk.code += `
self.__rolldown_runtime.manifest = ${JSON.stringify(manifest, null, 2)};
`
}
if (chunk.name === 'hmr-update') {
chunk.code += `
self.__rolldown_runtime.patch(__rolldown_modules);
`
} else {
// TODO: avoid top-level-await?
chunk.code += `
Object.assign(self.__rolldown_runtime.moduleFactoryMap, __rolldown_modules);
await self.__rolldown_runtime.ensureChunkDeps(${JSON.stringify(chunk.name)});
`
}
if (chunk.isEntry) {
assert(chunk.facadeModuleId)
const stableId = path.relative(
environment.config.root,
chunk.facadeModuleId,
)
chunk.code += `
self.__rolldown_runtime.require(${JSON.stringify(stableId)});
`
}
chunk.code = moveInlineSourcemapToEnd(chunk.code)
}
}
},
}
}

type ChunkManifest = Record<string, string>
export type ChunkManifest = {
chunks: Record<string, { fileName: string; imports: string[] }>
}

function getChunkManifest(
outputs: (rolldown.RolldownOutputChunk | rolldown.RolldownOutputAsset)[],
): ChunkManifest {
const manifest: Record<string, string> = {}
const manifest: ChunkManifest = {
chunks: {},
}
for (const chunk of outputs) {
if (chunk.name) {
manifest[chunk.name] = chunk.fileName
if (chunk.type === 'chunk') {
const { fileName, imports } = chunk
manifest.chunks[chunk.name] = { fileName, imports }
}
}
return manifest
Expand Down Expand Up @@ -577,7 +571,7 @@ hot.on("rolldown:hmr", (data) => {
self.__rolldown_hot = hot;
self.__rolldown_updateStyle = updateStyle;
`
return `;(() => {/*** @vite/client ***/\n${code}}\n)();`
return `\n;(() => {/*** @vite/client ***/\n${code}}\n)();\n`
}

function reactRefreshPlugin(): rolldown.Plugin {
Expand Down Expand Up @@ -615,7 +609,7 @@ function getReactRefreshRuntimeCode() {
'utf-8',
)
const output = new MagicString(code)
output.prepend('self.__react_refresh_runtime = {};\n')
output.prepend('\n;self.__react_refresh_runtime = {};\n')
output.replaceAll('process.env.NODE_ENV !== "production"', 'true')
output.replaceAll(/\bexports\./g, '__react_refresh_runtime.')
output.append(`
Expand Down

0 comments on commit 7c53ede

Please sign in to comment.