webpack/lib/runtime/PublicPathRuntimeModule.js

114 lines
3.1 KiB
JavaScript
Raw Normal View History

/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");
const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
const { getUndoPath } = require("../util/identifier");
2020-09-17 04:07:06 +08:00
/** @typedef {import("../../declarations/WebpackOptions").Output} OutputOptions */
/** @typedef {import("../../declarations/WebpackOptions").PublicPath} PublicPathOptions */
2018-12-18 05:05:08 +08:00
/** @typedef {import("../Compilation")} Compilation */
2020-09-17 04:07:06 +08:00
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
2018-12-18 05:05:08 +08:00
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;
return [RuntimeGlobals.global];
}
/**
2020-09-17 04:07:06 +08:00
* @param {OutputOptions} outputOptions output options
*/
constructor(outputOptions) {
super("publicPath");
2020-09-17 04:07:06 +08:00
const { publicPath, scriptType, importFunctionName } = outputOptions;
this.publicPath = publicPath;
this.scriptType = scriptType;
2020-09-17 04:07:06 +08:00
this.importName = importFunctionName;
}
/**
* @returns {string} runtime code
*/
generate() {
2020-09-16 02:03:05 +08:00
const { compilation, importName, publicPath, scriptType } = this;
const { runtimeTemplate } = compilation;
if (publicPath === "auto") {
if (scriptType === "module") {
2020-09-17 04:07:06 +08:00
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(
2020-09-17 04:07:06 +08:00
`return ${this.applyUndoPath(
`${RuntimeGlobals.global}.document.currentScript.src.replace(/[^\\/]+$/, "")`,
runtimeTemplate
)};`
),
" else ",
Template.indent(`return ${this.definePath("")};`)
])
)}`;
} else {
return `${RuntimeGlobals.publicPath} = ${this.definePath(publicPath)};`;
}
}
/**
2020-09-17 04:07:06 +08:00
* @param {PublicPathOptions} publicPath public path
* @returns {string} runtime code
*/
definePath(publicPath) {
return JSON.stringify(
this.compilation.getPath(publicPath || "", {
hash: this.compilation.hash || "XXXX"
})
);
}
2020-09-17 04:07:06 +08:00
/**
* @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);
2020-09-17 04:07:06 +08:00
if (!undoPath) return code;
if (runtimeTemplate.supportTemplateLiteral()) {
return `\`$\{${code}}$\{${JSON.stringify(undoPath)}}\``;
2020-09-17 04:07:06 +08:00
}
return `${code} + ${JSON.stringify(undoPath)}`;
2020-09-17 04:07:06 +08:00
}
}
module.exports = PublicPathRuntimeModule;