1 |
|
2 |
|
3 |
|
4 |
|
5 | "use strict";
|
6 |
|
7 | const { RawSource } = require("webpack-sources");
|
8 | const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
|
9 |
|
10 | const cache = new WeakMap();
|
11 |
|
12 | class EvalSourceMapDevToolModuleTemplatePlugin {
|
13 | constructor(compilation, options) {
|
14 | this.compilation = compilation;
|
15 | this.sourceMapComment =
|
16 | options.append || "//# sourceURL=[module]\n//# sourceMappingURL=[url]";
|
17 | this.moduleFilenameTemplate =
|
18 | options.moduleFilenameTemplate ||
|
19 | "webpack://[namespace]/[resource-path]?[hash]";
|
20 | this.namespace = options.namespace || "";
|
21 | this.options = options;
|
22 | }
|
23 |
|
24 | apply(moduleTemplate) {
|
25 | const self = this;
|
26 | const options = this.options;
|
27 | const matchModule = ModuleFilenameHelpers.matchObject.bind(
|
28 | ModuleFilenameHelpers,
|
29 | options
|
30 | );
|
31 | moduleTemplate.hooks.module.tap(
|
32 | "EvalSourceMapDevToolModuleTemplatePlugin",
|
33 | (source, module) => {
|
34 | const cachedSource = cache.get(source);
|
35 | if (cachedSource !== undefined) {
|
36 | return cachedSource;
|
37 | }
|
38 |
|
39 | if (!matchModule(module.resource)) {
|
40 | return source;
|
41 | }
|
42 |
|
43 |
|
44 | let sourceMap;
|
45 | let content;
|
46 | if (source.sourceAndMap) {
|
47 | const sourceAndMap = source.sourceAndMap(options);
|
48 | sourceMap = sourceAndMap.map;
|
49 | content = sourceAndMap.source;
|
50 | } else {
|
51 | sourceMap = source.map(options);
|
52 | content = source.source();
|
53 | }
|
54 | if (!sourceMap) {
|
55 | return source;
|
56 | }
|
57 |
|
58 |
|
59 | sourceMap = Object.keys(sourceMap).reduce((obj, key) => {
|
60 | obj[key] = sourceMap[key];
|
61 | return obj;
|
62 | }, {});
|
63 | const modules = sourceMap.sources.map(source => {
|
64 | const module = self.compilation.findModule(source);
|
65 | return module || source;
|
66 | });
|
67 | let moduleFilenames = modules.map(module => {
|
68 | return ModuleFilenameHelpers.createFilename(
|
69 | module,
|
70 | {
|
71 | moduleFilenameTemplate: self.moduleFilenameTemplate,
|
72 | namespace: self.namespace
|
73 | },
|
74 | moduleTemplate.runtimeTemplate.requestShortener
|
75 | );
|
76 | });
|
77 | moduleFilenames = ModuleFilenameHelpers.replaceDuplicates(
|
78 | moduleFilenames,
|
79 | (filename, i, n) => {
|
80 | for (let j = 0; j < n; j++) filename += "*";
|
81 | return filename;
|
82 | }
|
83 | );
|
84 | sourceMap.sources = moduleFilenames;
|
85 | sourceMap.sourceRoot = options.sourceRoot || "";
|
86 | sourceMap.file = `${module.id}.js`;
|
87 |
|
88 | const footer =
|
89 | self.sourceMapComment.replace(
|
90 | /\[url\]/g,
|
91 | `data:application/json;charset=utf-8;base64,${Buffer.from(
|
92 | JSON.stringify(sourceMap),
|
93 | "utf8"
|
94 | ).toString("base64")}`
|
95 | ) + `\n//# sourceURL=webpack-internal:///${module.id}\n`;
|
96 |
|
97 | const evalSource = new RawSource(
|
98 | `eval(${JSON.stringify(content + footer)});`
|
99 | );
|
100 |
|
101 | cache.set(source, evalSource);
|
102 |
|
103 | return evalSource;
|
104 | }
|
105 | );
|
106 | moduleTemplate.hooks.hash.tap(
|
107 | "EvalSourceMapDevToolModuleTemplatePlugin",
|
108 | hash => {
|
109 | hash.update("eval-source-map");
|
110 | hash.update("2");
|
111 | }
|
112 | );
|
113 | }
|
114 | }
|
115 | module.exports = EvalSourceMapDevToolModuleTemplatePlugin;
|