1 | /*
|
---|
2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
---|
3 | Author Tobias Koppers @sokra
|
---|
4 | */
|
---|
5 |
|
---|
6 | "use strict";
|
---|
7 |
|
---|
8 | const { ConcatSource, RawSource } = require("webpack-sources");
|
---|
9 | const ExternalModule = require("./ExternalModule");
|
---|
10 | const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
|
---|
11 | const RuntimeGlobals = require("./RuntimeGlobals");
|
---|
12 | const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
|
---|
13 |
|
---|
14 | /** @typedef {import("webpack-sources").Source} Source */
|
---|
15 | /** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
|
---|
16 | /** @typedef {import("./Compiler")} Compiler */
|
---|
17 |
|
---|
18 | /** @type {WeakMap<Source, Source>} */
|
---|
19 | const cache = new WeakMap();
|
---|
20 |
|
---|
21 | const devtoolWarning = new RawSource(`/*
|
---|
22 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
---|
23 | * This devtool is neither made for production nor for readable output files.
|
---|
24 | * It uses "eval()" calls to create a separate source file in the browser devtools.
|
---|
25 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
---|
26 | * or disable the default devtool with "devtool: false".
|
---|
27 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
---|
28 | */
|
---|
29 | `);
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * @typedef {object} EvalDevToolModulePluginOptions
|
---|
33 | * @property {OutputOptions["devtoolNamespace"]=} namespace namespace
|
---|
34 | * @property {string=} sourceUrlComment source url comment
|
---|
35 | * @property {OutputOptions["devtoolModuleFilenameTemplate"]=} moduleFilenameTemplate module filename template
|
---|
36 | */
|
---|
37 |
|
---|
38 | class EvalDevToolModulePlugin {
|
---|
39 | /**
|
---|
40 | * @param {EvalDevToolModulePluginOptions=} options options
|
---|
41 | */
|
---|
42 | constructor(options = {}) {
|
---|
43 | this.namespace = options.namespace || "";
|
---|
44 | this.sourceUrlComment = options.sourceUrlComment || "\n//# sourceURL=[url]";
|
---|
45 | this.moduleFilenameTemplate =
|
---|
46 | options.moduleFilenameTemplate ||
|
---|
47 | "webpack://[namespace]/[resourcePath]?[loaders]";
|
---|
48 | }
|
---|
49 |
|
---|
50 | /**
|
---|
51 | * Apply the plugin
|
---|
52 | * @param {Compiler} compiler the compiler instance
|
---|
53 | * @returns {void}
|
---|
54 | */
|
---|
55 | apply(compiler) {
|
---|
56 | compiler.hooks.compilation.tap("EvalDevToolModulePlugin", compilation => {
|
---|
57 | const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
|
---|
58 | hooks.renderModuleContent.tap(
|
---|
59 | "EvalDevToolModulePlugin",
|
---|
60 | (source, module, { chunk, runtimeTemplate, chunkGraph }) => {
|
---|
61 | const cacheEntry = cache.get(source);
|
---|
62 | if (cacheEntry !== undefined) return cacheEntry;
|
---|
63 | if (module instanceof ExternalModule) {
|
---|
64 | cache.set(source, source);
|
---|
65 | return source;
|
---|
66 | }
|
---|
67 | const content = source.source();
|
---|
68 | const namespace = compilation.getPath(this.namespace, {
|
---|
69 | chunk
|
---|
70 | });
|
---|
71 | const str = ModuleFilenameHelpers.createFilename(
|
---|
72 | module,
|
---|
73 | {
|
---|
74 | moduleFilenameTemplate: this.moduleFilenameTemplate,
|
---|
75 | namespace
|
---|
76 | },
|
---|
77 | {
|
---|
78 | requestShortener: runtimeTemplate.requestShortener,
|
---|
79 | chunkGraph,
|
---|
80 | hashFunction: compilation.outputOptions.hashFunction
|
---|
81 | }
|
---|
82 | );
|
---|
83 | const footer = `\n${this.sourceUrlComment.replace(
|
---|
84 | /\[url\]/g,
|
---|
85 | encodeURI(str)
|
---|
86 | .replace(/%2F/g, "/")
|
---|
87 | .replace(/%20/g, "_")
|
---|
88 | .replace(/%5E/g, "^")
|
---|
89 | .replace(/%5C/g, "\\")
|
---|
90 | .replace(/^\//, "")
|
---|
91 | )}`;
|
---|
92 | const result = new RawSource(
|
---|
93 | `eval(${
|
---|
94 | compilation.outputOptions.trustedTypes
|
---|
95 | ? `${RuntimeGlobals.createScript}(${JSON.stringify(
|
---|
96 | content + footer
|
---|
97 | )})`
|
---|
98 | : JSON.stringify(content + footer)
|
---|
99 | });`
|
---|
100 | );
|
---|
101 | cache.set(source, result);
|
---|
102 | return result;
|
---|
103 | }
|
---|
104 | );
|
---|
105 | hooks.inlineInRuntimeBailout.tap(
|
---|
106 | "EvalDevToolModulePlugin",
|
---|
107 | () => "the eval devtool is used."
|
---|
108 | );
|
---|
109 | hooks.render.tap(
|
---|
110 | "EvalDevToolModulePlugin",
|
---|
111 | source => new ConcatSource(devtoolWarning, source)
|
---|
112 | );
|
---|
113 | hooks.chunkHash.tap("EvalDevToolModulePlugin", (chunk, hash) => {
|
---|
114 | hash.update("EvalDevToolModulePlugin");
|
---|
115 | hash.update("2");
|
---|
116 | });
|
---|
117 | if (compilation.outputOptions.trustedTypes) {
|
---|
118 | compilation.hooks.additionalModuleRuntimeRequirements.tap(
|
---|
119 | "EvalDevToolModulePlugin",
|
---|
120 | (module, set, context) => {
|
---|
121 | set.add(RuntimeGlobals.createScript);
|
---|
122 | }
|
---|
123 | );
|
---|
124 | }
|
---|
125 | });
|
---|
126 | }
|
---|
127 | }
|
---|
128 |
|
---|
129 | module.exports = EvalDevToolModulePlugin;
|
---|