UNPKG

7.25 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const { OriginalSource, RawSource } = require("webpack-sources");
9const Module = require("./Module");
10const RuntimeGlobals = require("./RuntimeGlobals");
11const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency");
12const StaticExportsDependency = require("./dependencies/StaticExportsDependency");
13const makeSerializable = require("./util/makeSerializable");
14
15/** @typedef {import("webpack-sources").Source} Source */
16/** @typedef {import("../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
17/** @typedef {import("./ChunkGraph")} ChunkGraph */
18/** @typedef {import("./Compilation")} Compilation */
19/** @typedef {import("./Dependency").UpdateHashContext} UpdateHashContext */
20/** @typedef {import("./DependencyTemplates")} DependencyTemplates */
21/** @typedef {import("./LibManifestPlugin").ManifestModuleData} ManifestModuleData */
22/** @typedef {import("./Module").CodeGenerationContext} CodeGenerationContext */
23/** @typedef {import("./Module").CodeGenerationResult} CodeGenerationResult */
24/** @typedef {import("./Module").LibIdentOptions} LibIdentOptions */
25/** @typedef {import("./Module").NeedBuildContext} NeedBuildContext */
26/** @typedef {import("./Module").SourceContext} SourceContext */
27/** @typedef {import("./RequestShortener")} RequestShortener */
28/** @typedef {import("./ResolverFactory").ResolverWithOptions} ResolverWithOptions */
29/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */
30/** @typedef {import("./WebpackError")} WebpackError */
31/** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */
32/** @typedef {import("./util/Hash")} Hash */
33/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
34
35const TYPES = new Set(["javascript"]);
36const RUNTIME_REQUIREMENTS = new Set([
37 RuntimeGlobals.module,
38 RuntimeGlobals.require
39]);
40
41class DelegatedModule extends Module {
42 constructor(sourceRequest, data, type, userRequest, originalRequest) {
43 super("javascript/dynamic", null);
44
45 // Info from Factory
46 this.sourceRequest = sourceRequest;
47 this.request = data.id;
48 this.delegationType = type;
49 this.userRequest = userRequest;
50 this.originalRequest = originalRequest;
51 /** @type {ManifestModuleData} */
52 this.delegateData = data;
53
54 // Build info
55 this.delegatedSourceDependency = undefined;
56 }
57
58 /**
59 * @returns {Set<string>} types available (do not mutate)
60 */
61 getSourceTypes() {
62 return TYPES;
63 }
64
65 /**
66 * @param {LibIdentOptions} options options
67 * @returns {string | null} an identifier for library inclusion
68 */
69 libIdent(options) {
70 return typeof this.originalRequest === "string"
71 ? this.originalRequest
72 : this.originalRequest.libIdent(options);
73 }
74
75 /**
76 * @returns {string} a unique identifier of the module
77 */
78 identifier() {
79 return `delegated ${JSON.stringify(this.request)} from ${
80 this.sourceRequest
81 }`;
82 }
83
84 /**
85 * @param {RequestShortener} requestShortener the request shortener
86 * @returns {string} a user readable identifier of the module
87 */
88 readableIdentifier(requestShortener) {
89 return `delegated ${this.userRequest} from ${this.sourceRequest}`;
90 }
91
92 /**
93 * @param {NeedBuildContext} context context info
94 * @param {function((WebpackError | null)=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
95 * @returns {void}
96 */
97 needBuild(context, callback) {
98 return callback(null, !this.buildMeta);
99 }
100
101 /**
102 * @param {WebpackOptions} options webpack options
103 * @param {Compilation} compilation the compilation
104 * @param {ResolverWithOptions} resolver the resolver
105 * @param {InputFileSystem} fs the file system
106 * @param {function(WebpackError=): void} callback callback function
107 * @returns {void}
108 */
109 build(options, compilation, resolver, fs, callback) {
110 this.buildMeta = { ...this.delegateData.buildMeta };
111 this.buildInfo = {};
112 this.dependencies.length = 0;
113 this.delegatedSourceDependency = new DelegatedSourceDependency(
114 this.sourceRequest
115 );
116 this.addDependency(this.delegatedSourceDependency);
117 this.addDependency(
118 new StaticExportsDependency(this.delegateData.exports || true, false)
119 );
120 callback();
121 }
122
123 /**
124 * @param {CodeGenerationContext} context context for code generation
125 * @returns {CodeGenerationResult} result
126 */
127 codeGeneration({ runtimeTemplate, moduleGraph, chunkGraph }) {
128 const dep = /** @type {DelegatedSourceDependency} */ (this.dependencies[0]);
129 const sourceModule = moduleGraph.getModule(dep);
130 let str;
131
132 if (!sourceModule) {
133 str = runtimeTemplate.throwMissingModuleErrorBlock({
134 request: this.sourceRequest
135 });
136 } else {
137 str = `module.exports = (${runtimeTemplate.moduleExports({
138 module: sourceModule,
139 chunkGraph,
140 request: dep.request,
141 runtimeRequirements: new Set()
142 })})`;
143
144 switch (this.delegationType) {
145 case "require":
146 str += `(${JSON.stringify(this.request)})`;
147 break;
148 case "object":
149 str += `[${JSON.stringify(this.request)}]`;
150 break;
151 }
152
153 str += ";";
154 }
155
156 const sources = new Map();
157 if (this.useSourceMap || this.useSimpleSourceMap) {
158 sources.set("javascript", new OriginalSource(str, this.identifier()));
159 } else {
160 sources.set("javascript", new RawSource(str));
161 }
162
163 return {
164 sources,
165 runtimeRequirements: RUNTIME_REQUIREMENTS
166 };
167 }
168
169 /**
170 * @param {string=} type the source type for which the size should be estimated
171 * @returns {number} the estimated size of the module (must be non-zero)
172 */
173 size(type) {
174 return 42;
175 }
176
177 /**
178 * @param {Hash} hash the hash used to track dependencies
179 * @param {UpdateHashContext} context context
180 * @returns {void}
181 */
182 updateHash(hash, context) {
183 hash.update(this.delegationType);
184 hash.update(JSON.stringify(this.request));
185 super.updateHash(hash, context);
186 }
187
188 serialize(context) {
189 const { write } = context;
190 // constructor
191 write(this.sourceRequest);
192 write(this.delegateData);
193 write(this.delegationType);
194 write(this.userRequest);
195 write(this.originalRequest);
196 super.serialize(context);
197 }
198
199 static deserialize(context) {
200 const { read } = context;
201 const obj = new DelegatedModule(
202 read(), // sourceRequest
203 read(), // delegateData
204 read(), // delegationType
205 read(), // userRequest
206 read() // originalRequest
207 );
208 obj.deserialize(context);
209 return obj;
210 }
211
212 /**
213 * Assuming this module is in the cache. Update the (cached) module with
214 * the fresh module from the factory. Usually updates internal references
215 * and properties.
216 * @param {Module} module fresh module
217 * @returns {void}
218 */
219 updateCacheModule(module) {
220 super.updateCacheModule(module);
221 const m = /** @type {DelegatedModule} */ (module);
222 this.delegationType = m.delegationType;
223 this.userRequest = m.userRequest;
224 this.originalRequest = m.originalRequest;
225 this.delegateData = m.delegateData;
226 }
227
228 /**
229 * Assuming this module is in the cache. Remove internal references to allow freeing some memory.
230 */
231 cleanupForCache() {
232 super.cleanupForCache();
233 this.delegateData = undefined;
234 }
235}
236
237makeSerializable(DelegatedModule, "webpack/lib/DelegatedModule");
238
239module.exports = DelegatedModule;