diff options
Diffstat (limited to 'node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js')
| -rw-r--r-- | node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js b/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js new file mode 100644 index 00000000..f0b37b09 --- /dev/null +++ b/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js @@ -0,0 +1,245 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php +*/ + +"use strict"; + +const RuntimeGlobals = require("../RuntimeGlobals"); +const RuntimeModule = require("../RuntimeModule"); +const Template = require("../Template"); +const { + chunkHasJs, + getChunkFilenameTemplate +} = require("../javascript/JavascriptModulesPlugin"); +const { getInitialChunkIds } = require("../javascript/StartupHelpers"); +const compileBooleanMatcher = require("../util/compileBooleanMatcher"); +const { getUndoPath } = require("../util/identifier"); + +/** @typedef {import("../Chunk")} Chunk */ +/** @typedef {import("../ChunkGraph")} ChunkGraph */ +/** @typedef {import("../Compilation")} Compilation */ + +class RequireChunkLoadingRuntimeModule extends RuntimeModule { + /** + * @param {ReadonlySet<string>} runtimeRequirements runtime requirements + */ + constructor(runtimeRequirements) { + super("require chunk loading", RuntimeModule.STAGE_ATTACH); + this.runtimeRequirements = runtimeRequirements; + } + + /** + * @private + * @param {Chunk} chunk chunk + * @param {string} rootOutputDir root output directory + * @returns {string} generated code + */ + _generateBaseUri(chunk, rootOutputDir) { + const options = chunk.getEntryOptions(); + if (options && options.baseUri) { + return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`; + } + + return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${ + rootOutputDir !== "./" + ? `__dirname + ${JSON.stringify("/" + rootOutputDir)}` + : "__filename" + });`; + } + + /** + * @returns {string | null} runtime code + */ + generate() { + const compilation = /** @type {Compilation} */ (this.compilation); + const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph); + const chunk = /** @type {Chunk} */ (this.chunk); + const { runtimeTemplate } = compilation; + const fn = RuntimeGlobals.ensureChunkHandlers; + const withBaseURI = this.runtimeRequirements.has(RuntimeGlobals.baseURI); + const withExternalInstallChunk = this.runtimeRequirements.has( + RuntimeGlobals.externalInstallChunk + ); + const withOnChunkLoad = this.runtimeRequirements.has( + RuntimeGlobals.onChunksLoaded + ); + const withLoading = this.runtimeRequirements.has( + RuntimeGlobals.ensureChunkHandlers + ); + const withHmr = this.runtimeRequirements.has( + RuntimeGlobals.hmrDownloadUpdateHandlers + ); + const withHmrManifest = this.runtimeRequirements.has( + RuntimeGlobals.hmrDownloadManifest + ); + const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs); + const hasJsMatcher = compileBooleanMatcher(conditionMap); + const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs); + + const outputName = compilation.getPath( + getChunkFilenameTemplate(chunk, compilation.outputOptions), + { + chunk, + contentHashType: "javascript" + } + ); + const rootOutputDir = getUndoPath( + outputName, + /** @type {string} */ (compilation.outputOptions.path), + true + ); + + const stateExpression = withHmr + ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_require` + : undefined; + + return Template.asString([ + withBaseURI + ? this._generateBaseUri(chunk, rootOutputDir) + : "// no baseURI", + "", + "// object to store loaded chunks", + '// "1" means "loaded", otherwise not loaded yet', + `var installedChunks = ${ + stateExpression ? `${stateExpression} = ${stateExpression} || ` : "" + }{`, + Template.indent( + Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 1`).join( + ",\n" + ) + ), + "};", + "", + withOnChunkLoad + ? `${ + RuntimeGlobals.onChunksLoaded + }.require = ${runtimeTemplate.returningFunction( + "installedChunks[chunkId]", + "chunkId" + )};` + : "// no on chunks loaded", + "", + withLoading || withExternalInstallChunk + ? `var installChunk = ${runtimeTemplate.basicFunction("chunk", [ + "var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;", + "for(var moduleId in moreModules) {", + Template.indent([ + `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, + Template.indent([ + `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` + ]), + "}" + ]), + "}", + `if(runtime) runtime(${RuntimeGlobals.require});`, + "for(var i = 0; i < chunkIds.length; i++)", + Template.indent("installedChunks[chunkIds[i]] = 1;"), + withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : "" + ])};` + : "// no chunk install function needed", + "", + withLoading + ? Template.asString([ + "// require() chunk loading for javascript", + `${fn}.require = ${runtimeTemplate.basicFunction( + "chunkId, promises", + hasJsMatcher !== false + ? [ + '// "1" is the signal for "already loaded"', + "if(!installedChunks[chunkId]) {", + Template.indent([ + hasJsMatcher === true + ? "if(true) { // all chunks have JS" + : `if(${hasJsMatcher("chunkId")}) {`, + Template.indent([ + `installChunk(require(${JSON.stringify( + rootOutputDir + )} + ${ + RuntimeGlobals.getChunkScriptFilename + }(chunkId)));` + ]), + "} else installedChunks[chunkId] = 1;", + "" + ]), + "}" + ] + : "installedChunks[chunkId] = 1;" + )};` + ]) + : "// no chunk loading", + "", + withExternalInstallChunk + ? Template.asString([ + `module.exports = ${RuntimeGlobals.require};`, + `${RuntimeGlobals.externalInstallChunk} = installChunk;` + ]) + : "// no external install chunk", + "", + withHmr + ? Template.asString([ + "function loadUpdateChunk(chunkId, updatedModulesList) {", + Template.indent([ + `var update = require(${JSON.stringify(rootOutputDir)} + ${ + RuntimeGlobals.getChunkUpdateScriptFilename + }(chunkId));`, + "var updatedModules = update.modules;", + "var runtime = update.runtime;", + "for(var moduleId in updatedModules) {", + Template.indent([ + `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`, + Template.indent([ + `currentUpdate[moduleId] = updatedModules[moduleId];`, + "if(updatedModulesList) updatedModulesList.push(moduleId);" + ]), + "}" + ]), + "}", + "if(runtime) currentUpdateRuntime.push(runtime);" + ]), + "}", + "", + Template.getFunctionContent( + require("../hmr/JavascriptHotModuleReplacement.runtime.js") + ) + .replace(/\$key\$/g, "require") + .replace(/\$installedChunks\$/g, "installedChunks") + .replace(/\$loadUpdateChunk\$/g, "loadUpdateChunk") + .replace(/\$moduleCache\$/g, RuntimeGlobals.moduleCache) + .replace(/\$moduleFactories\$/g, RuntimeGlobals.moduleFactories) + .replace( + /\$ensureChunkHandlers\$/g, + RuntimeGlobals.ensureChunkHandlers + ) + .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty) + .replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData) + .replace( + /\$hmrDownloadUpdateHandlers\$/g, + RuntimeGlobals.hmrDownloadUpdateHandlers + ) + .replace( + /\$hmrInvalidateModuleHandlers\$/g, + RuntimeGlobals.hmrInvalidateModuleHandlers + ) + ]) + : "// no HMR", + "", + withHmrManifest + ? Template.asString([ + `${RuntimeGlobals.hmrDownloadManifest} = function() {`, + Template.indent([ + "return Promise.resolve().then(function() {", + Template.indent([ + `return require(${JSON.stringify(rootOutputDir)} + ${ + RuntimeGlobals.getUpdateManifestFilename + }());` + ]), + "})['catch'](function(err) { if(err.code !== 'MODULE_NOT_FOUND') throw err; });" + ]), + "}" + ]) + : "// no HMR manifest" + ]); + } +} + +module.exports = RequireChunkLoadingRuntimeModule; |
