1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | "use strict";
|
7 |
|
8 | const RuntimeGlobals = require("../RuntimeGlobals");
|
9 | const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin");
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | const COMMON_LIBRARY_NAME_MESSAGE =
|
25 | "Common configuration options that specific library names are 'output.library[.name]', 'entry.xyz.library[.name]', 'ModuleFederationPlugin.name' and 'ModuleFederationPlugin.library[.name]'.";
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | class AbstractLibraryPlugin {
|
39 | |
40 |
|
41 |
|
42 |
|
43 |
|
44 | constructor({ pluginName, type }) {
|
45 | this._pluginName = pluginName;
|
46 | this._type = type;
|
47 | this._parseCache = new WeakMap();
|
48 | }
|
49 |
|
50 | |
51 |
|
52 |
|
53 |
|
54 |
|
55 | apply(compiler) {
|
56 | const { _pluginName } = this;
|
57 | compiler.hooks.thisCompilation.tap(_pluginName, compilation => {
|
58 | compilation.hooks.finishModules.tap(
|
59 | { name: _pluginName, stage: 10 },
|
60 | () => {
|
61 | for (const [
|
62 | name,
|
63 | {
|
64 | dependencies: deps,
|
65 | options: { library }
|
66 | }
|
67 | ] of compilation.entries) {
|
68 | const options = this._parseOptionsCached(
|
69 | library !== undefined
|
70 | ? library
|
71 | : compilation.outputOptions.library
|
72 | );
|
73 | if (options !== false) {
|
74 | const dep = deps[deps.length - 1];
|
75 | if (dep) {
|
76 | const module = compilation.moduleGraph.getModule(dep);
|
77 | if (module) {
|
78 | this.finishEntryModule(module, name, {
|
79 | options,
|
80 | compilation,
|
81 | chunkGraph: compilation.chunkGraph
|
82 | });
|
83 | }
|
84 | }
|
85 | }
|
86 | }
|
87 | }
|
88 | );
|
89 |
|
90 | const getOptionsForChunk = chunk => {
|
91 | if (compilation.chunkGraph.getNumberOfEntryModules(chunk) === 0)
|
92 | return false;
|
93 | const options = chunk.getEntryOptions();
|
94 | const library = options && options.library;
|
95 | return this._parseOptionsCached(
|
96 | library !== undefined ? library : compilation.outputOptions.library
|
97 | );
|
98 | };
|
99 |
|
100 | if (
|
101 | this.render !== AbstractLibraryPlugin.prototype.render ||
|
102 | this.runtimeRequirements !==
|
103 | AbstractLibraryPlugin.prototype.runtimeRequirements
|
104 | ) {
|
105 | compilation.hooks.additionalChunkRuntimeRequirements.tap(
|
106 | _pluginName,
|
107 | (chunk, set, { chunkGraph }) => {
|
108 | const options = getOptionsForChunk(chunk);
|
109 | if (options !== false) {
|
110 | this.runtimeRequirements(chunk, set, {
|
111 | options,
|
112 | compilation,
|
113 | chunkGraph
|
114 | });
|
115 | }
|
116 | }
|
117 | );
|
118 | }
|
119 |
|
120 | const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
|
121 |
|
122 | if (this.render !== AbstractLibraryPlugin.prototype.render) {
|
123 | hooks.render.tap(_pluginName, (source, renderContext) => {
|
124 | const options = getOptionsForChunk(renderContext.chunk);
|
125 | if (options === false) return source;
|
126 | return this.render(source, renderContext, {
|
127 | options,
|
128 | compilation,
|
129 | chunkGraph: compilation.chunkGraph
|
130 | });
|
131 | });
|
132 | }
|
133 |
|
134 | if (
|
135 | this.embedInRuntimeBailout !==
|
136 | AbstractLibraryPlugin.prototype.embedInRuntimeBailout
|
137 | ) {
|
138 | hooks.embedInRuntimeBailout.tap(
|
139 | _pluginName,
|
140 | (module, renderContext) => {
|
141 | const options = getOptionsForChunk(renderContext.chunk);
|
142 | if (options === false) return;
|
143 | return this.embedInRuntimeBailout(module, renderContext, {
|
144 | options,
|
145 | compilation,
|
146 | chunkGraph: compilation.chunkGraph
|
147 | });
|
148 | }
|
149 | );
|
150 | }
|
151 |
|
152 | if (
|
153 | this.strictRuntimeBailout !==
|
154 | AbstractLibraryPlugin.prototype.strictRuntimeBailout
|
155 | ) {
|
156 | hooks.strictRuntimeBailout.tap(_pluginName, renderContext => {
|
157 | const options = getOptionsForChunk(renderContext.chunk);
|
158 | if (options === false) return;
|
159 | return this.strictRuntimeBailout(renderContext, {
|
160 | options,
|
161 | compilation,
|
162 | chunkGraph: compilation.chunkGraph
|
163 | });
|
164 | });
|
165 | }
|
166 |
|
167 | if (
|
168 | this.renderStartup !== AbstractLibraryPlugin.prototype.renderStartup
|
169 | ) {
|
170 | hooks.renderStartup.tap(
|
171 | _pluginName,
|
172 | (source, module, renderContext) => {
|
173 | const options = getOptionsForChunk(renderContext.chunk);
|
174 | if (options === false) return source;
|
175 | return this.renderStartup(source, module, renderContext, {
|
176 | options,
|
177 | compilation,
|
178 | chunkGraph: compilation.chunkGraph
|
179 | });
|
180 | }
|
181 | );
|
182 | }
|
183 |
|
184 | hooks.chunkHash.tap(_pluginName, (chunk, hash, context) => {
|
185 | const options = getOptionsForChunk(chunk);
|
186 | if (options === false) return;
|
187 | this.chunkHash(chunk, hash, context, {
|
188 | options,
|
189 | compilation,
|
190 | chunkGraph: compilation.chunkGraph
|
191 | });
|
192 | });
|
193 | });
|
194 | }
|
195 |
|
196 | |
197 |
|
198 |
|
199 |
|
200 | _parseOptionsCached(library) {
|
201 | if (!library) return false;
|
202 | if (library.type !== this._type) return false;
|
203 | const cacheEntry = this._parseCache.get(library);
|
204 | if (cacheEntry !== undefined) return cacheEntry;
|
205 | const result = this.parseOptions(library);
|
206 | this._parseCache.set(library, result);
|
207 | return result;
|
208 | }
|
209 |
|
210 |
|
211 | |
212 |
|
213 |
|
214 |
|
215 |
|
216 | parseOptions(library) {
|
217 | const AbstractMethodError = require("../AbstractMethodError");
|
218 | throw new AbstractMethodError();
|
219 | }
|
220 |
|
221 | |
222 |
|
223 |
|
224 |
|
225 |
|
226 |
|
227 | finishEntryModule(module, entryName, libraryContext) {}
|
228 |
|
229 | |
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 | embedInRuntimeBailout(module, renderContext, libraryContext) {
|
236 | return undefined;
|
237 | }
|
238 |
|
239 | |
240 |
|
241 |
|
242 |
|
243 |
|
244 | strictRuntimeBailout(renderContext, libraryContext) {
|
245 | return undefined;
|
246 | }
|
247 |
|
248 | |
249 |
|
250 |
|
251 |
|
252 |
|
253 |
|
254 | runtimeRequirements(chunk, set, libraryContext) {
|
255 | if (this.render !== AbstractLibraryPlugin.prototype.render)
|
256 | set.add(RuntimeGlobals.returnExportsFromRuntime);
|
257 | }
|
258 |
|
259 | /**
|
260 | * @param {Source} source source
|
261 | * @param {RenderContext} renderContext render context
|
262 | * @param {LibraryContext<T>} libraryContext context
|
263 | * @returns {Source} source with library export
|
264 | */
|
265 | render(source, renderContext, libraryContext) {
|
266 | return source;
|
267 | }
|
268 |
|
269 | |
270 |
|
271 |
|
272 |
|
273 |
|
274 |
|
275 |
|
276 | renderStartup(source, module, renderContext, libraryContext) {
|
277 | return source;
|
278 | }
|
279 |
|
280 | |
281 |
|
282 |
|
283 |
|
284 |
|
285 |
|
286 |
|
287 | chunkHash(chunk, hash, chunkHashContext, libraryContext) {
|
288 | const options = this._parseOptionsCached(
|
289 | libraryContext.compilation.outputOptions.library
|
290 | );
|
291 | hash.update(this._pluginName);
|
292 | hash.update(JSON.stringify(options));
|
293 | }
|
294 | }
|
295 |
|
296 | AbstractLibraryPlugin.COMMON_LIBRARY_NAME_MESSAGE = COMMON_LIBRARY_NAME_MESSAGE;
|
297 | module.exports = AbstractLibraryPlugin;
|