improve public path runtime module
This commit is contained in:
parent
c67e03abc7
commit
b5719c57e2
|
@ -160,7 +160,7 @@ class RuntimePlugin {
|
|||
.tap("RuntimePlugin", (chunk, runtimeRequirements) => {
|
||||
const { outputOptions } = compilation;
|
||||
const { publicPath } = outputOptions;
|
||||
const module = new PublicPathRuntimeModule(outputOptions);
|
||||
const module = new PublicPathRuntimeModule();
|
||||
|
||||
if (
|
||||
typeof publicPath !== "string" ||
|
||||
|
@ -169,15 +169,13 @@ class RuntimePlugin {
|
|||
module.fullHash = true;
|
||||
}
|
||||
|
||||
const moduleRuntimeRequirements = PublicPathRuntimeModule.getRuntimeRequirements(
|
||||
module
|
||||
);
|
||||
compilation.addRuntimeModule(chunk, module);
|
||||
const moduleRuntimeRequirements = module.getRuntimeRequirements();
|
||||
|
||||
if (moduleRuntimeRequirements) {
|
||||
for (const req of moduleRuntimeRequirements)
|
||||
runtimeRequirements.add(req);
|
||||
}
|
||||
compilation.addRuntimeModule(chunk, module);
|
||||
return true;
|
||||
});
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
|
|
|
@ -17,54 +17,71 @@ const { getUndoPath } = require("../util/identifier");
|
|||
|
||||
class PublicPathRuntimeModule extends RuntimeModule {
|
||||
/**
|
||||
* @param {PublicPathRuntimeModule} module module
|
||||
* @returns {ReadonlyArray<string> | null} requirements
|
||||
*/
|
||||
static getRuntimeRequirements(module) {
|
||||
if (module.publicPath !== "auto" || module.scriptType === "module")
|
||||
return null;
|
||||
getRuntimeRequirements() {
|
||||
const { compilation } = this;
|
||||
const { publicPath, scriptType } = compilation.outputOptions;
|
||||
if (publicPath !== "auto" || scriptType === "module") return null;
|
||||
|
||||
return [RuntimeGlobals.global];
|
||||
}
|
||||
/**
|
||||
* @param {OutputOptions} outputOptions output options
|
||||
*/
|
||||
constructor(outputOptions) {
|
||||
super("publicPath");
|
||||
const { publicPath, scriptType, importFunctionName } = outputOptions;
|
||||
this.publicPath = publicPath;
|
||||
this.scriptType = scriptType;
|
||||
this.importName = importFunctionName;
|
||||
|
||||
constructor() {
|
||||
super("publicPath", 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const { compilation, importName, publicPath, scriptType } = this;
|
||||
const { runtimeTemplate } = compilation;
|
||||
const { compilation } = this;
|
||||
const {
|
||||
publicPath,
|
||||
scriptType,
|
||||
importFunctionName
|
||||
} = compilation.outputOptions;
|
||||
if (publicPath === "auto") {
|
||||
if (scriptType === "module") {
|
||||
return `${RuntimeGlobals.publicPath} = ${this.applyUndoPath(
|
||||
`${importName}.meta.url.replace(/[^\\/]+$/, "")`,
|
||||
runtimeTemplate
|
||||
)};`;
|
||||
}
|
||||
|
||||
return `${RuntimeGlobals.publicPath} = ${runtimeTemplate.iife(
|
||||
"",
|
||||
Template.indent([
|
||||
`if ("document" in ${RuntimeGlobals.global} && "currentScript" in ${RuntimeGlobals.global}.document) `,
|
||||
Template.indent(
|
||||
`return ${this.applyUndoPath(
|
||||
`${RuntimeGlobals.global}.document.currentScript.src.replace(/[^\\/]+$/, "")`,
|
||||
runtimeTemplate
|
||||
)};`
|
||||
),
|
||||
" else ",
|
||||
Template.indent(`return ${this.definePath("")};`)
|
||||
])
|
||||
)}`;
|
||||
const chunkName = compilation.getPath(
|
||||
JavascriptModulesPlugin.getChunkFilenameTemplate(
|
||||
this.chunk,
|
||||
compilation.outputOptions
|
||||
),
|
||||
{
|
||||
chunk: this.chunk,
|
||||
contentHashType: "javascript"
|
||||
}
|
||||
);
|
||||
const undoPath = getUndoPath(chunkName, false);
|
||||
return Template.asString([
|
||||
"var scriptUrl;",
|
||||
scriptType === "module"
|
||||
? `if (typeof ${importFunctionName}.meta.url === "string") scriptUrl = ${importFunctionName}.meta.url`
|
||||
: Template.asString([
|
||||
`var document = ${RuntimeGlobals.global}.document;`,
|
||||
"if (document) {",
|
||||
Template.indent([
|
||||
`if (document.currentScript)`,
|
||||
Template.indent(`scriptUrl = document.currentScript.src`),
|
||||
"if (!scriptUrl) {",
|
||||
Template.indent([
|
||||
'var scripts = document.getElementsByTagName("script");',
|
||||
"if(scripts.length) scriptUrl = scripts[scripts.length - 1].src"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration",
|
||||
'// or pass an empty string ("") and set the __webpack_public_path__ variable from your code to use your own logic.',
|
||||
'if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");',
|
||||
'scriptUrl = scriptUrl.replace(/#.*$/, "").replace(/\\?.*$/, "").replace(/\\/[^\\/]+$/, "/");',
|
||||
!undoPath
|
||||
? `${RuntimeGlobals.publicPath} = scriptUrl;`
|
||||
: `${RuntimeGlobals.publicPath} = scriptUrl + ${JSON.stringify(
|
||||
undoPath
|
||||
)};`
|
||||
]);
|
||||
} else {
|
||||
return `${RuntimeGlobals.publicPath} = ${this.definePath(publicPath)};`;
|
||||
}
|
||||
|
@ -81,33 +98,6 @@ class PublicPathRuntimeModule extends RuntimeModule {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} code code
|
||||
* @param {RuntimeTemplate} runtimeTemplate runtime template
|
||||
* @returns {string} generated code
|
||||
*/
|
||||
applyUndoPath(code, runtimeTemplate) {
|
||||
const chunkName = this.compilation.getPath(
|
||||
JavascriptModulesPlugin.getChunkFilenameTemplate(
|
||||
this.chunk,
|
||||
this.compilation.outputOptions
|
||||
),
|
||||
{
|
||||
chunk: this.chunk,
|
||||
contentHashType: "javascript"
|
||||
}
|
||||
);
|
||||
const undoPath = getUndoPath(chunkName, false);
|
||||
|
||||
if (!undoPath) return code;
|
||||
|
||||
if (runtimeTemplate.supportTemplateLiteral()) {
|
||||
return `\`$\{${code}}$\{${JSON.stringify(undoPath)}}\``;
|
||||
}
|
||||
|
||||
return `${code} + ${JSON.stringify(undoPath)}`;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PublicPathRuntimeModule;
|
||||
|
|
|
@ -173,10 +173,10 @@ describe("Stats", () => {
|
|||
"assets": Array [
|
||||
Object {
|
||||
"name": "entryB.js",
|
||||
"size": 2452,
|
||||
"size": 2651,
|
||||
},
|
||||
],
|
||||
"assetsSize": 2452,
|
||||
"assetsSize": 2651,
|
||||
"auxiliaryAssets": undefined,
|
||||
"auxiliaryAssetsSize": 0,
|
||||
"childAssets": undefined,
|
||||
|
@ -258,10 +258,10 @@ describe("Stats", () => {
|
|||
"filteredRelated": undefined,
|
||||
"info": Object {
|
||||
"minimized": true,
|
||||
"size": 2452,
|
||||
"size": 2651,
|
||||
},
|
||||
"name": "entryB.js",
|
||||
"size": 2452,
|
||||
"size": 2651,
|
||||
"type": "asset",
|
||||
},
|
||||
],
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue