马宇豪
2024-07-16 f591c27b57e2418c9495bc02ae8cfff84d35bc18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
    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");
 
class AutoPublicPathRuntimeModule extends RuntimeModule {
    constructor() {
        super("publicPath", RuntimeModule.STAGE_BASIC);
    }
 
    /**
     * @returns {string} runtime code
     */
    generate() {
        const { compilation } = this;
        const { scriptType, importMetaName, path } = compilation.outputOptions;
        const chunkName = compilation.getPath(
            JavascriptModulesPlugin.getChunkFilenameTemplate(
                this.chunk,
                compilation.outputOptions
            ),
            {
                chunk: this.chunk,
                contentHashType: "javascript"
            }
        );
        const undoPath = getUndoPath(
            chunkName,
            /** @type {string} */ (path),
            false
        );
 
        return Template.asString([
            "var scriptUrl;",
            scriptType === "module"
                ? `if (typeof ${importMetaName}.url === "string") scriptUrl = ${importMetaName}.url`
                : Template.asString([
                        `if (${RuntimeGlobals.global}.importScripts) scriptUrl = ${RuntimeGlobals.global}.location + "";`,
                        `var document = ${RuntimeGlobals.global}.document;`,
                        "if (!scriptUrl && document) {",
                        Template.indent([
                            `if (document.currentScript)`,
                            Template.indent(`scriptUrl = document.currentScript.src;`),
                            "if (!scriptUrl) {",
                            Template.indent([
                                'var scripts = document.getElementsByTagName("script");',
                                "if(scripts.length) {",
                                Template.indent([
                                    "var i = scripts.length - 1;",
                                    "while (i > -1 && !scriptUrl) scriptUrl = scripts[i--].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
                  )};`
        ]);
    }
}
 
module.exports = AutoPublicPathRuntimeModule;