mirror of https://github.com/webpack/webpack.git
Deprecate MainTemplate, ChunkTemplate, ModuleTemplate
move logic and hooks to JavascriptModulesPlugin
This commit is contained in:
parent
f45ba2408e
commit
69a545c444
|
@ -1,7 +1,7 @@
|
||||||
/node_modules
|
/node_modules
|
||||||
/test/js
|
/test/js
|
||||||
/test/browsertest/js
|
/test/browsertest/js
|
||||||
/test/fixtures/temp-cache-fixture*
|
/test/fixtures/temp-*
|
||||||
/benchmark/js
|
/benchmark/js
|
||||||
/benchmark/fixtures
|
/benchmark/fixtures
|
||||||
/examples/**/dist
|
/examples/**/dist
|
||||||
|
|
|
@ -1302,7 +1302,12 @@ export interface OutputOptions {
|
||||||
/**
|
/**
|
||||||
* The `publicPath` specifies the public URL address of the output files when referenced in a browser.
|
* The `publicPath` specifies the public URL address of the output files when referenced in a browser.
|
||||||
*/
|
*/
|
||||||
publicPath?: string | Function;
|
publicPath?:
|
||||||
|
| string
|
||||||
|
| ((
|
||||||
|
pathData: import("../lib/Compilation").PathData,
|
||||||
|
assetInfo?: import("../lib/Compilation").AssetInfo
|
||||||
|
) => string);
|
||||||
/**
|
/**
|
||||||
* The filename of the SourceMaps for the JavaScript files. They are inside the `output.path` directory.
|
* The filename of the SourceMaps for the JavaScript files. They are inside the `output.path` directory.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,78 +5,119 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { SyncWaterfallHook, SyncHook } = require("tapable");
|
const util = require("util");
|
||||||
|
const memorize = require("./util/memorize");
|
||||||
|
|
||||||
/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
|
/** @typedef {import("./Compilation")} Compilation */
|
||||||
/** @typedef {import("./Chunk")} Chunk */
|
|
||||||
/** @typedef {import("./Module")} Module} */
|
|
||||||
/** @typedef {import("./util/Hash")} Hash} */
|
|
||||||
/** @typedef {import("webpack-sources").Source} Source} */
|
|
||||||
/** @typedef {import("./ModuleTemplate").RenderContext} RenderContext} */
|
|
||||||
/** @typedef {import("./MainTemplate").UpdateHashForChunkContext} UpdateHashForChunkContext} */
|
|
||||||
/** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions} */
|
|
||||||
/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry} */
|
|
||||||
|
|
||||||
module.exports = class ChunkTemplate {
|
const getJavascriptModulesPlugin = memorize(() =>
|
||||||
constructor(outputOptions) {
|
require("./JavascriptModulesPlugin")
|
||||||
this.outputOptions = outputOptions || {};
|
);
|
||||||
|
|
||||||
|
// TODO webpack 6 remove this class
|
||||||
|
class ChunkTemplate {
|
||||||
|
/**
|
||||||
|
* @param {TODO} outputOptions TODO
|
||||||
|
* @param {Compilation} compilation the compilation
|
||||||
|
*/
|
||||||
|
constructor(outputOptions, compilation) {
|
||||||
|
this._outputOptions = outputOptions || {};
|
||||||
|
const moduleTemplate = null; // TODO add deprecated ModuleTemplate
|
||||||
this.hooks = Object.freeze({
|
this.hooks = Object.freeze({
|
||||||
/** @type {SyncWaterfallHook<[RenderManifestEntry[], RenderManifestOptions]>} */
|
renderManifest: {
|
||||||
renderManifest: new SyncWaterfallHook(["result", "options"]),
|
tap: util.deprecate(
|
||||||
/** @type {SyncWaterfallHook<[Source, ModuleTemplate, RenderContext]>} */
|
(options, fn) => {
|
||||||
modules: new SyncWaterfallHook([
|
compilation.hooks.renderManifest.tap(
|
||||||
"source",
|
options,
|
||||||
"moduleTemplate",
|
(entries, options) => {
|
||||||
"renderContext"
|
if (options.chunk.hasRuntime()) return entries;
|
||||||
]),
|
return fn(entries, options);
|
||||||
/** @type {SyncWaterfallHook<[Source, ModuleTemplate, RenderContext]>} */
|
}
|
||||||
render: new SyncWaterfallHook([
|
);
|
||||||
"source",
|
},
|
||||||
"moduleTemplate",
|
"ChunkTemplate.hooks.renderManifest is deprecated (use Compilation.hooks.renderManifest instead)",
|
||||||
"renderContext"
|
"DEP_WEBPACK_CHUNK_TEMPLATE_RENDER_MANIFEST"
|
||||||
]),
|
)
|
||||||
/** @type {SyncWaterfallHook<[Source, Chunk]>} */
|
},
|
||||||
renderWithEntry: new SyncWaterfallHook(["source", "chunk"]),
|
modules: {
|
||||||
/** @type {SyncHook<[Hash]>} */
|
tap: util.deprecate(
|
||||||
hash: new SyncHook(["hash"]),
|
(options, fn) => {
|
||||||
/** @type {SyncHook<[Hash, Chunk]>} */
|
getJavascriptModulesPlugin()
|
||||||
hashForChunk: new SyncHook(["hash", "chunk"])
|
.getCompilationHooks(compilation)
|
||||||
|
.renderChunk.tap(options, (source, renderContext) =>
|
||||||
|
fn(source, moduleTemplate, renderContext)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
"ChunkTemplate.hooks.modules is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderChunk instead)",
|
||||||
|
"DEP_WEBPACK_CHUNK_TEMPLATE_MODULES"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
render: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
getJavascriptModulesPlugin()
|
||||||
|
.getCompilationHooks(compilation)
|
||||||
|
.renderChunk.tap(options, (source, renderContext) =>
|
||||||
|
fn(source, moduleTemplate, renderContext)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
"ChunkTemplate.hooks.render is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderChunk instead)",
|
||||||
|
"DEP_WEBPACK_CHUNK_TEMPLATE_RENDER"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
renderWithEntry: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
getJavascriptModulesPlugin()
|
||||||
|
.getCompilationHooks(compilation)
|
||||||
|
.renderWithEntry.tap(options, (source, renderContext) => {
|
||||||
|
if (renderContext.chunk.hasRuntime()) return source;
|
||||||
|
return fn(source, renderContext.chunk);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"ChunkTemplate.hooks.renderWithEntry is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderWithEntry instead)",
|
||||||
|
"DEP_WEBPACK_CHUNK_TEMPLATE_RENDER_WITH_ENTRY"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
hash: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
compilation.hooks.fullHash.tap(options, fn);
|
||||||
|
},
|
||||||
|
"ChunkTemplate.hooks.hash is deprecated (use Compilation.hooks.fullHash instead)",
|
||||||
|
"DEP_WEBPACK_CHUNK_TEMPLATE_HASH"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
hashForChunk: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
getJavascriptModulesPlugin()
|
||||||
|
.getCompilationHooks(compilation)
|
||||||
|
.chunkHash.tap(options, (chunk, hash, context) => {
|
||||||
|
if (chunk.hasRuntime()) return;
|
||||||
|
fn(hash, chunk, context);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"ChunkTemplate.hooks.hashForChunk is deprecated (use JavascriptModulesPlugin.getCompilationHooks().chunkHash instead)",
|
||||||
|
"DEP_WEBPACK_CHUNK_TEMPLATE_HASH_FOR_CHUNK"
|
||||||
|
)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
Object.defineProperty(ChunkTemplate.prototype, "outputOptions", {
|
||||||
*
|
get: util.deprecate(
|
||||||
* @param {RenderManifestOptions} options render manifest options
|
/**
|
||||||
* @returns {RenderManifestEntry[]} returns render manifest
|
* @this {ChunkTemplate}
|
||||||
*/
|
* @returns {TODO} output options
|
||||||
getRenderManifest(options) {
|
*/
|
||||||
const result = [];
|
function() {
|
||||||
|
return this._outputOptions;
|
||||||
|
},
|
||||||
|
"ChunkTemplate.outputOptions is deprecated (use Compilation.outputOptions instead)",
|
||||||
|
"DEP_WEBPACK_CHUNK_TEMPLATE_OUTPUT_OPTIONS"
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
this.hooks.renderManifest.call(result, options);
|
module.exports = ChunkTemplate;
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates hash with information from this template
|
|
||||||
* @param {Hash} hash the hash to update
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
updateHash(hash) {
|
|
||||||
hash.update("ChunkTemplate");
|
|
||||||
hash.update("3");
|
|
||||||
this.hooks.hash.call(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates hash with chunk-specific information from this template
|
|
||||||
* @param {Hash} hash the hash to update
|
|
||||||
* @param {Chunk} chunk the chunk
|
|
||||||
* @param {UpdateHashForChunkContext} context options object
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
updateHashForChunk(hash, chunk, context) {
|
|
||||||
this.updateHash(hash);
|
|
||||||
this.hooks.hashForChunk.call(hash, chunk);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ const { arrayToSetDeprecation } = require("./util/deprecation");
|
||||||
/** @typedef {import("./ModuleFactory")} ModuleFactory */
|
/** @typedef {import("./ModuleFactory")} ModuleFactory */
|
||||||
/** @typedef {import("./RuntimeModule")} RuntimeModule */
|
/** @typedef {import("./RuntimeModule")} RuntimeModule */
|
||||||
/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry */
|
/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry */
|
||||||
|
/** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions */
|
||||||
/** @typedef {import("./WebpackError")} WebpackError */
|
/** @typedef {import("./WebpackError")} WebpackError */
|
||||||
/** @typedef {import("./dependencies/DependencyReference")} DependencyReference */
|
/** @typedef {import("./dependencies/DependencyReference")} DependencyReference */
|
||||||
/** @typedef {import("./dependencies/DllEntryDependency")} DllEntryDependency */
|
/** @typedef {import("./dependencies/DllEntryDependency")} DllEntryDependency */
|
||||||
|
@ -127,6 +128,13 @@ const { arrayToSetDeprecation } = require("./util/deprecation");
|
||||||
* @property {(Record<string, (length: number) => string>)=} contentHashWithLength
|
* @property {(Record<string, (length: number) => string>)=} contentHashWithLength
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} ChunkHashContext
|
||||||
|
* @property {RuntimeTemplate} runtimeTemplate the runtime template
|
||||||
|
* @property {ModuleGraph} moduleGraph the module graph
|
||||||
|
* @property {ChunkGraph} chunkGraph the chunk graph
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} LogEntry
|
* @typedef {Object} LogEntry
|
||||||
* @property {string} type
|
* @property {string} type
|
||||||
|
@ -407,15 +415,21 @@ class Compilation {
|
||||||
/** @type {AsyncSeriesHook<[]>} */
|
/** @type {AsyncSeriesHook<[]>} */
|
||||||
afterSeal: new AsyncSeriesHook([]),
|
afterSeal: new AsyncSeriesHook([]),
|
||||||
|
|
||||||
/** @type {SyncHook<[Chunk, Hash]>} */
|
/** @type {SyncWaterfallHook<[RenderManifestEntry[], RenderManifestOptions]>} */
|
||||||
chunkHash: new SyncHook(["chunk", "chunkHash"]),
|
renderManifest: new SyncWaterfallHook(["result", "options"]),
|
||||||
|
|
||||||
|
/** @type {SyncHook<[Hash]>} */
|
||||||
|
fullHash: new SyncHook(["hash"]),
|
||||||
|
/** @type {SyncHook<[Chunk, Hash, ChunkHashContext]>} */
|
||||||
|
chunkHash: new SyncHook(["chunk", "chunkHash", "ChunkHashContext"]),
|
||||||
|
|
||||||
/** @type {SyncHook<[Module, string]>} */
|
/** @type {SyncHook<[Module, string]>} */
|
||||||
moduleAsset: new SyncHook(["module", "filename"]),
|
moduleAsset: new SyncHook(["module", "filename"]),
|
||||||
/** @type {SyncHook<[Chunk, string]>} */
|
/** @type {SyncHook<[Chunk, string]>} */
|
||||||
chunkAsset: new SyncHook(["chunk", "filename"]),
|
chunkAsset: new SyncHook(["chunk", "filename"]),
|
||||||
|
|
||||||
/** @type {SyncWaterfallHook<[string, TODO]>} */
|
/** @type {SyncWaterfallHook<[string, object, AssetInfo]>} */
|
||||||
assetPath: new SyncWaterfallHook(["filename", "data"]), // TODO MainTemplate
|
assetPath: new SyncWaterfallHook(["path", "options", "assetInfo"]),
|
||||||
|
|
||||||
/** @type {SyncBailHook<[], boolean>} */
|
/** @type {SyncBailHook<[], boolean>} */
|
||||||
needAdditionalPass: new SyncBailHook([]),
|
needAdditionalPass: new SyncBailHook([]),
|
||||||
|
@ -471,18 +485,36 @@ class Compilation {
|
||||||
/** @type {boolean} */
|
/** @type {boolean} */
|
||||||
this.profile = (options && options.profile) || false;
|
this.profile = (options && options.profile) || false;
|
||||||
|
|
||||||
this.mainTemplate = new MainTemplate(this.outputOptions);
|
this.mainTemplate = new MainTemplate(this.outputOptions, this);
|
||||||
this.chunkTemplate = new ChunkTemplate(this.outputOptions);
|
this.chunkTemplate = new ChunkTemplate(this.outputOptions, this);
|
||||||
this.runtimeTemplate = new RuntimeTemplate(
|
this.runtimeTemplate = new RuntimeTemplate(
|
||||||
this.outputOptions,
|
this.outputOptions,
|
||||||
this.requestShortener
|
this.requestShortener
|
||||||
);
|
);
|
||||||
/** @type {{asset: ModuleTemplate, javascript: ModuleTemplate, webassembly: ModuleTemplate}} */
|
/** @type {{javascript: ModuleTemplate}} */
|
||||||
this.moduleTemplates = {
|
this.moduleTemplates = {
|
||||||
asset: new ModuleTemplate(this.runtimeTemplate, "asset"),
|
javascript: new ModuleTemplate(this.runtimeTemplate, this)
|
||||||
javascript: new ModuleTemplate(this.runtimeTemplate, "javascript"),
|
|
||||||
webassembly: new ModuleTemplate(this.runtimeTemplate, "webassembly")
|
|
||||||
};
|
};
|
||||||
|
Object.defineProperties(this.moduleTemplates, {
|
||||||
|
asset: {
|
||||||
|
enumerable: false,
|
||||||
|
configurable: false,
|
||||||
|
get() {
|
||||||
|
throw new WebpackError(
|
||||||
|
"Compilation.moduleTemplates.asset has been removed"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
webassembly: {
|
||||||
|
enumerable: false,
|
||||||
|
configurable: false,
|
||||||
|
get() {
|
||||||
|
throw new WebpackError(
|
||||||
|
"Compilation.moduleTemplates.webassembly has been removed"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.moduleGraph = new ModuleGraph();
|
this.moduleGraph = new ModuleGraph();
|
||||||
this.chunkGraph = undefined;
|
this.chunkGraph = undefined;
|
||||||
|
@ -1941,11 +1973,7 @@ class Compilation {
|
||||||
if (outputOptions.hashSalt) {
|
if (outputOptions.hashSalt) {
|
||||||
hash.update(outputOptions.hashSalt);
|
hash.update(outputOptions.hashSalt);
|
||||||
}
|
}
|
||||||
this.mainTemplate.updateHash(hash);
|
this.hooks.fullHash.call(hash);
|
||||||
this.chunkTemplate.updateHash(hash);
|
|
||||||
for (const key of Object.keys(this.moduleTemplates).sort()) {
|
|
||||||
this.moduleTemplates[key].updateHash(hash);
|
|
||||||
}
|
|
||||||
for (const child of this.children) {
|
for (const child of this.children) {
|
||||||
hash.update(child.hash);
|
hash.update(child.hash);
|
||||||
}
|
}
|
||||||
|
@ -1993,15 +2021,11 @@ class Compilation {
|
||||||
chunkHash.update(outputOptions.hashSalt);
|
chunkHash.update(outputOptions.hashSalt);
|
||||||
}
|
}
|
||||||
chunk.updateHash(chunkHash, chunkGraph);
|
chunk.updateHash(chunkHash, chunkGraph);
|
||||||
const template = chunk.hasRuntime()
|
this.hooks.chunkHash.call(chunk, chunkHash, {
|
||||||
? this.mainTemplate
|
|
||||||
: this.chunkTemplate;
|
|
||||||
template.updateHashForChunk(chunkHash, chunk, {
|
|
||||||
chunkGraph,
|
chunkGraph,
|
||||||
moduleGraph: this.moduleGraph,
|
moduleGraph: this.moduleGraph,
|
||||||
runtimeTemplate: this.runtimeTemplate
|
runtimeTemplate: this.runtimeTemplate
|
||||||
});
|
});
|
||||||
this.hooks.chunkHash.call(chunk, chunkHash);
|
|
||||||
chunk.hash = /** @type {string} */ (chunkHash.digest(hashDigest));
|
chunk.hash = /** @type {string} */ (chunkHash.digest(hashDigest));
|
||||||
hash.update(chunk.hash);
|
hash.update(chunk.hash);
|
||||||
chunk.renderedHash = chunk.hash.substr(0, hashDigestLength);
|
chunk.renderedHash = chunk.hash.substr(0, hashDigestLength);
|
||||||
|
@ -2150,6 +2174,14 @@ class Compilation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {RenderManifestOptions} options options object
|
||||||
|
* @returns {RenderManifestEntry[]} manifest entries
|
||||||
|
*/
|
||||||
|
getRenderManifest(options) {
|
||||||
|
return this.hooks.renderManifest.call([], options);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Callback} callback signals when the call finishes
|
* @param {Callback} callback signals when the call finishes
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
@ -2166,10 +2198,7 @@ class Compilation {
|
||||||
/** @type {RenderManifestEntry[]} */
|
/** @type {RenderManifestEntry[]} */
|
||||||
let manifest;
|
let manifest;
|
||||||
try {
|
try {
|
||||||
const template = chunk.hasRuntime()
|
manifest = this.getRenderManifest({
|
||||||
? this.mainTemplate
|
|
||||||
: this.chunkTemplate;
|
|
||||||
manifest = template.getRenderManifest({
|
|
||||||
chunk,
|
chunk,
|
||||||
hash: this.hash,
|
hash: this.hash,
|
||||||
fullHash: this.fullHash,
|
fullHash: this.fullHash,
|
||||||
|
@ -2179,7 +2208,7 @@ class Compilation {
|
||||||
chunkGraph: this.chunkGraph,
|
chunkGraph: this.chunkGraph,
|
||||||
moduleGraph: this.moduleGraph,
|
moduleGraph: this.moduleGraph,
|
||||||
runtimeTemplate: this.runtimeTemplate
|
runtimeTemplate: this.runtimeTemplate
|
||||||
}); // [{ render(), filenameTemplate, pathOptions, identifier, hash }]
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.errors.push(new ChunkRenderError(chunk, "", err));
|
this.errors.push(new ChunkRenderError(chunk, "", err));
|
||||||
return callback();
|
return callback();
|
||||||
|
@ -2294,14 +2323,14 @@ class Compilation {
|
||||||
* @param {PathData} data context data
|
* @param {PathData} data context data
|
||||||
* @returns {string} interpolated path
|
* @returns {string} interpolated path
|
||||||
*/
|
*/
|
||||||
getPath(filename, data) {
|
getPath(filename, data = {}) {
|
||||||
if (!data.hash) {
|
if (!data.hash) {
|
||||||
data = {
|
data = {
|
||||||
hash: this.hash,
|
hash: this.hash,
|
||||||
...data
|
...data
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return this.mainTemplate.getAssetPath(filename, data);
|
return this.getAssetPath(filename, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2309,10 +2338,43 @@ class Compilation {
|
||||||
* @param {PathData} data context data
|
* @param {PathData} data context data
|
||||||
* @returns {{ path: string, info: AssetInfo }} interpolated path and asset info
|
* @returns {{ path: string, info: AssetInfo }} interpolated path and asset info
|
||||||
*/
|
*/
|
||||||
getPathWithInfo(filename, data) {
|
getPathWithInfo(filename, data = {}) {
|
||||||
data = data || {};
|
if (!data.hash) {
|
||||||
data.hash = data.hash || this.hash;
|
data = {
|
||||||
return this.mainTemplate.getAssetPathWithInfo(filename, data);
|
hash: this.hash,
|
||||||
|
...data
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return this.getAssetPathWithInfo(filename, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string | function(PathData, AssetInfo=): string} filename used to get asset path with hash
|
||||||
|
* @param {PathData} data context data
|
||||||
|
* @returns {string} interpolated path
|
||||||
|
*/
|
||||||
|
getAssetPath(filename, data) {
|
||||||
|
return this.hooks.assetPath.call(
|
||||||
|
typeof filename === "function" ? filename(data) : filename,
|
||||||
|
data,
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string | function(PathData, AssetInfo=): string} filename used to get asset path with hash
|
||||||
|
* @param {PathData} data context data
|
||||||
|
* @returns {{ path: string, info: AssetInfo }} interpolated path and asset info
|
||||||
|
*/
|
||||||
|
getAssetPathWithInfo(filename, data) {
|
||||||
|
const assetInfo = {};
|
||||||
|
// TODO webpack 5: refactor assetPath hook to receive { path, info } object
|
||||||
|
const newPath = this.hooks.assetPath.call(
|
||||||
|
typeof filename === "function" ? filename(data, assetInfo) : filename,
|
||||||
|
data,
|
||||||
|
assetInfo
|
||||||
|
);
|
||||||
|
return { path: newPath, info: assetInfo };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
||||||
Author Tobias Koppers @sokra
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const FunctionModuleTemplatePlugin = require("./FunctionModuleTemplatePlugin");
|
|
||||||
|
|
||||||
/** @typedef {import("./Compiler")} Compiler */
|
|
||||||
|
|
||||||
class FunctionModulePlugin {
|
|
||||||
/**
|
|
||||||
* Apply the plugin
|
|
||||||
* @param {Compiler} compiler the compiler instance
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
apply(compiler) {
|
|
||||||
compiler.hooks.compilation.tap("FunctionModulePlugin", compilation => {
|
|
||||||
new FunctionModuleTemplatePlugin({
|
|
||||||
compilation
|
|
||||||
}).apply(compilation.moduleTemplates.javascript);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = FunctionModulePlugin;
|
|
|
@ -69,4 +69,26 @@ const makeWebpackErrorCallback = (callback, hook) => {
|
||||||
callback(null, result);
|
callback(null, result);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.makeWebpackErrorCallback = makeWebpackErrorCallback;
|
module.exports.makeWebpackErrorCallback = makeWebpackErrorCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @param {function(): T} fn function which will be wrapping in try catch
|
||||||
|
* @param {string} hook name of hook
|
||||||
|
* @returns {T} the result
|
||||||
|
*/
|
||||||
|
const tryRunOrWebpackError = (fn, hook) => {
|
||||||
|
let r;
|
||||||
|
try {
|
||||||
|
r = fn();
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof WebpackError) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
throw new HookWebpackError(err, hook);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.tryRunOrWebpackError = tryRunOrWebpackError;
|
||||||
|
|
|
@ -342,7 +342,7 @@ class HotModuleReplacementPlugin {
|
||||||
newRuntimeModules
|
newRuntimeModules
|
||||||
);
|
);
|
||||||
hotUpdateChunk.removedModules = removedModules;
|
hotUpdateChunk.removedModules = removedModules;
|
||||||
const renderManifest = chunkTemplate.getRenderManifest({
|
const renderManifest = compilation.getRenderManifest({
|
||||||
chunk: hotUpdateChunk,
|
chunk: hotUpdateChunk,
|
||||||
hash: records.hash,
|
hash: records.hash,
|
||||||
fullHash: records.hash,
|
fullHash: records.hash,
|
||||||
|
|
|
@ -5,10 +5,18 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { ConcatSource } = require("webpack-sources");
|
const { SyncWaterfallHook, SyncHook } = require("tapable");
|
||||||
|
const {
|
||||||
|
ConcatSource,
|
||||||
|
OriginalSource,
|
||||||
|
PrefixSource
|
||||||
|
} = require("webpack-sources");
|
||||||
|
const Compilation = require("./Compilation");
|
||||||
|
const { tryRunOrWebpackError } = require("./HookWebpackError");
|
||||||
const HotUpdateChunk = require("./HotUpdateChunk");
|
const HotUpdateChunk = require("./HotUpdateChunk");
|
||||||
const JavascriptGenerator = require("./JavascriptGenerator");
|
const JavascriptGenerator = require("./JavascriptGenerator");
|
||||||
const JavascriptParser = require("./JavascriptParser");
|
const JavascriptParser = require("./JavascriptParser");
|
||||||
|
const RuntimeGlobals = require("./RuntimeGlobals");
|
||||||
const Template = require("./Template");
|
const Template = require("./Template");
|
||||||
const { compareModulesByIdOrIdentifier } = require("./util/comparators");
|
const { compareModulesByIdOrIdentifier } = require("./util/comparators");
|
||||||
const createHash = require("./util/createHash");
|
const createHash = require("./util/createHash");
|
||||||
|
@ -17,12 +25,13 @@ const createHash = require("./util/createHash");
|
||||||
/** @typedef {import("./Chunk")} Chunk */
|
/** @typedef {import("./Chunk")} Chunk */
|
||||||
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
||||||
/** @typedef {import("./ChunkTemplate")} ChunkTemplate */
|
/** @typedef {import("./ChunkTemplate")} ChunkTemplate */
|
||||||
/** @typedef {import("./Compilation")} Compilation */
|
/** @typedef {import("./Compilation").ChunkHashContext} ChunkHashContext */
|
||||||
/** @typedef {import("./Compiler")} Compiler */
|
/** @typedef {import("./Compiler")} Compiler */
|
||||||
|
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
|
||||||
/** @typedef {import("./Module")} Module */
|
/** @typedef {import("./Module")} Module */
|
||||||
/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
|
/** @typedef {import("./ModuleGraph")} ModuleGraph */
|
||||||
/** @typedef {import("./ModuleTemplate").RenderContext} RenderContext */
|
|
||||||
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
|
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
|
||||||
|
/** @typedef {import("./util/Hash")} Hash */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Chunk} chunk a chunk
|
* @param {Chunk} chunk a chunk
|
||||||
|
@ -40,7 +49,89 @@ const chunkHasJs = (chunk, chunkGraph) => {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} RenderContext
|
||||||
|
* @property {Chunk} chunk the chunk
|
||||||
|
* @property {DependencyTemplates} dependencyTemplates the dependency templates
|
||||||
|
* @property {RuntimeTemplate} runtimeTemplate the runtime template
|
||||||
|
* @property {ModuleGraph} moduleGraph the module graph
|
||||||
|
* @property {ChunkGraph} chunkGraph the chunk graph
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} MainRenderContext
|
||||||
|
* @property {Chunk} chunk the chunk
|
||||||
|
* @property {DependencyTemplates} dependencyTemplates the dependency templates
|
||||||
|
* @property {RuntimeTemplate} runtimeTemplate the runtime template
|
||||||
|
* @property {ModuleGraph} moduleGraph the module graph
|
||||||
|
* @property {ChunkGraph} chunkGraph the chunk graph
|
||||||
|
* @property {string} hash hash to be used for render call
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} RenderBootstrapContext
|
||||||
|
* @property {Chunk} chunk the chunk
|
||||||
|
* @property {RuntimeTemplate} runtimeTemplate the runtime template
|
||||||
|
* @property {ModuleGraph} moduleGraph the module graph
|
||||||
|
* @property {ChunkGraph} chunkGraph the chunk graph
|
||||||
|
* @property {string} hash hash to be used for render call
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} CompilationHooks
|
||||||
|
* @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModuleContent
|
||||||
|
* @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModuleContainer
|
||||||
|
* @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModulePackage
|
||||||
|
* @property {SyncWaterfallHook<[Source, RenderContext]>} renderChunk
|
||||||
|
* @property {SyncWaterfallHook<[Source, RenderContext]>} renderMain
|
||||||
|
* @property {SyncWaterfallHook<[Source, RenderContext]>} renderWithEntry
|
||||||
|
* @property {SyncWaterfallHook<[string, RenderBootstrapContext]>} renderRequire
|
||||||
|
* @property {SyncHook<[Chunk, Hash, ChunkHashContext]>} chunkHash
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type {WeakMap<Compilation, CompilationHooks>} */
|
||||||
|
const compilationHooksMap = new WeakMap();
|
||||||
|
|
||||||
class JavascriptModulesPlugin {
|
class JavascriptModulesPlugin {
|
||||||
|
/**
|
||||||
|
* @param {Compilation} compilation the compilation
|
||||||
|
* @returns {CompilationHooks} the attached hooks
|
||||||
|
*/
|
||||||
|
static getCompilationHooks(compilation) {
|
||||||
|
if (!(compilation instanceof Compilation)) {
|
||||||
|
throw new TypeError(
|
||||||
|
"The 'compilation' argument must be an instance of JavascriptParser"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let hooks = compilationHooksMap.get(compilation);
|
||||||
|
if (hooks === undefined) {
|
||||||
|
hooks = {
|
||||||
|
renderModuleContent: new SyncWaterfallHook([
|
||||||
|
"source",
|
||||||
|
"module",
|
||||||
|
"renderContext"
|
||||||
|
]),
|
||||||
|
renderModuleContainer: new SyncWaterfallHook([
|
||||||
|
"source",
|
||||||
|
"module",
|
||||||
|
"renderContext"
|
||||||
|
]),
|
||||||
|
renderModulePackage: new SyncWaterfallHook([
|
||||||
|
"source",
|
||||||
|
"module",
|
||||||
|
"renderContext"
|
||||||
|
]),
|
||||||
|
renderWithEntry: new SyncWaterfallHook(["source", "renderContext"]),
|
||||||
|
renderChunk: new SyncWaterfallHook(["source", "renderContext"]),
|
||||||
|
renderMain: new SyncWaterfallHook(["source", "renderContext"]),
|
||||||
|
renderRequire: new SyncWaterfallHook(["code", "renderContext"]),
|
||||||
|
chunkHash: new SyncHook(["chunk", "hash", "context"])
|
||||||
|
};
|
||||||
|
compilationHooksMap.set(compilation, hooks);
|
||||||
|
}
|
||||||
|
return hooks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Compiler} compiler webpack compiler
|
* @param {Compiler} compiler webpack compiler
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
|
@ -49,6 +140,7 @@ class JavascriptModulesPlugin {
|
||||||
compiler.hooks.compilation.tap(
|
compiler.hooks.compilation.tap(
|
||||||
"JavascriptModulesPlugin",
|
"JavascriptModulesPlugin",
|
||||||
(compilation, { normalModuleFactory }) => {
|
(compilation, { normalModuleFactory }) => {
|
||||||
|
const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
|
||||||
const moduleGraph = compilation.moduleGraph;
|
const moduleGraph = compilation.moduleGraph;
|
||||||
normalModuleFactory.hooks.createParser
|
normalModuleFactory.hooks.createParser
|
||||||
.for("javascript/auto")
|
.for("javascript/auto")
|
||||||
|
@ -86,7 +178,6 @@ class JavascriptModulesPlugin {
|
||||||
const chunk = options.chunk;
|
const chunk = options.chunk;
|
||||||
const hash = options.hash;
|
const hash = options.hash;
|
||||||
const outputOptions = options.outputOptions;
|
const outputOptions = options.outputOptions;
|
||||||
const moduleTemplates = options.moduleTemplates;
|
|
||||||
const dependencyTemplates = options.dependencyTemplates;
|
const dependencyTemplates = options.dependencyTemplates;
|
||||||
|
|
||||||
const filenameTemplate =
|
const filenameTemplate =
|
||||||
|
@ -94,14 +185,17 @@ class JavascriptModulesPlugin {
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
render: () =>
|
render: () =>
|
||||||
compilation.mainTemplate.render(moduleTemplates.javascript, {
|
this.renderMain(
|
||||||
hash,
|
{
|
||||||
chunk,
|
hash,
|
||||||
dependencyTemplates,
|
chunk,
|
||||||
runtimeTemplate: options.runtimeTemplate,
|
dependencyTemplates,
|
||||||
moduleGraph: options.moduleGraph,
|
runtimeTemplate: options.runtimeTemplate,
|
||||||
chunkGraph: options.chunkGraph
|
moduleGraph: options.moduleGraph,
|
||||||
}),
|
chunkGraph: options.chunkGraph
|
||||||
|
},
|
||||||
|
hooks
|
||||||
|
),
|
||||||
filenameTemplate,
|
filenameTemplate,
|
||||||
pathOptions: {
|
pathOptions: {
|
||||||
chunk,
|
chunk,
|
||||||
|
@ -121,7 +215,6 @@ class JavascriptModulesPlugin {
|
||||||
const hotUpdateChunk =
|
const hotUpdateChunk =
|
||||||
chunk instanceof HotUpdateChunk ? chunk : null;
|
chunk instanceof HotUpdateChunk ? chunk : null;
|
||||||
const outputOptions = options.outputOptions;
|
const outputOptions = options.outputOptions;
|
||||||
const moduleTemplates = options.moduleTemplates;
|
|
||||||
const dependencyTemplates = options.dependencyTemplates;
|
const dependencyTemplates = options.dependencyTemplates;
|
||||||
|
|
||||||
if (!hotUpdateChunk && !chunkHasJs(chunk, chunkGraph)) {
|
if (!hotUpdateChunk && !chunkHasJs(chunk, chunkGraph)) {
|
||||||
|
@ -141,17 +234,17 @@ class JavascriptModulesPlugin {
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
render: () =>
|
render: () =>
|
||||||
this.renderJavascript(
|
this.renderChunk(
|
||||||
compilation,
|
compilation,
|
||||||
compilation.chunkTemplate,
|
compilation.chunkTemplate,
|
||||||
moduleTemplates.javascript,
|
|
||||||
{
|
{
|
||||||
chunk,
|
chunk,
|
||||||
dependencyTemplates,
|
dependencyTemplates,
|
||||||
runtimeTemplate: compilation.runtimeTemplate,
|
runtimeTemplate: compilation.runtimeTemplate,
|
||||||
moduleGraph,
|
moduleGraph,
|
||||||
chunkGraph: compilation.chunkGraph
|
chunkGraph: compilation.chunkGraph
|
||||||
}
|
},
|
||||||
|
hooks
|
||||||
),
|
),
|
||||||
filenameTemplate,
|
filenameTemplate,
|
||||||
pathOptions: {
|
pathOptions: {
|
||||||
|
@ -166,6 +259,30 @@ class JavascriptModulesPlugin {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
compilation.hooks.chunkHash.tap(
|
||||||
|
"JavascriptModulesPlugin",
|
||||||
|
(chunk, hash, context) => {
|
||||||
|
hooks.chunkHash.call(chunk, hash, context);
|
||||||
|
if (chunk.hasRuntime()) {
|
||||||
|
const bootstrap = this.renderBootstrap(
|
||||||
|
{
|
||||||
|
hash: "0000",
|
||||||
|
chunk,
|
||||||
|
chunkGraph: context.chunkGraph,
|
||||||
|
moduleGraph: context.moduleGraph,
|
||||||
|
runtimeTemplate: context.runtimeTemplate
|
||||||
|
},
|
||||||
|
hooks
|
||||||
|
);
|
||||||
|
for (const key of Object.keys(bootstrap)) {
|
||||||
|
hash.update(key);
|
||||||
|
for (const line of bootstrap[key]) {
|
||||||
|
hash.update(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
compilation.hooks.contentHash.tap("JavascriptModulesPlugin", chunk => {
|
compilation.hooks.contentHash.tap("JavascriptModulesPlugin", chunk => {
|
||||||
const {
|
const {
|
||||||
chunkGraph,
|
chunkGraph,
|
||||||
|
@ -181,12 +298,9 @@ class JavascriptModulesPlugin {
|
||||||
const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null;
|
const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null;
|
||||||
const hash = createHash(hashFunction);
|
const hash = createHash(hashFunction);
|
||||||
if (hashSalt) hash.update(hashSalt);
|
if (hashSalt) hash.update(hashSalt);
|
||||||
const template = chunk.hasRuntime()
|
|
||||||
? compilation.mainTemplate
|
|
||||||
: compilation.chunkTemplate;
|
|
||||||
hash.update(`${chunk.id} `);
|
hash.update(`${chunk.id} `);
|
||||||
hash.update(chunk.ids ? chunk.ids.join(",") : "");
|
hash.update(chunk.ids ? chunk.ids.join(",") : "");
|
||||||
template.updateHashForChunk(hash, chunk, {
|
hooks.chunkHash.call(chunk, hash, {
|
||||||
chunkGraph,
|
chunkGraph,
|
||||||
moduleGraph,
|
moduleGraph,
|
||||||
runtimeTemplate
|
runtimeTemplate
|
||||||
|
@ -209,36 +323,411 @@ class JavascriptModulesPlugin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Module} module the rendered module
|
||||||
|
* @param {RenderContext} renderContext options object
|
||||||
|
* @param {CompilationHooks} hooks hooks
|
||||||
|
* @returns {Source} the newly generated source from rendering
|
||||||
|
*/
|
||||||
|
renderModule(module, renderContext, hooks) {
|
||||||
|
const {
|
||||||
|
chunkGraph,
|
||||||
|
moduleGraph,
|
||||||
|
runtimeTemplate,
|
||||||
|
dependencyTemplates
|
||||||
|
} = renderContext;
|
||||||
|
try {
|
||||||
|
const moduleSource = module.source({
|
||||||
|
dependencyTemplates,
|
||||||
|
runtimeTemplate,
|
||||||
|
moduleGraph,
|
||||||
|
chunkGraph,
|
||||||
|
type: "javascript"
|
||||||
|
});
|
||||||
|
const moduleSourcePostContent = tryRunOrWebpackError(
|
||||||
|
() =>
|
||||||
|
hooks.renderModuleContent.call(moduleSource, module, renderContext),
|
||||||
|
"JavascriptModulesPlugin.getCompilationHooks().renderModuleContent"
|
||||||
|
);
|
||||||
|
const source = new ConcatSource();
|
||||||
|
const args = [];
|
||||||
|
const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
|
||||||
|
module
|
||||||
|
);
|
||||||
|
const needModule = runtimeRequirements.has(RuntimeGlobals.module);
|
||||||
|
const needExports = runtimeRequirements.has(RuntimeGlobals.exports);
|
||||||
|
const needRequire =
|
||||||
|
runtimeRequirements.has(RuntimeGlobals.require) ||
|
||||||
|
runtimeRequirements.has(RuntimeGlobals.requireScope);
|
||||||
|
const needThisAsExports = runtimeRequirements.has(
|
||||||
|
RuntimeGlobals.thisAsExports
|
||||||
|
);
|
||||||
|
if (needExports || needRequire || needModule)
|
||||||
|
args.push(
|
||||||
|
needModule
|
||||||
|
? module.moduleArgument
|
||||||
|
: "__unused_webpack_" + module.moduleArgument
|
||||||
|
);
|
||||||
|
if (needExports || needRequire)
|
||||||
|
args.push(
|
||||||
|
needExports
|
||||||
|
? module.exportsArgument
|
||||||
|
: "__unused_webpack_" + module.exportsArgument
|
||||||
|
);
|
||||||
|
if (needRequire) args.push("__webpack_require__");
|
||||||
|
if (!needThisAsExports && runtimeTemplate.supportsArrowFunction()) {
|
||||||
|
source.add("/***/ ((" + args.join(", ") + ") => {\n\n");
|
||||||
|
} else {
|
||||||
|
source.add("/***/ (function(" + args.join(", ") + ") {\n\n");
|
||||||
|
}
|
||||||
|
if (module.buildInfo.strict) source.add('"use strict";\n');
|
||||||
|
source.add(moduleSourcePostContent);
|
||||||
|
source.add("\n\n/***/ })");
|
||||||
|
const moduleSourcePostContainer = tryRunOrWebpackError(
|
||||||
|
() => hooks.renderModuleContainer.call(source, module, renderContext),
|
||||||
|
"JavascriptModulesPlugin.getCompilationHooks().renderModuleContainer"
|
||||||
|
);
|
||||||
|
return tryRunOrWebpackError(
|
||||||
|
() =>
|
||||||
|
hooks.renderModulePackage.call(
|
||||||
|
moduleSourcePostContainer,
|
||||||
|
module,
|
||||||
|
renderContext
|
||||||
|
),
|
||||||
|
"JavascriptModulesPlugin.getCompilationHooks().renderModulePackage"
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
e.module = module;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Compilation} compilation the compilation
|
* @param {Compilation} compilation the compilation
|
||||||
* @param {ChunkTemplate} chunkTemplate the chunk template
|
* @param {ChunkTemplate} chunkTemplate the chunk template
|
||||||
* @param {ModuleTemplate} moduleTemplate the module template
|
|
||||||
* @param {RenderContext} renderContext the render context
|
* @param {RenderContext} renderContext the render context
|
||||||
|
* @param {CompilationHooks} hooks hooks
|
||||||
* @returns {Source} the rendered source
|
* @returns {Source} the rendered source
|
||||||
*/
|
*/
|
||||||
renderJavascript(compilation, chunkTemplate, moduleTemplate, renderContext) {
|
renderChunk(compilation, chunkTemplate, renderContext, hooks) {
|
||||||
const chunk = renderContext.chunk;
|
const chunk = renderContext.chunk;
|
||||||
const moduleSources = Template.renderChunkModules(
|
const moduleSources = Template.renderChunkModules(
|
||||||
renderContext,
|
renderContext,
|
||||||
m => m.getSourceTypes().has("javascript"),
|
m => m.getSourceTypes().has("javascript"),
|
||||||
moduleTemplate
|
module => this.renderModule(module, renderContext, hooks)
|
||||||
);
|
);
|
||||||
const core = chunkTemplate.hooks.modules.call(
|
let source = tryRunOrWebpackError(
|
||||||
moduleSources,
|
() => hooks.renderChunk.call(moduleSources, renderContext),
|
||||||
moduleTemplate,
|
"JavascriptModulesPlugin.getCompilationHooks().renderChunk"
|
||||||
renderContext
|
|
||||||
);
|
|
||||||
let source = chunkTemplate.hooks.render.call(
|
|
||||||
core,
|
|
||||||
moduleTemplate,
|
|
||||||
renderContext
|
|
||||||
);
|
);
|
||||||
if (renderContext.chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
if (renderContext.chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
||||||
source = chunkTemplate.hooks.renderWithEntry.call(source, chunk);
|
source = tryRunOrWebpackError(
|
||||||
|
() => hooks.renderWithEntry.call(source, renderContext),
|
||||||
|
"JavascriptModulesPlugin.getCompilationHooks().renderWithEntry"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
chunk.rendered = true;
|
chunk.rendered = true;
|
||||||
return new ConcatSource(source, ";");
|
return new ConcatSource(source, ";");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MainRenderContext} renderContext options object
|
||||||
|
* @param {CompilationHooks} hooks hooks
|
||||||
|
* @returns {Source} the newly generated source from rendering
|
||||||
|
*/
|
||||||
|
renderMain(renderContext, hooks) {
|
||||||
|
const { chunk, chunkGraph, runtimeTemplate } = renderContext;
|
||||||
|
|
||||||
|
let source = new ConcatSource();
|
||||||
|
if (runtimeTemplate.supportsConst()) {
|
||||||
|
source.add("/******/ (() => { // webpackBootstrap\n");
|
||||||
|
} else {
|
||||||
|
source.add("/******/ (function() { // webpackBootstrap\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
source.add("/******/ \tvar __webpack_modules__ = (");
|
||||||
|
source.add(
|
||||||
|
Template.renderChunkModules(
|
||||||
|
renderContext,
|
||||||
|
m => m.getSourceTypes().has("javascript"),
|
||||||
|
module => this.renderModule(module, renderContext, hooks),
|
||||||
|
"/******/ \t"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
source.add(");\n");
|
||||||
|
|
||||||
|
const bootstrap = this.renderBootstrap(renderContext, hooks);
|
||||||
|
|
||||||
|
source.add(
|
||||||
|
"/************************************************************************/\n"
|
||||||
|
);
|
||||||
|
source.add(
|
||||||
|
new PrefixSource(
|
||||||
|
"/******/",
|
||||||
|
new OriginalSource(
|
||||||
|
Template.prefix(bootstrap.header, " \t") + "\n",
|
||||||
|
"webpack/bootstrap"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const runtimeModules = renderContext.chunkGraph.getChunkRuntimeModulesInOrder(
|
||||||
|
chunk
|
||||||
|
);
|
||||||
|
|
||||||
|
if (runtimeModules.length > 0) {
|
||||||
|
source.add(
|
||||||
|
"/************************************************************************/\n"
|
||||||
|
);
|
||||||
|
source.add(
|
||||||
|
Template.renderMainRuntimeModules(runtimeModules, renderContext)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
source.add(
|
||||||
|
"/************************************************************************/\n"
|
||||||
|
);
|
||||||
|
source.add(
|
||||||
|
new PrefixSource(
|
||||||
|
"/******/",
|
||||||
|
new OriginalSource(
|
||||||
|
Template.prefix(bootstrap.startup, " \t") + "\n",
|
||||||
|
"webpack/startup"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
source.add("/******/ })()\n");
|
||||||
|
|
||||||
|
/** @type {Source} */
|
||||||
|
let finalSource = tryRunOrWebpackError(
|
||||||
|
() => hooks.renderMain.call(source, renderContext),
|
||||||
|
"JavascriptModulesPlugin.getCompilationHooks().renderMain"
|
||||||
|
);
|
||||||
|
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
||||||
|
finalSource = tryRunOrWebpackError(
|
||||||
|
() => hooks.renderWithEntry.call(finalSource, renderContext),
|
||||||
|
"JavascriptModulesPlugin.getCompilationHooks().renderWithEntry"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!finalSource) {
|
||||||
|
throw new Error(
|
||||||
|
"Compiler error: MainTemplate plugin 'render' should return something"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
chunk.rendered = true;
|
||||||
|
return new ConcatSource(finalSource, ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {RenderBootstrapContext} renderContext options object
|
||||||
|
* @param {CompilationHooks} hooks hooks
|
||||||
|
* @returns {{ header: string[], startup: string[] }} the generated source of the bootstrap code
|
||||||
|
*/
|
||||||
|
renderBootstrap(renderContext, hooks) {
|
||||||
|
const { chunkGraph, chunk, runtimeTemplate } = renderContext;
|
||||||
|
|
||||||
|
const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
|
||||||
|
|
||||||
|
const requireFunction = runtimeRequirements.has(RuntimeGlobals.require);
|
||||||
|
const moduleCache = runtimeRequirements.has(RuntimeGlobals.moduleCache);
|
||||||
|
const moduleUsed = runtimeRequirements.has(RuntimeGlobals.module);
|
||||||
|
const exportsUsed = runtimeRequirements.has(RuntimeGlobals.exports);
|
||||||
|
const requireScopeUsed = runtimeRequirements.has(
|
||||||
|
RuntimeGlobals.requireScope
|
||||||
|
);
|
||||||
|
const interceptModuleExecution = runtimeRequirements.has(
|
||||||
|
RuntimeGlobals.interceptModuleExecution
|
||||||
|
);
|
||||||
|
const returnExportsFromRuntime = runtimeRequirements.has(
|
||||||
|
RuntimeGlobals.returnExportsFromRuntime
|
||||||
|
);
|
||||||
|
|
||||||
|
const useRequire =
|
||||||
|
requireFunction ||
|
||||||
|
interceptModuleExecution ||
|
||||||
|
returnExportsFromRuntime ||
|
||||||
|
moduleUsed ||
|
||||||
|
exportsUsed;
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
header: [],
|
||||||
|
startup: []
|
||||||
|
};
|
||||||
|
|
||||||
|
let buf = result.header;
|
||||||
|
let startup = result.startup;
|
||||||
|
|
||||||
|
if (useRequire || moduleCache) {
|
||||||
|
buf.push("// The module cache");
|
||||||
|
buf.push("var __webpack_module_cache__ = {};");
|
||||||
|
buf.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useRequire) {
|
||||||
|
buf.push("// The require function");
|
||||||
|
buf.push(`function __webpack_require__(moduleId) {`);
|
||||||
|
buf.push(Template.indent('"use strict";'));
|
||||||
|
buf.push(Template.indent(this.renderRequire(renderContext, hooks)));
|
||||||
|
buf.push("}");
|
||||||
|
buf.push("");
|
||||||
|
} else if (runtimeRequirements.has(RuntimeGlobals.requireScope)) {
|
||||||
|
buf.push("// The require scope");
|
||||||
|
buf.push("var __webpack_require__ = {};");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runtimeRequirements.has(RuntimeGlobals.moduleFactories)) {
|
||||||
|
buf.push("");
|
||||||
|
buf.push("// expose the modules object (__webpack_modules__)");
|
||||||
|
buf.push(`${RuntimeGlobals.moduleFactories} = __webpack_modules__;`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moduleCache) {
|
||||||
|
buf.push("");
|
||||||
|
buf.push("// expose the module cache");
|
||||||
|
buf.push(`${RuntimeGlobals.moduleCache} = __webpack_module_cache__;`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interceptModuleExecution) {
|
||||||
|
buf.push("");
|
||||||
|
buf.push("// expose the module execution interceptor");
|
||||||
|
buf.push(`${RuntimeGlobals.interceptModuleExecution} = [];`);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.push("");
|
||||||
|
if (!runtimeRequirements.has(RuntimeGlobals.startupNoDefault)) {
|
||||||
|
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
||||||
|
/** @type {string[]} */
|
||||||
|
const buf2 = [];
|
||||||
|
const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(
|
||||||
|
chunk
|
||||||
|
);
|
||||||
|
buf2.push(
|
||||||
|
returnExportsFromRuntime
|
||||||
|
? "// Load entry module and return exports"
|
||||||
|
: "// Load entry module"
|
||||||
|
);
|
||||||
|
let i = chunkGraph.getNumberOfEntryModules(chunk);
|
||||||
|
for (const entryModule of chunkGraph.getChunkEntryModulesIterable(
|
||||||
|
chunk
|
||||||
|
)) {
|
||||||
|
const mayReturn =
|
||||||
|
--i === 0 && returnExportsFromRuntime ? "return " : "";
|
||||||
|
const moduleId = chunkGraph.getModuleId(entryModule);
|
||||||
|
let moduleIdExpr = JSON.stringify(moduleId);
|
||||||
|
if (runtimeRequirements.has(RuntimeGlobals.entryModuleId)) {
|
||||||
|
moduleIdExpr = `${RuntimeGlobals.entryModuleId} = ${moduleIdExpr}`;
|
||||||
|
}
|
||||||
|
if (useRequire) {
|
||||||
|
buf2.push(`${mayReturn}__webpack_require__(${moduleIdExpr});`);
|
||||||
|
} else if (requireScopeUsed) {
|
||||||
|
buf2.push(
|
||||||
|
`__webpack_modules__[${moduleIdExpr}](0, 0, __webpack_require__);`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
buf2.push(`__webpack_modules__[${moduleIdExpr}]();`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (runtimeRequirements.has(RuntimeGlobals.startup)) {
|
||||||
|
buf.push(
|
||||||
|
Template.asString([
|
||||||
|
"// the startup function",
|
||||||
|
`${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction(
|
||||||
|
"",
|
||||||
|
buf2
|
||||||
|
)};`
|
||||||
|
])
|
||||||
|
);
|
||||||
|
startup.push("// run startup");
|
||||||
|
startup.push(`return ${RuntimeGlobals.startup}();`);
|
||||||
|
} else {
|
||||||
|
startup.push(
|
||||||
|
Template.asString(["// startup", Template.asString(buf2)])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (runtimeRequirements.has(RuntimeGlobals.startup)) {
|
||||||
|
buf.push(
|
||||||
|
Template.asString([
|
||||||
|
"// the startup function",
|
||||||
|
"// It's empty as no entry modules are in this chunk",
|
||||||
|
`${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction(
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
)}`
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (runtimeRequirements.has(RuntimeGlobals.startup)) {
|
||||||
|
startup.push("// run startup");
|
||||||
|
startup.push(`return ${RuntimeGlobals.startup}();`);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {RenderBootstrapContext} renderContext options object
|
||||||
|
* @param {CompilationHooks} hooks hooks
|
||||||
|
* @returns {string} the generated source of the require function
|
||||||
|
*/
|
||||||
|
renderRequire(renderContext, hooks) {
|
||||||
|
const {
|
||||||
|
chunk,
|
||||||
|
chunkGraph,
|
||||||
|
runtimeTemplate: { outputOptions }
|
||||||
|
} = renderContext;
|
||||||
|
const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
|
||||||
|
const moduleExecution = runtimeRequirements.has(
|
||||||
|
RuntimeGlobals.interceptModuleExecution
|
||||||
|
)
|
||||||
|
? Template.asString([
|
||||||
|
"var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };",
|
||||||
|
`${RuntimeGlobals.interceptModuleExecution}.forEach(function(handler) { handler(execOptions); });`,
|
||||||
|
"module = execOptions.module;",
|
||||||
|
"execOptions.factory.call(module.exports, module, module.exports, execOptions.require);"
|
||||||
|
])
|
||||||
|
: runtimeRequirements.has(RuntimeGlobals.thisAsExports)
|
||||||
|
? Template.asString([
|
||||||
|
"__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);"
|
||||||
|
])
|
||||||
|
: Template.asString([
|
||||||
|
"__webpack_modules__[moduleId](module, module.exports, __webpack_require__);"
|
||||||
|
]);
|
||||||
|
const content = Template.asString([
|
||||||
|
"// Check if module is in cache",
|
||||||
|
"if(__webpack_module_cache__[moduleId]) {",
|
||||||
|
Template.indent("return __webpack_module_cache__[moduleId].exports;"),
|
||||||
|
"}",
|
||||||
|
"// Create a new module (and put it into the cache)",
|
||||||
|
"var module = __webpack_module_cache__[moduleId] = {",
|
||||||
|
Template.indent(["i: moduleId,", "l: false,", "exports: {}"]),
|
||||||
|
"};",
|
||||||
|
"",
|
||||||
|
outputOptions.strictModuleExceptionHandling
|
||||||
|
? Template.asString([
|
||||||
|
"// Execute the module function",
|
||||||
|
"var threw = true;",
|
||||||
|
"try {",
|
||||||
|
Template.indent([moduleExecution, "threw = false;"]),
|
||||||
|
"} finally {",
|
||||||
|
Template.indent([
|
||||||
|
"if(threw) delete __webpack_module_cache__[moduleId];"
|
||||||
|
]),
|
||||||
|
"}"
|
||||||
|
])
|
||||||
|
: Template.asString([
|
||||||
|
"// Execute the module function",
|
||||||
|
moduleExecution
|
||||||
|
]),
|
||||||
|
"",
|
||||||
|
"// Flag the module as loaded",
|
||||||
|
"module.l = true;",
|
||||||
|
"",
|
||||||
|
"// Return the exports of the module",
|
||||||
|
"return module.exports;"
|
||||||
|
]);
|
||||||
|
return tryRunOrWebpackError(
|
||||||
|
() => hooks.renderRequire.call(content, renderContext),
|
||||||
|
"JavascriptModulesPlugin.getCompilationHooks().renderRequire"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = JavascriptModulesPlugin;
|
module.exports = JavascriptModulesPlugin;
|
||||||
|
|
|
@ -5,19 +5,16 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { SyncWaterfallHook, SyncHook } = require("tapable");
|
const { SyncWaterfallHook } = require("tapable");
|
||||||
const {
|
const util = require("util");
|
||||||
ConcatSource,
|
|
||||||
OriginalSource,
|
|
||||||
PrefixSource
|
|
||||||
} = require("webpack-sources");
|
|
||||||
const RuntimeGlobals = require("./RuntimeGlobals");
|
const RuntimeGlobals = require("./RuntimeGlobals");
|
||||||
const Template = require("./Template");
|
const memorize = require("./util/memorize");
|
||||||
|
|
||||||
/** @typedef {import("webpack-sources").ConcatSource} ConcatSource */
|
/** @typedef {import("webpack-sources").ConcatSource} ConcatSource */
|
||||||
/** @typedef {import("webpack-sources").Source} Source */
|
/** @typedef {import("webpack-sources").Source} Source */
|
||||||
/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
|
/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
|
||||||
/** @typedef {import("./Chunk")} Chunk */
|
/** @typedef {import("./Chunk")} Chunk */
|
||||||
|
/** @typedef {import("./Compilation")} Compilation */
|
||||||
/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
|
/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
|
||||||
/** @typedef {import("./Module")} Module} */
|
/** @typedef {import("./Module")} Module} */
|
||||||
/** @typedef {import("./util/Hash")} Hash} */
|
/** @typedef {import("./util/Hash")} Hash} */
|
||||||
|
@ -29,53 +26,93 @@ const Template = require("./Template");
|
||||||
/** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions} */
|
/** @typedef {import("./Template").RenderManifestOptions} RenderManifestOptions} */
|
||||||
/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry} */
|
/** @typedef {import("./Template").RenderManifestEntry} RenderManifestEntry} */
|
||||||
|
|
||||||
/**
|
const getJavascriptModulesPlugin = memorize(() =>
|
||||||
* @typedef {Object} MainRenderContext
|
require("./JavascriptModulesPlugin")
|
||||||
* @property {Chunk} chunk the chunk
|
);
|
||||||
* @property {DependencyTemplates} dependencyTemplates the dependency templates
|
|
||||||
* @property {RuntimeTemplate} runtimeTemplate the runtime template
|
|
||||||
* @property {ModuleGraph} moduleGraph the module graph
|
|
||||||
* @property {ChunkGraph} chunkGraph the chunk graph
|
|
||||||
* @property {string} hash hash to be used for render call
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
// TODO webpack 6 remove this class
|
||||||
* @typedef {Object} RenderBootstrapContext
|
class MainTemplate {
|
||||||
* @property {Chunk} chunk the chunk
|
|
||||||
* @property {RuntimeTemplate} runtimeTemplate the runtime template
|
|
||||||
* @property {ModuleGraph} moduleGraph the module graph
|
|
||||||
* @property {ChunkGraph} chunkGraph the chunk graph
|
|
||||||
* @property {string} hash hash to be used for render call
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {Object} UpdateHashForChunkContext
|
|
||||||
* @property {RuntimeTemplate} runtimeTemplate the runtime template
|
|
||||||
* @property {ModuleGraph} moduleGraph the module graph
|
|
||||||
* @property {ChunkGraph} chunkGraph the chunk graph
|
|
||||||
*/
|
|
||||||
|
|
||||||
module.exports = class MainTemplate {
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {TODO=} outputOptions output options for the MainTemplate
|
* @param {TODO=} outputOptions output options for the MainTemplate
|
||||||
|
* @param {Compilation} compilation the compilation
|
||||||
*/
|
*/
|
||||||
constructor(outputOptions) {
|
constructor(outputOptions, compilation) {
|
||||||
/** @type {TODO?} */
|
/** @type {TODO?} */
|
||||||
this.outputOptions = outputOptions || {};
|
this._outputOptions = outputOptions || {};
|
||||||
this.hooks = Object.freeze({
|
this.hooks = Object.freeze({
|
||||||
/** @type {SyncWaterfallHook<[RenderManifestEntry[], RenderManifestOptions]>} */
|
renderManifest: {
|
||||||
renderManifest: new SyncWaterfallHook(["result", "options"]),
|
tap: util.deprecate(
|
||||||
/** @type {SyncWaterfallHook<[string, RenderBootstrapContext]>} */
|
(options, fn) => {
|
||||||
require: new SyncWaterfallHook(["source", "renderContext"]),
|
compilation.hooks.renderManifest.tap(
|
||||||
/** @type {SyncWaterfallHook<[Source, Chunk, string]>} */
|
options,
|
||||||
renderWithEntry: new SyncWaterfallHook(["source", "chunk", "hash"]),
|
(entries, options) => {
|
||||||
/** @type {SyncWaterfallHook<[string, object, AssetInfo]>} */
|
if (!options.chunk.hasRuntime()) return entries;
|
||||||
assetPath: new SyncWaterfallHook(["path", "options", "assetInfo"]),
|
return fn(entries, options);
|
||||||
/** @type {SyncHook<[Hash]>} */
|
}
|
||||||
hash: new SyncHook(["hash"]),
|
);
|
||||||
/** @type {SyncHook<[Hash, Chunk]>} */
|
},
|
||||||
hashForChunk: new SyncHook(["hash", "chunk"]),
|
"MainTemplate.hooks.renderManifest is deprecated (use Compilation.hooks.renderManifest instead)",
|
||||||
|
"DEP_WEBPACK_MAIN_TEMPLATE_RENDER_MANIFEST"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
require: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
getJavascriptModulesPlugin()
|
||||||
|
.getCompilationHooks(compilation)
|
||||||
|
.renderRequire.tap(options, fn);
|
||||||
|
},
|
||||||
|
"MainTemplate.hooks.require is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderRequire instead)",
|
||||||
|
"DEP_WEBPACK_MAIN_TEMPLATE_REQUIRE"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
renderWithEntry: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
getJavascriptModulesPlugin()
|
||||||
|
.getCompilationHooks(compilation)
|
||||||
|
.renderWithEntry.tap(options, (source, renderContext) => {
|
||||||
|
if (!renderContext.chunk.hasRuntime()) return source;
|
||||||
|
return fn(source, renderContext.chunk, compilation.hash);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"MainTemplate.hooks.renderWithEntry is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderWithEntry instead)",
|
||||||
|
"DEP_WEBPACK_MAIN_TEMPLATE_RENDER_WITH_ENTRY"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
assetPath: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
compilation.hooks.assetPath.tap(options, fn);
|
||||||
|
},
|
||||||
|
"MainTemplate.hooks.assetPath is deprecated (use Compilation.hooks.assetPath instead)",
|
||||||
|
"DEP_WEBPACK_MAIN_TEMPLATE_ASSET_PATH"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
hash: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
compilation.hooks.fullHash.tap(options, fn);
|
||||||
|
},
|
||||||
|
"MainTemplate.hooks.hash is deprecated (use Compilation.hooks.fullHash instead)",
|
||||||
|
"DEP_WEBPACK_MAIN_TEMPLATE_HASH"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
hashForChunk: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
getJavascriptModulesPlugin()
|
||||||
|
.getCompilationHooks(compilation)
|
||||||
|
.chunkHash.tap(options, (chunk, hash) => {
|
||||||
|
if (!chunk.hasRuntime()) return;
|
||||||
|
return fn(hash, chunk);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"MainTemplate.hooks.hashForChunk is deprecated (use JavascriptModulesPlugin.getCompilationHooks().chunkHash instead)",
|
||||||
|
"DEP_WEBPACK_MAIN_TEMPLATE_HASH_FOR_CHUNK"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
// for compatibility:
|
// for compatibility:
|
||||||
/** @type {SyncWaterfallHook<[string, Chunk, string, ModuleTemplate, DependencyTemplates]>} */
|
/** @type {SyncWaterfallHook<[string, Chunk, string, ModuleTemplate, DependencyTemplates]>} */
|
||||||
|
@ -98,379 +135,78 @@ module.exports = class MainTemplate {
|
||||||
"chunkIdExpression"
|
"chunkIdExpression"
|
||||||
])
|
])
|
||||||
});
|
});
|
||||||
this.hooks.require.tap("MainTemplate", (source, renderContext) => {
|
|
||||||
const { chunk, chunkGraph } = renderContext;
|
|
||||||
const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
|
|
||||||
const moduleExecution = runtimeRequirements.has(
|
|
||||||
RuntimeGlobals.interceptModuleExecution
|
|
||||||
)
|
|
||||||
? Template.asString([
|
|
||||||
"var execOptions = { id: moduleId, module: module, factory: __webpack_modules__[moduleId], require: __webpack_require__ };",
|
|
||||||
`${RuntimeGlobals.interceptModuleExecution}.forEach(function(handler) { handler(execOptions); });`,
|
|
||||||
"module = execOptions.module;",
|
|
||||||
"execOptions.factory.call(module.exports, module, module.exports, execOptions.require);"
|
|
||||||
])
|
|
||||||
: runtimeRequirements.has(RuntimeGlobals.thisAsExports)
|
|
||||||
? Template.asString([
|
|
||||||
"__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);"
|
|
||||||
])
|
|
||||||
: Template.asString([
|
|
||||||
"__webpack_modules__[moduleId](module, module.exports, __webpack_require__);"
|
|
||||||
]);
|
|
||||||
return Template.asString([
|
|
||||||
source,
|
|
||||||
"// Check if module is in cache",
|
|
||||||
"if(__webpack_module_cache__[moduleId]) {",
|
|
||||||
Template.indent("return __webpack_module_cache__[moduleId].exports;"),
|
|
||||||
"}",
|
|
||||||
"// Create a new module (and put it into the cache)",
|
|
||||||
"var module = __webpack_module_cache__[moduleId] = {",
|
|
||||||
Template.indent(["i: moduleId,", "l: false,", "exports: {}"]),
|
|
||||||
"};",
|
|
||||||
"",
|
|
||||||
outputOptions.strictModuleExceptionHandling
|
|
||||||
? Template.asString([
|
|
||||||
"// Execute the module function",
|
|
||||||
"var threw = true;",
|
|
||||||
"try {",
|
|
||||||
Template.indent([moduleExecution, "threw = false;"]),
|
|
||||||
"} finally {",
|
|
||||||
Template.indent([
|
|
||||||
"if(threw) delete __webpack_module_cache__[moduleId];"
|
|
||||||
]),
|
|
||||||
"}"
|
|
||||||
])
|
|
||||||
: Template.asString([
|
|
||||||
"// Execute the module function",
|
|
||||||
moduleExecution
|
|
||||||
]),
|
|
||||||
"",
|
|
||||||
"// Flag the module as loaded",
|
|
||||||
"module.l = true;",
|
|
||||||
"",
|
|
||||||
"// Return the exports of the module",
|
|
||||||
"return module.exports;"
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO webpack 6 remove
|
this.renderCurrentHashCode = util.deprecate(
|
||||||
// BACKWARD COMPAT START
|
/**
|
||||||
get requireFn() {
|
* @deprecated
|
||||||
return "__webpack_require__";
|
* @param {string} hash the hash
|
||||||
}
|
* @param {number=} length length of the hash
|
||||||
|
* @returns {string} generated code
|
||||||
/**
|
*/ (hash, length) => {
|
||||||
* @deprecated
|
if (length) {
|
||||||
* @param {string} hash the hash
|
return `${RuntimeGlobals.getFullHash} ? ${
|
||||||
* @param {number=} length length of the hash
|
RuntimeGlobals.getFullHash
|
||||||
* @returns {string} generated code
|
}().slice(0, ${length}) : ${hash.slice(0, length)}`;
|
||||||
*/
|
|
||||||
renderCurrentHashCode(hash, length) {
|
|
||||||
if (length) {
|
|
||||||
return `${RuntimeGlobals.getFullHash} ? ${
|
|
||||||
RuntimeGlobals.getFullHash
|
|
||||||
}().slice(0, ${length}) : ${hash.slice(0, length)}`;
|
|
||||||
}
|
|
||||||
return `${RuntimeGlobals.getFullHash} ? ${RuntimeGlobals.getFullHash}() : ${hash}`;
|
|
||||||
}
|
|
||||||
// BACKWARD COMPAT END
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {RenderManifestOptions} options render manifest options
|
|
||||||
* @returns {RenderManifestEntry[]} returns render manifest
|
|
||||||
*/
|
|
||||||
getRenderManifest(options) {
|
|
||||||
const result = [];
|
|
||||||
|
|
||||||
this.hooks.renderManifest.call(result, options);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {RenderBootstrapContext} renderContext options object
|
|
||||||
* @returns {{ header: string[], startup: string[] }} the generated source of the bootstrap code
|
|
||||||
*/
|
|
||||||
renderBootstrap(renderContext) {
|
|
||||||
const { chunkGraph, chunk, runtimeTemplate } = renderContext;
|
|
||||||
|
|
||||||
const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(chunk);
|
|
||||||
|
|
||||||
const requireFunction = runtimeRequirements.has(RuntimeGlobals.require);
|
|
||||||
const moduleCache = runtimeRequirements.has(RuntimeGlobals.moduleCache);
|
|
||||||
const moduleUsed = runtimeRequirements.has(RuntimeGlobals.module);
|
|
||||||
const exportsUsed = runtimeRequirements.has(RuntimeGlobals.exports);
|
|
||||||
const requireScopeUsed = runtimeRequirements.has(
|
|
||||||
RuntimeGlobals.requireScope
|
|
||||||
);
|
|
||||||
const interceptModuleExecution = runtimeRequirements.has(
|
|
||||||
RuntimeGlobals.interceptModuleExecution
|
|
||||||
);
|
|
||||||
const returnExportsFromRuntime = runtimeRequirements.has(
|
|
||||||
RuntimeGlobals.returnExportsFromRuntime
|
|
||||||
);
|
|
||||||
|
|
||||||
const useRequire =
|
|
||||||
requireFunction ||
|
|
||||||
interceptModuleExecution ||
|
|
||||||
returnExportsFromRuntime ||
|
|
||||||
moduleUsed ||
|
|
||||||
exportsUsed;
|
|
||||||
|
|
||||||
const result = {
|
|
||||||
header: [],
|
|
||||||
startup: []
|
|
||||||
};
|
|
||||||
|
|
||||||
let buf = result.header;
|
|
||||||
let startup = result.startup;
|
|
||||||
|
|
||||||
if (useRequire || moduleCache) {
|
|
||||||
buf.push("// The module cache");
|
|
||||||
buf.push("var __webpack_module_cache__ = {};");
|
|
||||||
buf.push("");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useRequire) {
|
|
||||||
buf.push("// The require function");
|
|
||||||
buf.push(`function __webpack_require__(moduleId) {`);
|
|
||||||
buf.push(Template.indent('"use strict";'));
|
|
||||||
buf.push(Template.indent(this.hooks.require.call("", renderContext)));
|
|
||||||
buf.push("}");
|
|
||||||
buf.push("");
|
|
||||||
} else if (runtimeRequirements.has(RuntimeGlobals.requireScope)) {
|
|
||||||
buf.push("// The require scope");
|
|
||||||
buf.push("var __webpack_require__ = {};");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (runtimeRequirements.has(RuntimeGlobals.moduleFactories)) {
|
|
||||||
buf.push("");
|
|
||||||
buf.push("// expose the modules object (__webpack_modules__)");
|
|
||||||
buf.push(`${RuntimeGlobals.moduleFactories} = __webpack_modules__;`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (moduleCache) {
|
|
||||||
buf.push("");
|
|
||||||
buf.push("// expose the module cache");
|
|
||||||
buf.push(`${RuntimeGlobals.moduleCache} = __webpack_module_cache__;`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interceptModuleExecution) {
|
|
||||||
buf.push("");
|
|
||||||
buf.push("// expose the module execution interceptor");
|
|
||||||
buf.push(`${RuntimeGlobals.interceptModuleExecution} = [];`);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.push("");
|
|
||||||
if (!runtimeRequirements.has(RuntimeGlobals.startupNoDefault)) {
|
|
||||||
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
|
||||||
/** @type {string[]} */
|
|
||||||
const buf2 = [];
|
|
||||||
const runtimeRequirements = chunkGraph.getTreeRuntimeRequirements(
|
|
||||||
chunk
|
|
||||||
);
|
|
||||||
buf2.push(
|
|
||||||
returnExportsFromRuntime
|
|
||||||
? "// Load entry module and return exports"
|
|
||||||
: "// Load entry module"
|
|
||||||
);
|
|
||||||
let i = chunkGraph.getNumberOfEntryModules(chunk);
|
|
||||||
for (const entryModule of chunkGraph.getChunkEntryModulesIterable(
|
|
||||||
chunk
|
|
||||||
)) {
|
|
||||||
const mayReturn =
|
|
||||||
--i === 0 && returnExportsFromRuntime ? "return " : "";
|
|
||||||
const moduleId = chunkGraph.getModuleId(entryModule);
|
|
||||||
let moduleIdExpr = JSON.stringify(moduleId);
|
|
||||||
if (runtimeRequirements.has(RuntimeGlobals.entryModuleId)) {
|
|
||||||
moduleIdExpr = `${RuntimeGlobals.entryModuleId} = ${moduleIdExpr}`;
|
|
||||||
}
|
|
||||||
if (useRequire) {
|
|
||||||
buf2.push(`${mayReturn}__webpack_require__(${moduleIdExpr});`);
|
|
||||||
} else if (requireScopeUsed) {
|
|
||||||
buf2.push(
|
|
||||||
`__webpack_modules__[${moduleIdExpr}](0, 0, __webpack_require__);`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
buf2.push(`__webpack_modules__[${moduleIdExpr}]();`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (runtimeRequirements.has(RuntimeGlobals.startup)) {
|
return `${RuntimeGlobals.getFullHash} ? ${RuntimeGlobals.getFullHash}() : ${hash}`;
|
||||||
buf.push(
|
},
|
||||||
Template.asString([
|
"MainTemplate.renderCurrentHashCode is deprecated (use RuntimeGlobals.getFullHash runtime function instead)",
|
||||||
"// the startup function",
|
"DEP_WEBPACK_MAIN_TEMPLATE_RENDER_CURRENT_HASH_CODE"
|
||||||
`${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction(
|
);
|
||||||
"",
|
|
||||||
buf2
|
this.getPublicPath = util.deprecate(
|
||||||
)};`
|
/**
|
||||||
])
|
*
|
||||||
);
|
* @param {object} options get public path options
|
||||||
startup.push("// run startup");
|
* @returns {string} hook call
|
||||||
startup.push(`return ${RuntimeGlobals.startup}();`);
|
*/ options => {
|
||||||
} else {
|
return compilation.getAssetPath(
|
||||||
startup.push(
|
compilation.outputOptions.publicPath,
|
||||||
Template.asString(["// startup", Template.asString(buf2)])
|
options
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if (runtimeRequirements.has(RuntimeGlobals.startup)) {
|
|
||||||
buf.push(
|
|
||||||
Template.asString([
|
|
||||||
"// the startup function",
|
|
||||||
"// It's empty as no entry modules are in this chunk",
|
|
||||||
`${RuntimeGlobals.startup} = ${runtimeTemplate.basicFunction(
|
|
||||||
"",
|
|
||||||
""
|
|
||||||
)}`
|
|
||||||
])
|
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
} else if (runtimeRequirements.has(RuntimeGlobals.startup)) {
|
"MainTemplate.getPublicPath is depreacted (use Compilation.getAssetPath(compilation.outputOptions.publicPath, options) instead)",
|
||||||
startup.push("// run startup");
|
"DEP_WEBPACK_MAIN_TEMPLATE_GET_PUBLIC_PATH"
|
||||||
startup.push(`return ${RuntimeGlobals.startup}();`);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {ModuleTemplate} moduleTemplate ModuleTemplate instance for render
|
|
||||||
* @param {MainRenderContext} renderContext options object
|
|
||||||
* @returns {Source} the newly generated source from rendering
|
|
||||||
*/
|
|
||||||
render(moduleTemplate, renderContext) {
|
|
||||||
const { hash, chunk, chunkGraph, runtimeTemplate } = renderContext;
|
|
||||||
|
|
||||||
let source = new ConcatSource();
|
|
||||||
if (runtimeTemplate.supportsConst()) {
|
|
||||||
source.add("/******/ (() => { // webpackBootstrap\n");
|
|
||||||
} else {
|
|
||||||
source.add("/******/ (function() { // webpackBootstrap\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
source.add("/******/ \tvar __webpack_modules__ = (");
|
|
||||||
source.add(
|
|
||||||
Template.renderChunkModules(
|
|
||||||
renderContext,
|
|
||||||
m => m.getSourceTypes().has("javascript"),
|
|
||||||
moduleTemplate,
|
|
||||||
"/******/ \t"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
source.add(");\n");
|
|
||||||
|
|
||||||
const bootstrap = this.renderBootstrap(renderContext);
|
|
||||||
|
|
||||||
source.add(
|
|
||||||
"/************************************************************************/\n"
|
|
||||||
);
|
|
||||||
source.add(
|
|
||||||
new PrefixSource(
|
|
||||||
"/******/",
|
|
||||||
new OriginalSource(
|
|
||||||
Template.prefix(bootstrap.header, " \t") + "\n",
|
|
||||||
"webpack/bootstrap"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const runtimeModules = renderContext.chunkGraph.getChunkRuntimeModulesInOrder(
|
this.getAssetPath = util.deprecate(
|
||||||
chunk
|
(path, options) => {
|
||||||
|
return compilation.getAssetPath(path, options);
|
||||||
|
},
|
||||||
|
"MainTemplate.getAssetPath is deprecated (use Compilation.getAssetPath instead)",
|
||||||
|
"DEP_WEBPACK_MAIN_TEMPLATE_GET_ASSET_PATH"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (runtimeModules.length > 0) {
|
this.getAssetPathWithInfo = util.deprecate(
|
||||||
source.add(
|
(path, options) => {
|
||||||
"/************************************************************************/\n"
|
return compilation.getAssetPathWithInfo(path, options);
|
||||||
);
|
},
|
||||||
source.add(
|
"MainTemplate.getAssetPathWithInfo is deprecated (use Compilation.getAssetPath instead)",
|
||||||
Template.renderMainRuntimeModules(runtimeModules, renderContext)
|
"DEP_WEBPACK_MAIN_TEMPLATE_GET_ASSET_PATH_WITH_INFO"
|
||||||
);
|
|
||||||
}
|
|
||||||
source.add(
|
|
||||||
"/************************************************************************/\n"
|
|
||||||
);
|
|
||||||
source.add(
|
|
||||||
new PrefixSource(
|
|
||||||
"/******/",
|
|
||||||
new OriginalSource(
|
|
||||||
Template.prefix(bootstrap.startup, " \t") + "\n",
|
|
||||||
"webpack/startup"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
source.add("/******/ })()\n");
|
|
||||||
|
|
||||||
/** @type {Source} */
|
|
||||||
let finalSource = source;
|
|
||||||
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
|
||||||
finalSource = this.hooks.renderWithEntry.call(finalSource, chunk, hash);
|
|
||||||
}
|
|
||||||
if (!finalSource) {
|
|
||||||
throw new Error(
|
|
||||||
"Compiler error: MainTemplate plugin 'render' should return something"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
chunk.rendered = true;
|
|
||||||
return new ConcatSource(finalSource, ";");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {object} options get public path options
|
|
||||||
* @returns {string} hook call
|
|
||||||
*/
|
|
||||||
getPublicPath(options) {
|
|
||||||
return this.hooks.assetPath.call(
|
|
||||||
this.outputOptions.publicPath || "",
|
|
||||||
options,
|
|
||||||
undefined
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getAssetPath(path, options) {
|
Object.defineProperty(MainTemplate.prototype, "requireFn", {
|
||||||
return this.hooks.assetPath.call(path, options, undefined);
|
get: util.deprecate(
|
||||||
}
|
() => "__webpack_require__",
|
||||||
|
'MainTemplate.requireFn is deprecated (use "__webpack_require__")',
|
||||||
|
"DEP_WEBPACK_MAIN_TEMPLATE_REQUIRE_FN"
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
getAssetPathWithInfo(path, options) {
|
Object.defineProperty(MainTemplate.prototype, "outputOptions", {
|
||||||
const assetInfo = {};
|
get: util.deprecate(
|
||||||
// TODO webpack 5: refactor assetPath hook to receive { path, info } object
|
/**
|
||||||
const newPath = this.hooks.assetPath.call(path, options, assetInfo);
|
* @this {MainTemplate}
|
||||||
return { path: newPath, info: assetInfo };
|
* @returns {TODO} output options
|
||||||
}
|
*/
|
||||||
|
function() {
|
||||||
|
return this._outputOptions;
|
||||||
|
},
|
||||||
|
"MainTemplate.outputOptions is deprecated (use Compilation.outputOptions instead)",
|
||||||
|
"DEP_WEBPACK_MAIN_TEMPLATE_OUTPUT_OPTIONS"
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
module.exports = MainTemplate;
|
||||||
* Updates hash with information from this template
|
|
||||||
* @param {Hash} hash the hash to update
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
updateHash(hash) {
|
|
||||||
hash.update("maintemplate");
|
|
||||||
hash.update("3");
|
|
||||||
this.hooks.hash.call(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates hash with chunk-specific information from this template
|
|
||||||
* @param {Hash} hash the hash to update
|
|
||||||
* @param {Chunk} chunk the chunk
|
|
||||||
* @param {UpdateHashForChunkContext} context options object
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
updateHashForChunk(hash, chunk, context) {
|
|
||||||
this.updateHash(hash);
|
|
||||||
this.hooks.hashForChunk.call(hash, chunk);
|
|
||||||
const bootstrap = this.renderBootstrap({
|
|
||||||
hash: "0000",
|
|
||||||
chunk,
|
|
||||||
chunkGraph: context.chunkGraph,
|
|
||||||
moduleGraph: context.moduleGraph,
|
|
||||||
runtimeTemplate: context.runtimeTemplate
|
|
||||||
});
|
|
||||||
for (const key of Object.keys(bootstrap)) {
|
|
||||||
hash.update(key);
|
|
||||||
for (const line of bootstrap[key]) {
|
|
||||||
hash.update(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { ConcatSource } = require("webpack-sources");
|
const { ConcatSource } = require("webpack-sources");
|
||||||
const RuntimeGlobals = require("./RuntimeGlobals");
|
const JavascriptModulesPlugin = require("./JavascriptModulesPlugin");
|
||||||
const Template = require("./Template");
|
const Template = require("./Template");
|
||||||
|
|
||||||
|
/** @typedef {import("./Compiler")} Compiler */
|
||||||
/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
|
/** @typedef {import("./ModuleTemplate")} ModuleTemplate */
|
||||||
|
|
||||||
const joinIterableWithComma = iterable => {
|
const joinIterableWithComma = iterable => {
|
||||||
|
@ -53,66 +54,24 @@ const printExportsInfoToSource = (source, indent, exportsInfo) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class FunctionModuleTemplatePlugin {
|
class ModuleInfoHeaderPlugin {
|
||||||
constructor({ compilation }) {
|
|
||||||
this.compilation = compilation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {ModuleTemplate} moduleTemplate a module template
|
* @param {Compiler} compiler the compiler
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
apply(moduleTemplate) {
|
apply(compiler) {
|
||||||
const arrow = this.compilation.runtimeTemplate.supportsArrowFunction();
|
compiler.hooks.compilation.tap("ModuleInfoHeaderPlugin", compilation => {
|
||||||
moduleTemplate.hooks.render.tap(
|
const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
|
||||||
"FunctionModuleTemplatePlugin",
|
hooks.renderModulePackage.tap(
|
||||||
(moduleSource, module) => {
|
"ModuleInfoHeaderPlugin",
|
||||||
const { chunkGraph } = this.compilation;
|
(
|
||||||
const source = new ConcatSource();
|
moduleSource,
|
||||||
const args = [];
|
module,
|
||||||
const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
|
{ chunkGraph, moduleGraph, runtimeTemplate }
|
||||||
module
|
) => {
|
||||||
);
|
|
||||||
const needModule = runtimeRequirements.has(RuntimeGlobals.module);
|
|
||||||
const needExports = runtimeRequirements.has(RuntimeGlobals.exports);
|
|
||||||
const needRequire =
|
|
||||||
runtimeRequirements.has(RuntimeGlobals.require) ||
|
|
||||||
runtimeRequirements.has(RuntimeGlobals.requireScope);
|
|
||||||
const needThisAsExports = runtimeRequirements.has(
|
|
||||||
RuntimeGlobals.thisAsExports
|
|
||||||
);
|
|
||||||
if (needExports || needRequire || needModule)
|
|
||||||
args.push(
|
|
||||||
needModule
|
|
||||||
? module.moduleArgument
|
|
||||||
: "__unused" + module.moduleArgument
|
|
||||||
);
|
|
||||||
if (needExports || needRequire)
|
|
||||||
args.push(
|
|
||||||
needExports
|
|
||||||
? module.exportsArgument
|
|
||||||
: "__unused" + module.exportsArgument
|
|
||||||
);
|
|
||||||
if (needRequire) args.push("__webpack_require__");
|
|
||||||
if (arrow && !needThisAsExports) {
|
|
||||||
source.add("/***/ ((" + args.join(", ") + ") => {\n\n");
|
|
||||||
} else {
|
|
||||||
source.add("/***/ (function(" + args.join(", ") + ") {\n\n");
|
|
||||||
}
|
|
||||||
if (module.buildInfo.strict) source.add('"use strict";\n');
|
|
||||||
source.add(moduleSource);
|
|
||||||
source.add("\n\n/***/ })");
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
moduleTemplate.hooks.package.tap(
|
|
||||||
"FunctionModuleTemplatePlugin",
|
|
||||||
(moduleSource, module, { moduleGraph, chunkGraph }) => {
|
|
||||||
if (moduleTemplate.runtimeTemplate.outputOptions.pathinfo) {
|
|
||||||
const source = new ConcatSource();
|
const source = new ConcatSource();
|
||||||
const req = module.readableIdentifier(
|
const req = module.readableIdentifier(
|
||||||
moduleTemplate.runtimeTemplate.requestShortener
|
runtimeTemplate.requestShortener
|
||||||
);
|
);
|
||||||
const reqStr = req.replace(/\*\//g, "*_/");
|
const reqStr = req.replace(/\*\//g, "*_/");
|
||||||
const reqStrStar = "*".repeat(reqStr.length);
|
const reqStrStar = "*".repeat(reqStr.length);
|
||||||
|
@ -135,7 +94,7 @@ class FunctionModuleTemplatePlugin {
|
||||||
for (const text of optimizationBailout) {
|
for (const text of optimizationBailout) {
|
||||||
let code;
|
let code;
|
||||||
if (typeof text === "function") {
|
if (typeof text === "function") {
|
||||||
code = text(moduleTemplate.runtimeTemplate.requestShortener);
|
code = text(runtimeTemplate.requestShortener);
|
||||||
} else {
|
} else {
|
||||||
code = text;
|
code = text;
|
||||||
}
|
}
|
||||||
|
@ -145,14 +104,12 @@ class FunctionModuleTemplatePlugin {
|
||||||
source.add(moduleSource);
|
source.add(moduleSource);
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
return moduleSource;
|
);
|
||||||
}
|
hooks.chunkHash.tap("ModuleInfoHeaderPlugin", (chunk, hash) => {
|
||||||
);
|
hash.update("ModuleInfoHeaderPlugin");
|
||||||
|
hash.update("1");
|
||||||
moduleTemplate.hooks.hash.tap("FunctionModuleTemplatePlugin", hash => {
|
});
|
||||||
hash.update("FunctionModuleTemplatePlugin");
|
|
||||||
hash.update("2");
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = FunctionModuleTemplatePlugin;
|
module.exports = ModuleInfoHeaderPlugin;
|
|
@ -5,17 +5,23 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const { SyncWaterfallHook, SyncHook } = require("tapable");
|
const util = require("util");
|
||||||
|
const memorize = require("./util/memorize");
|
||||||
|
|
||||||
/** @typedef {import("webpack-sources").Source} Source */
|
/** @typedef {import("webpack-sources").Source} Source */
|
||||||
/** @typedef {import("./Chunk")} Chunk */
|
/** @typedef {import("./Chunk")} Chunk */
|
||||||
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
||||||
|
/** @typedef {import("./Compilation")} Compilation */
|
||||||
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
|
/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
|
||||||
/** @typedef {import("./Module")} Module */
|
/** @typedef {import("./Module")} Module */
|
||||||
/** @typedef {import("./ModuleGraph")} ModuleGraph */
|
/** @typedef {import("./ModuleGraph")} ModuleGraph */
|
||||||
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
|
/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
|
||||||
/** @typedef {import("./util/Hash")} Hash */
|
/** @typedef {import("./util/Hash")} Hash */
|
||||||
|
|
||||||
|
const getJavascriptModulesPlugin = memorize(() =>
|
||||||
|
require("./JavascriptModulesPlugin")
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} RenderContext
|
* @typedef {Object} RenderContext
|
||||||
* @property {Chunk} chunk the chunk
|
* @property {Chunk} chunk the chunk
|
||||||
|
@ -25,77 +31,69 @@ const { SyncWaterfallHook, SyncHook } = require("tapable");
|
||||||
* @property {ChunkGraph} chunkGraph the chunk graph
|
* @property {ChunkGraph} chunkGraph the chunk graph
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO webpack 6: remove this class
|
||||||
module.exports = class ModuleTemplate {
|
module.exports = class ModuleTemplate {
|
||||||
/**
|
/**
|
||||||
* @param {RuntimeTemplate} runtimeTemplate the runtime template
|
* @param {RuntimeTemplate} runtimeTemplate the runtime template
|
||||||
* @param {string} type the module template type
|
* @param {Compilation} compilation the compilation
|
||||||
*/
|
*/
|
||||||
constructor(runtimeTemplate, type) {
|
constructor(runtimeTemplate, compilation) {
|
||||||
this.runtimeTemplate = runtimeTemplate;
|
this.runtimeTemplate = runtimeTemplate;
|
||||||
this.type = type;
|
this.type = "javascript";
|
||||||
this.hooks = Object.freeze({
|
this.hooks = Object.freeze({
|
||||||
/** @type {SyncWaterfallHook<[Source, Module, RenderContext]>} */
|
content: {
|
||||||
content: new SyncWaterfallHook(["source", "module", "context"]),
|
tap: util.deprecate(
|
||||||
/** @type {SyncWaterfallHook<[Source, Module, RenderContext]>} */
|
(options, fn) => {
|
||||||
module: new SyncWaterfallHook(["source", "module", "context"]),
|
getJavascriptModulesPlugin()
|
||||||
/** @type {SyncWaterfallHook<[Source, Module, RenderContext]>} */
|
.getCompilationHooks(compilation)
|
||||||
render: new SyncWaterfallHook(["source", "module", "context"]),
|
.renderModuleContent.tap(options, fn);
|
||||||
/** @type {SyncWaterfallHook<[Source, Module, RenderContext]>} */
|
},
|
||||||
package: new SyncWaterfallHook(["source", "module", "context"]),
|
"ModuleTemplate.hooks.content is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderModuleContent instead)",
|
||||||
/** @type {SyncHook<[Hash]>} */
|
"DEP_MODULE_TEMPLATE_CONTENT"
|
||||||
hash: new SyncHook(["hash"])
|
)
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
getJavascriptModulesPlugin()
|
||||||
|
.getCompilationHooks(compilation)
|
||||||
|
.renderModuleContent.tap(options, fn);
|
||||||
|
},
|
||||||
|
"ModuleTemplate.hooks.module is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderModuleContent instead)",
|
||||||
|
"DEP_MODULE_TEMPLATE_MODULE"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
render: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
getJavascriptModulesPlugin()
|
||||||
|
.getCompilationHooks(compilation)
|
||||||
|
.renderModuleContainer.tap(options, fn);
|
||||||
|
},
|
||||||
|
"ModuleTemplate.hooks.render is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderModuleContainer instead)",
|
||||||
|
"DEP_MODULE_TEMPLATE_RENDER"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
package: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
getJavascriptModulesPlugin()
|
||||||
|
.getCompilationHooks(compilation)
|
||||||
|
.renderModulePackage.tap(options, fn);
|
||||||
|
},
|
||||||
|
"ModuleTemplate.hooks.package is deprecated (use JavascriptModulesPlugin.getCompilationHooks().renderModulePackage instead)",
|
||||||
|
"DEP_MODULE_TEMPLATE_PACKAGE"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
hash: {
|
||||||
|
tap: util.deprecate(
|
||||||
|
(options, fn) => {
|
||||||
|
compilation.hooks.fullHash.tap(options, fn);
|
||||||
|
},
|
||||||
|
"ModuleTemplate.hooks.package is deprecated (use Compilation.hooks.fullHash instead)",
|
||||||
|
"DEP_MODULE_TEMPLATE_HASH"
|
||||||
|
)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Module} module the module
|
|
||||||
* @param {RenderContext} ctx render ctx
|
|
||||||
* @returns {Source} the source
|
|
||||||
*/
|
|
||||||
render(module, ctx) {
|
|
||||||
try {
|
|
||||||
const {
|
|
||||||
runtimeTemplate,
|
|
||||||
dependencyTemplates,
|
|
||||||
moduleGraph,
|
|
||||||
chunkGraph
|
|
||||||
} = ctx;
|
|
||||||
const moduleSource = module.source({
|
|
||||||
dependencyTemplates,
|
|
||||||
runtimeTemplate,
|
|
||||||
moduleGraph,
|
|
||||||
chunkGraph,
|
|
||||||
type: this.type
|
|
||||||
});
|
|
||||||
const moduleSourcePostContent = this.hooks.content.call(
|
|
||||||
moduleSource,
|
|
||||||
module,
|
|
||||||
ctx
|
|
||||||
);
|
|
||||||
const moduleSourcePostModule = this.hooks.module.call(
|
|
||||||
moduleSourcePostContent,
|
|
||||||
module,
|
|
||||||
ctx
|
|
||||||
);
|
|
||||||
const moduleSourcePostRender = this.hooks.render.call(
|
|
||||||
moduleSourcePostModule,
|
|
||||||
module,
|
|
||||||
ctx
|
|
||||||
);
|
|
||||||
return this.hooks.package.call(moduleSourcePostRender, module, ctx);
|
|
||||||
} catch (e) {
|
|
||||||
e.message = `${module.identifier()}\n${e.message}`;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates hash with information from this template
|
|
||||||
* @param {Hash} hash the hash to update
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
updateHash(hash) {
|
|
||||||
hash.update("1");
|
|
||||||
this.hooks.hash.call(hash);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,7 +44,7 @@ const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
|
||||||
* @property {string} hash
|
* @property {string} hash
|
||||||
* @property {string} fullHash
|
* @property {string} fullHash
|
||||||
* @property {TODO} outputOptions
|
* @property {TODO} outputOptions
|
||||||
* @property {{asset: ModuleTemplate, javascript: ModuleTemplate, webassembly: ModuleTemplate}} moduleTemplates
|
* @property {{javascript: ModuleTemplate}} moduleTemplates
|
||||||
* @property {DependencyTemplates} dependencyTemplates
|
* @property {DependencyTemplates} dependencyTemplates
|
||||||
* @property {RuntimeTemplate} runtimeTemplate
|
* @property {RuntimeTemplate} runtimeTemplate
|
||||||
* @property {ModuleGraph} moduleGraph
|
* @property {ModuleGraph} moduleGraph
|
||||||
|
@ -226,14 +226,14 @@ class Template {
|
||||||
/**
|
/**
|
||||||
* @param {RenderContext} renderContext render context
|
* @param {RenderContext} renderContext render context
|
||||||
* @param {ModuleFilterPredicate} filterFn function used to filter modules from chunk to render
|
* @param {ModuleFilterPredicate} filterFn function used to filter modules from chunk to render
|
||||||
* @param {ModuleTemplate} moduleTemplate ModuleTemplate instance used to render modules
|
* @param {function(Module): Source} renderModule function to render a module
|
||||||
* @param {string=} prefix applying prefix strings
|
* @param {string=} prefix applying prefix strings
|
||||||
* @returns {Source} rendered chunk modules in a Source object
|
* @returns {Source} rendered chunk modules in a Source object
|
||||||
*/
|
*/
|
||||||
static renderChunkModules(
|
static renderChunkModules(
|
||||||
renderContext,
|
renderContext,
|
||||||
filterFn,
|
filterFn,
|
||||||
moduleTemplate,
|
renderModule,
|
||||||
prefix = ""
|
prefix = ""
|
||||||
) {
|
) {
|
||||||
const { chunk, chunkGraph } = renderContext;
|
const { chunk, chunkGraph } = renderContext;
|
||||||
|
@ -256,7 +256,7 @@ class Template {
|
||||||
const allModules = modules.map(module => {
|
const allModules = modules.map(module => {
|
||||||
return {
|
return {
|
||||||
id: chunkGraph.getModuleId(module),
|
id: chunkGraph.getModuleId(module),
|
||||||
source: moduleTemplate.render(module, renderContext)
|
source: renderModule(module)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
if (removedModules && removedModules.length > 0) {
|
if (removedModules && removedModules.length > 0) {
|
||||||
|
|
|
@ -12,8 +12,8 @@ const JsonModulesPlugin = require("./JsonModulesPlugin");
|
||||||
|
|
||||||
const EvalDevToolModulePlugin = require("./EvalDevToolModulePlugin");
|
const EvalDevToolModulePlugin = require("./EvalDevToolModulePlugin");
|
||||||
const EvalSourceMapDevToolPlugin = require("./EvalSourceMapDevToolPlugin");
|
const EvalSourceMapDevToolPlugin = require("./EvalSourceMapDevToolPlugin");
|
||||||
const FunctionModulePlugin = require("./FunctionModulePlugin");
|
|
||||||
const LoaderTargetPlugin = require("./LoaderTargetPlugin");
|
const LoaderTargetPlugin = require("./LoaderTargetPlugin");
|
||||||
|
const ModuleInfoHeaderPlugin = require("./ModuleInfoHeaderPlugin");
|
||||||
const SourceMapDevToolPlugin = require("./SourceMapDevToolPlugin");
|
const SourceMapDevToolPlugin = require("./SourceMapDevToolPlugin");
|
||||||
|
|
||||||
const EntryOptionPlugin = require("./EntryOptionPlugin");
|
const EntryOptionPlugin = require("./EntryOptionPlugin");
|
||||||
|
@ -81,7 +81,6 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
mangleImports: options.optimization.mangleWasmImports
|
mangleImports: options.optimization.mangleWasmImports
|
||||||
}).apply(compiler);
|
}).apply(compiler);
|
||||||
new FetchCompileAsyncWasmPlugin().apply(compiler);
|
new FetchCompileAsyncWasmPlugin().apply(compiler);
|
||||||
new FunctionModulePlugin().apply(compiler);
|
|
||||||
new NodeSourcePlugin(options.node).apply(compiler);
|
new NodeSourcePlugin(options.node).apply(compiler);
|
||||||
new LoaderTargetPlugin(options.target).apply(compiler);
|
new LoaderTargetPlugin(options.target).apply(compiler);
|
||||||
break;
|
break;
|
||||||
|
@ -97,7 +96,6 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
mangleImports: options.optimization.mangleWasmImports
|
mangleImports: options.optimization.mangleWasmImports
|
||||||
}).apply(compiler);
|
}).apply(compiler);
|
||||||
new FetchCompileAsyncWasmPlugin().apply(compiler);
|
new FetchCompileAsyncWasmPlugin().apply(compiler);
|
||||||
new FunctionModulePlugin().apply(compiler);
|
|
||||||
new NodeSourcePlugin(options.node).apply(compiler);
|
new NodeSourcePlugin(options.node).apply(compiler);
|
||||||
new LoaderTargetPlugin(options.target).apply(compiler);
|
new LoaderTargetPlugin(options.target).apply(compiler);
|
||||||
new StartupChunkDependenciesPlugin({
|
new StartupChunkDependenciesPlugin({
|
||||||
|
@ -119,7 +117,6 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
mangleImports: options.optimization.mangleWasmImports
|
mangleImports: options.optimization.mangleWasmImports
|
||||||
}).apply(compiler);
|
}).apply(compiler);
|
||||||
new ReadFileCompileAsyncWasmPlugin().apply(compiler);
|
new ReadFileCompileAsyncWasmPlugin().apply(compiler);
|
||||||
new FunctionModulePlugin().apply(compiler);
|
|
||||||
new NodeTargetPlugin().apply(compiler);
|
new NodeTargetPlugin().apply(compiler);
|
||||||
new LoaderTargetPlugin("node").apply(compiler);
|
new LoaderTargetPlugin("node").apply(compiler);
|
||||||
new StartupChunkDependenciesPlugin({
|
new StartupChunkDependenciesPlugin({
|
||||||
|
@ -133,7 +130,6 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
const ExternalsPlugin = require("./ExternalsPlugin");
|
const ExternalsPlugin = require("./ExternalsPlugin");
|
||||||
const StartupChunkDependenciesPlugin = require("./runtime/StartupChunkDependenciesPlugin");
|
const StartupChunkDependenciesPlugin = require("./runtime/StartupChunkDependenciesPlugin");
|
||||||
new JsonpTemplatePlugin().apply(compiler);
|
new JsonpTemplatePlugin().apply(compiler);
|
||||||
new FunctionModulePlugin().apply(compiler);
|
|
||||||
new NodeTargetPlugin().apply(compiler);
|
new NodeTargetPlugin().apply(compiler);
|
||||||
new ExternalsPlugin("commonjs", "nw.gui").apply(compiler);
|
new ExternalsPlugin("commonjs", "nw.gui").apply(compiler);
|
||||||
new LoaderTargetPlugin(options.target).apply(compiler);
|
new LoaderTargetPlugin(options.target).apply(compiler);
|
||||||
|
@ -150,7 +146,6 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
new NodeTemplatePlugin({
|
new NodeTemplatePlugin({
|
||||||
asyncChunkLoading: true
|
asyncChunkLoading: true
|
||||||
}).apply(compiler);
|
}).apply(compiler);
|
||||||
new FunctionModulePlugin().apply(compiler);
|
|
||||||
new NodeTargetPlugin().apply(compiler);
|
new NodeTargetPlugin().apply(compiler);
|
||||||
new ExternalsPlugin("commonjs", [
|
new ExternalsPlugin("commonjs", [
|
||||||
"app",
|
"app",
|
||||||
|
@ -202,7 +197,6 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
mangleImports: options.optimization.mangleWasmImports
|
mangleImports: options.optimization.mangleWasmImports
|
||||||
}).apply(compiler);
|
}).apply(compiler);
|
||||||
new FetchCompileAsyncWasmPlugin().apply(compiler);
|
new FetchCompileAsyncWasmPlugin().apply(compiler);
|
||||||
new FunctionModulePlugin().apply(compiler);
|
|
||||||
new NodeTargetPlugin().apply(compiler);
|
new NodeTargetPlugin().apply(compiler);
|
||||||
new ExternalsPlugin("commonjs", [
|
new ExternalsPlugin("commonjs", [
|
||||||
"clipboard",
|
"clipboard",
|
||||||
|
@ -250,6 +244,10 @@ class WebpackOptionsApply extends OptionsApply {
|
||||||
).apply(compiler);
|
).apply(compiler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.output.pathinfo) {
|
||||||
|
new ModuleInfoHeaderPlugin().apply(compiler);
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
options.devtool &&
|
options.devtool &&
|
||||||
(options.devtool.includes("sourcemap") ||
|
(options.devtool.includes("sourcemap") ||
|
||||||
|
|
|
@ -17,8 +17,6 @@ const AssetParser = require("./AssetParser");
|
||||||
/** @typedef {import("../Compiler")} Compiler */
|
/** @typedef {import("../Compiler")} Compiler */
|
||||||
/** @typedef {import("../MainTemplate")} MainTemplate */
|
/** @typedef {import("../MainTemplate")} MainTemplate */
|
||||||
/** @typedef {import("../Module")} Module */
|
/** @typedef {import("../Module")} Module */
|
||||||
/** @typedef {import("../ModuleTemplate")} ModuleTemplate */
|
|
||||||
/** @typedef {import("../ModuleTemplate").RenderContext} RenderContext */
|
|
||||||
|
|
||||||
const type = "asset";
|
const type = "asset";
|
||||||
const plugin = "AssetModulesPlugin";
|
const plugin = "AssetModulesPlugin";
|
||||||
|
@ -47,12 +45,7 @@ class AssetModulesPlugin {
|
||||||
plugin,
|
plugin,
|
||||||
(result, options) => {
|
(result, options) => {
|
||||||
const { chunkGraph, moduleGraph } = compilation;
|
const { chunkGraph, moduleGraph } = compilation;
|
||||||
const {
|
const { chunk, dependencyTemplates, runtimeTemplate } = options;
|
||||||
chunk,
|
|
||||||
moduleTemplates,
|
|
||||||
dependencyTemplates,
|
|
||||||
runtimeTemplate
|
|
||||||
} = options;
|
|
||||||
|
|
||||||
const { outputOptions } = runtimeTemplate;
|
const { outputOptions } = runtimeTemplate;
|
||||||
|
|
||||||
|
@ -66,12 +59,12 @@ class AssetModulesPlugin {
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
render: () =>
|
render: () =>
|
||||||
this.renderAsset(module, moduleTemplates.asset, {
|
module.source({
|
||||||
chunk,
|
|
||||||
chunkGraph,
|
|
||||||
moduleGraph,
|
|
||||||
dependencyTemplates,
|
dependencyTemplates,
|
||||||
runtimeTemplate
|
runtimeTemplate,
|
||||||
|
moduleGraph,
|
||||||
|
chunkGraph,
|
||||||
|
type
|
||||||
}),
|
}),
|
||||||
filenameTemplate,
|
filenameTemplate,
|
||||||
pathOptions: {
|
pathOptions: {
|
||||||
|
@ -92,17 +85,6 @@ class AssetModulesPlugin {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Module} module the module to render
|
|
||||||
* @param {ModuleTemplate} moduleTemplate the module template
|
|
||||||
* @param {RenderContext} renderContext the render context
|
|
||||||
* @returns {Source} the rendered source
|
|
||||||
*/
|
|
||||||
/* eslint-enable */
|
|
||||||
renderAsset(module, moduleTemplate, renderContext) {
|
|
||||||
return moduleTemplate.render(module, renderContext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = AssetModulesPlugin;
|
module.exports = AssetModulesPlugin;
|
||||||
|
|
|
@ -206,7 +206,7 @@ class ProfilingPlugin {
|
||||||
"Context Module Factory"
|
"Context Module Factory"
|
||||||
);
|
);
|
||||||
interceptAllParserHooks(normalModuleFactory, tracer);
|
interceptAllParserHooks(normalModuleFactory, tracer);
|
||||||
interceptTemplateInstancesFrom(compilation, tracer);
|
interceptAllJavascriptModulesPluginHooks(compilation, tracer);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -276,37 +276,6 @@ class ProfilingPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const interceptTemplateInstancesFrom = (compilation, tracer) => {
|
|
||||||
const { mainTemplate, chunkTemplate, moduleTemplates } = compilation;
|
|
||||||
|
|
||||||
const { javascript, webassembly } = moduleTemplates;
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
instance: mainTemplate,
|
|
||||||
name: "MainTemplate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instance: chunkTemplate,
|
|
||||||
name: "ChunkTemplate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instance: javascript,
|
|
||||||
name: "JavaScriptModuleTemplate"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
instance: webassembly,
|
|
||||||
name: "WebAssemblyModuleTemplate"
|
|
||||||
}
|
|
||||||
].forEach(templateObject => {
|
|
||||||
Object.keys(templateObject.instance.hooks).forEach(hookName => {
|
|
||||||
templateObject.instance.hooks[hookName].intercept(
|
|
||||||
makeInterceptorFor(templateObject.name, tracer)(hookName)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const interceptAllHooksFor = (instance, tracer, logLabel) => {
|
const interceptAllHooksFor = (instance, tracer, logLabel) => {
|
||||||
if (Reflect.has(instance, "hooks")) {
|
if (Reflect.has(instance, "hooks")) {
|
||||||
Object.keys(instance.hooks).forEach(hookName => {
|
Object.keys(instance.hooks).forEach(hookName => {
|
||||||
|
@ -336,6 +305,18 @@ const interceptAllParserHooks = (moduleFactory, tracer) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const interceptAllJavascriptModulesPluginHooks = (compilation, tracer) => {
|
||||||
|
interceptAllHooksFor(
|
||||||
|
{
|
||||||
|
hooks: require("../JavascriptModulesPlugin").getCompilationHooks(
|
||||||
|
compilation
|
||||||
|
)
|
||||||
|
},
|
||||||
|
tracer,
|
||||||
|
"JavascriptModulesPlugin"
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const makeInterceptorFor = (instance, tracer) => hookName => ({
|
const makeInterceptorFor = (instance, tracer) => hookName => ({
|
||||||
register: ({ name, type, context, fn }) => {
|
register: ({ name, type, context, fn }) => {
|
||||||
const newFn = makeNewProfiledTapFn(hookName, tracer, {
|
const newFn = makeNewProfiledTapFn(hookName, tracer, {
|
||||||
|
|
|
@ -4,8 +4,16 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
/** @template T @typedef {function(): T} FunctionReturning */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @param {FunctionReturning<T>} fn memorized function
|
||||||
|
* @returns {FunctionReturning<T>} new function
|
||||||
|
*/
|
||||||
const memorize = fn => {
|
const memorize = fn => {
|
||||||
let memorized = false;
|
let memorized = false;
|
||||||
|
/** @type {T} */
|
||||||
let result = undefined;
|
let result = undefined;
|
||||||
return () => {
|
return () => {
|
||||||
if (memorized) {
|
if (memorized) {
|
||||||
|
|
|
@ -5,18 +5,65 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const { SyncWaterfallHook } = require("tapable");
|
||||||
|
const Compilation = require("../Compilation");
|
||||||
const Generator = require("../Generator");
|
const Generator = require("../Generator");
|
||||||
|
const { tryRunOrWebpackError } = require("../HookWebpackError");
|
||||||
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency");
|
||||||
const { compareModulesById } = require("../util/comparators");
|
const { compareModulesById } = require("../util/comparators");
|
||||||
const AsyncWebAssemblyGenerator = require("./AsyncWebAssemblyGenerator");
|
const AsyncWebAssemblyGenerator = require("./AsyncWebAssemblyGenerator");
|
||||||
const AsyncWebAssemblyJavascriptGenerator = require("./AsyncWebAssemblyJavascriptGenerator");
|
const AsyncWebAssemblyJavascriptGenerator = require("./AsyncWebAssemblyJavascriptGenerator");
|
||||||
const AsyncWebAssemblyParser = require("./AsyncWebAssemblyParser");
|
const AsyncWebAssemblyParser = require("./AsyncWebAssemblyParser");
|
||||||
|
|
||||||
|
/** @typedef {import("webpack-sources").Source} Source */
|
||||||
/** @typedef {import("../Compiler")} Compiler */
|
/** @typedef {import("../Compiler")} Compiler */
|
||||||
|
/** @typedef {import("../Module")} Module */
|
||||||
|
/** @typedef {import("../Compilation")} Compilation */
|
||||||
/** @typedef {import("../Template").RenderManifestOptions} RenderManifestOptions} */
|
/** @typedef {import("../Template").RenderManifestOptions} RenderManifestOptions} */
|
||||||
/** @typedef {import("../Template").RenderManifestEntry} RenderManifestEntry} */
|
/** @typedef {import("../Template").RenderManifestEntry} RenderManifestEntry} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} RenderContext
|
||||||
|
* @property {Chunk} chunk the chunk
|
||||||
|
* @property {DependencyTemplates} dependencyTemplates the dependency templates
|
||||||
|
* @property {RuntimeTemplate} runtimeTemplate the runtime template
|
||||||
|
* @property {ModuleGraph} moduleGraph the module graph
|
||||||
|
* @property {ChunkGraph} chunkGraph the chunk graph
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} CompilationHooks
|
||||||
|
* @property {SyncWaterfallHook<[Source, Module, RenderContext]>} renderModuleContent
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type {WeakMap<Compilation, CompilationHooks>} */
|
||||||
|
const compilationHooksMap = new WeakMap();
|
||||||
|
|
||||||
class AsyncWebAssemblyModulesPlugin {
|
class AsyncWebAssemblyModulesPlugin {
|
||||||
|
/**
|
||||||
|
* @param {Compilation} compilation the compilation
|
||||||
|
* @returns {CompilationHooks} the attached hooks
|
||||||
|
*/
|
||||||
|
static getCompilationHooks(compilation) {
|
||||||
|
if (!(compilation instanceof Compilation)) {
|
||||||
|
throw new TypeError(
|
||||||
|
"The 'compilation' argument must be an instance of JavascriptParser"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let hooks = compilationHooksMap.get(compilation);
|
||||||
|
if (hooks === undefined) {
|
||||||
|
hooks = {
|
||||||
|
renderModuleContent: new SyncWaterfallHook([
|
||||||
|
"source",
|
||||||
|
"module",
|
||||||
|
"renderContext"
|
||||||
|
])
|
||||||
|
};
|
||||||
|
compilationHooksMap.set(compilation, hooks);
|
||||||
|
}
|
||||||
|
return hooks;
|
||||||
|
}
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +76,9 @@ class AsyncWebAssemblyModulesPlugin {
|
||||||
compiler.hooks.compilation.tap(
|
compiler.hooks.compilation.tap(
|
||||||
"AsyncWebAssemblyModulesPlugin",
|
"AsyncWebAssemblyModulesPlugin",
|
||||||
(compilation, { normalModuleFactory }) => {
|
(compilation, { normalModuleFactory }) => {
|
||||||
|
const hooks = AsyncWebAssemblyModulesPlugin.getCompilationHooks(
|
||||||
|
compilation
|
||||||
|
);
|
||||||
compilation.dependencyFactories.set(
|
compilation.dependencyFactories.set(
|
||||||
WebAssemblyImportDependency,
|
WebAssemblyImportDependency,
|
||||||
normalModuleFactory
|
normalModuleFactory
|
||||||
|
@ -50,62 +100,81 @@ class AsyncWebAssemblyModulesPlugin {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
compilation.hooks.renderManifest.tap(
|
||||||
*
|
"WebAssemblyModulesPlugin",
|
||||||
* @param {RenderManifestEntry[]} result render entries
|
(result, options) => {
|
||||||
* @param {RenderManifestOptions} options context options
|
const { moduleGraph, chunkGraph, runtimeTemplate } = compilation;
|
||||||
* @returns {RenderManifestEntry[]} render entries
|
const chunk = options.chunk;
|
||||||
*/
|
const outputOptions = options.outputOptions;
|
||||||
const handler = (result, options) => {
|
const dependencyTemplates = options.dependencyTemplates;
|
||||||
const { moduleGraph, chunkGraph, runtimeTemplate } = compilation;
|
|
||||||
const chunk = options.chunk;
|
|
||||||
const outputOptions = options.outputOptions;
|
|
||||||
const moduleTemplates = options.moduleTemplates;
|
|
||||||
const dependencyTemplates = options.dependencyTemplates;
|
|
||||||
|
|
||||||
for (const module of chunkGraph.getOrderedChunkModulesIterable(
|
for (const module of chunkGraph.getOrderedChunkModulesIterable(
|
||||||
chunk,
|
chunk,
|
||||||
compareModulesById(chunkGraph)
|
compareModulesById(chunkGraph)
|
||||||
)) {
|
)) {
|
||||||
if (module.type === "webassembly/async") {
|
if (module.type === "webassembly/async") {
|
||||||
const filenameTemplate = outputOptions.webassemblyModuleFilename;
|
const filenameTemplate =
|
||||||
|
outputOptions.webassemblyModuleFilename;
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
render: () =>
|
render: () =>
|
||||||
moduleTemplates.webassembly.render(module, {
|
this.renderModule(
|
||||||
chunk,
|
module,
|
||||||
dependencyTemplates,
|
{
|
||||||
runtimeTemplate,
|
chunk,
|
||||||
moduleGraph,
|
dependencyTemplates,
|
||||||
|
runtimeTemplate,
|
||||||
|
moduleGraph,
|
||||||
|
chunkGraph
|
||||||
|
},
|
||||||
|
hooks
|
||||||
|
),
|
||||||
|
filenameTemplate,
|
||||||
|
pathOptions: {
|
||||||
|
module,
|
||||||
chunkGraph
|
chunkGraph
|
||||||
}),
|
},
|
||||||
filenameTemplate,
|
auxiliary: true,
|
||||||
pathOptions: {
|
identifier: `webassemblyAsyncModule${chunkGraph.getModuleId(
|
||||||
module,
|
module
|
||||||
chunkGraph
|
)}`,
|
||||||
},
|
hash: chunkGraph.getModuleHash(module)
|
||||||
auxiliary: true,
|
});
|
||||||
identifier: `webassemblyAsyncModule${chunkGraph.getModuleId(
|
}
|
||||||
module
|
|
||||||
)}`,
|
|
||||||
hash: chunkGraph.getModuleHash(module)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
}
|
||||||
compilation.chunkTemplate.hooks.renderManifest.tap(
|
|
||||||
"WebAssemblyModulesPlugin",
|
|
||||||
handler
|
|
||||||
);
|
|
||||||
compilation.mainTemplate.hooks.renderManifest.tap(
|
|
||||||
"WebAssemblyModulesPlugin",
|
|
||||||
handler
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderModule(module, renderContext, hooks) {
|
||||||
|
const {
|
||||||
|
chunkGraph,
|
||||||
|
moduleGraph,
|
||||||
|
runtimeTemplate,
|
||||||
|
dependencyTemplates
|
||||||
|
} = renderContext;
|
||||||
|
try {
|
||||||
|
const moduleSource = module.source({
|
||||||
|
dependencyTemplates,
|
||||||
|
runtimeTemplate,
|
||||||
|
moduleGraph,
|
||||||
|
chunkGraph,
|
||||||
|
type: "webassembly"
|
||||||
|
});
|
||||||
|
return tryRunOrWebpackError(
|
||||||
|
() =>
|
||||||
|
hooks.renderModuleContent.call(moduleSource, module, renderContext),
|
||||||
|
"AsyncWebAssemblyModulesPlugin.getCompilationHooks().renderModuleContent"
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
e.module = module;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = AsyncWebAssemblyModulesPlugin;
|
module.exports = AsyncWebAssemblyModulesPlugin;
|
||||||
|
|
|
@ -64,7 +64,6 @@ class WebAssemblyModulesPlugin {
|
||||||
const { moduleGraph, chunkGraph, runtimeTemplate } = compilation;
|
const { moduleGraph, chunkGraph, runtimeTemplate } = compilation;
|
||||||
const chunk = options.chunk;
|
const chunk = options.chunk;
|
||||||
const outputOptions = options.outputOptions;
|
const outputOptions = options.outputOptions;
|
||||||
const moduleTemplates = options.moduleTemplates;
|
|
||||||
const dependencyTemplates = options.dependencyTemplates;
|
const dependencyTemplates = options.dependencyTemplates;
|
||||||
|
|
||||||
for (const module of chunkGraph.getOrderedChunkModulesIterable(
|
for (const module of chunkGraph.getOrderedChunkModulesIterable(
|
||||||
|
@ -77,17 +76,12 @@ class WebAssemblyModulesPlugin {
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
render: () =>
|
render: () =>
|
||||||
this.renderWebAssembly(
|
module.source({
|
||||||
module,
|
dependencyTemplates,
|
||||||
moduleTemplates.webassembly,
|
runtimeTemplate,
|
||||||
{
|
moduleGraph,
|
||||||
chunk,
|
chunkGraph
|
||||||
dependencyTemplates,
|
}),
|
||||||
runtimeTemplate,
|
|
||||||
moduleGraph,
|
|
||||||
chunkGraph
|
|
||||||
}
|
|
||||||
),
|
|
||||||
filenameTemplate,
|
filenameTemplate,
|
||||||
pathOptions: {
|
pathOptions: {
|
||||||
module,
|
module,
|
||||||
|
@ -132,17 +126,6 @@ class WebAssemblyModulesPlugin {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param {Module} module the wasm module
|
|
||||||
* @param {ModuleTemplate} moduleTemplate the module tempalte
|
|
||||||
* @param {RenderContext} renderContext render context
|
|
||||||
* @returns {Source} rendered source
|
|
||||||
*/
|
|
||||||
renderWebAssembly(module, moduleTemplate, renderContext) {
|
|
||||||
return moduleTemplate.render(module, renderContext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = WebAssemblyModulesPlugin;
|
module.exports = WebAssemblyModulesPlugin;
|
||||||
|
|
|
@ -1294,7 +1294,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"instanceof": "Function",
|
"instanceof": "Function",
|
||||||
"tsType": "Function"
|
"tsType": "((pathData: import(\"../lib/Compilation\").PathData, assetInfo?: import(\"../lib/Compilation\").AssetInfo) => string)"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -160,7 +160,10 @@ describe("StatsTestCases", () => {
|
||||||
const testPath = path.join(base, testName);
|
const testPath = path.join(base, testName);
|
||||||
actual = actual
|
actual = actual
|
||||||
.replace(/\r\n?/g, "\n")
|
.replace(/\r\n?/g, "\n")
|
||||||
.replace(/\(.+\) DeprecationWarning.+(\n\s+at .*)*\n?/g, "")
|
.replace(
|
||||||
|
/\([^)]+\) (\[[^\]]+\]\s*)?DeprecationWarning.+(\n\s+at .*)*\n?/g,
|
||||||
|
""
|
||||||
|
)
|
||||||
.replace(/[\t ]*Version:.+\n/g, "")
|
.replace(/[\t ]*Version:.+\n/g, "")
|
||||||
.replace(new RegExp(quotemeta(testPath), "g"), "Xdir/" + testName)
|
.replace(new RegExp(quotemeta(testPath), "g"), "Xdir/" + testName)
|
||||||
.replace(/(\w)\\(\w)/g, "$1/$2")
|
.replace(/(\w)\\(\w)/g, "$1/$2")
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,7 +19,7 @@ it("should include only one use strict per module", function() {
|
||||||
|
|
||||||
expect(matches).toEqual([
|
expect(matches).toEqual([
|
||||||
'/* unused harmony default export */ var _unused_webpack_default_export = ("a");',
|
'/* unused harmony default export */ var _unused_webpack_default_export = ("a");',
|
||||||
"/******/",
|
"/******/ // Check if module is in cache",
|
||||||
"__webpack_require__.r(__webpack_exports__);",
|
"__webpack_require__.r(__webpack_exports__);",
|
||||||
"__webpack_require__.r(__webpack_exports__);",
|
"__webpack_require__.r(__webpack_exports__);",
|
||||||
"__webpack_require__.r(__webpack_exports__);",
|
"__webpack_require__.r(__webpack_exports__);",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const { CachedSource } = require("webpack-sources");
|
const { CachedSource } = require("webpack-sources");
|
||||||
|
const AsyncWebAssemblyModulesPlugin = require("../../../../lib/wasm-async/AsyncWebAssemblyModulesPlugin");
|
||||||
|
|
||||||
/** @typedef {import("../../../lib/Compilation")} Compilation */
|
/** @typedef {import("../../../../lib/Compilation")} Compilation */
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
module: {
|
module: {
|
||||||
|
@ -25,13 +26,12 @@ module.exports = {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
compilation => {
|
compilation => {
|
||||||
compilation.moduleTemplates.webassembly.hooks.package.tap(
|
AsyncWebAssemblyModulesPlugin.getCompilationHooks(
|
||||||
"Test",
|
compilation
|
||||||
source => {
|
).renderModuleContent.tap("Test", source => {
|
||||||
// this is important to make each returned value a new instance
|
// this is important to make each returned value a new instance
|
||||||
return new CachedSource(source);
|
return new CachedSource(source);
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
const NodeTemplatePlugin = require("../../../../lib/node/NodeTemplatePlugin");
|
const NodeTemplatePlugin = require("../../../../lib/node/NodeTemplatePlugin");
|
||||||
const FunctionModulePlugin = require("../../../../lib/FunctionModulePlugin");
|
|
||||||
const SingleEntryPlugin = require("../../../../lib/SingleEntryPlugin");
|
const SingleEntryPlugin = require("../../../../lib/SingleEntryPlugin");
|
||||||
|
|
||||||
const compilerCache = new WeakMap();
|
const compilerCache = new WeakMap();
|
||||||
|
@ -14,7 +13,6 @@ module.exports = function(source) {
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
new NodeTemplatePlugin(),
|
new NodeTemplatePlugin(),
|
||||||
new FunctionModulePlugin(),
|
|
||||||
new SingleEntryPlugin(this.context, this.resource)
|
new SingleEntryPlugin(this.context, this.resource)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue