1 | "use strict";
|
---|
2 |
|
---|
3 | Object.defineProperty(exports, "__esModule", {
|
---|
4 | value: true
|
---|
5 | });
|
---|
6 | exports.default = exports.pluginSymbol = exports.pluginName = void 0;
|
---|
7 |
|
---|
8 | var _schemaUtils = require("schema-utils");
|
---|
9 |
|
---|
10 | var _identifier = require("webpack/lib/util/identifier");
|
---|
11 |
|
---|
12 | var _pluginOptions = _interopRequireDefault(require("./plugin-options.json"));
|
---|
13 |
|
---|
14 | var _utils = require("./utils");
|
---|
15 |
|
---|
16 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
---|
17 |
|
---|
18 | /* eslint-disable class-methods-use-this */
|
---|
19 | const pluginName = "mini-css-extract-plugin";
|
---|
20 | exports.pluginName = pluginName;
|
---|
21 | const pluginSymbol = Symbol(pluginName);
|
---|
22 | exports.pluginSymbol = pluginSymbol;
|
---|
23 | const DEFAULT_FILENAME = "[name].css";
|
---|
24 | const TYPES = new Set([_utils.MODULE_TYPE]);
|
---|
25 | const CODE_GENERATION_RESULT = {
|
---|
26 | sources: new Map(),
|
---|
27 | runtimeRequirements: new Set()
|
---|
28 | };
|
---|
29 | /**
|
---|
30 | * @type WeakMap<webpack, CssModule>
|
---|
31 | */
|
---|
32 |
|
---|
33 | const cssModuleCache = new WeakMap();
|
---|
34 | /**
|
---|
35 | * @type WeakMap<webpack, CssDependency>
|
---|
36 | */
|
---|
37 |
|
---|
38 | const cssDependencyCache = new WeakMap();
|
---|
39 | const registered = new WeakSet();
|
---|
40 |
|
---|
41 | class MiniCssExtractPlugin {
|
---|
42 | static getCssModule(webpack) {
|
---|
43 | /**
|
---|
44 | * Prevent creation of multiple CssModule classes to allow other integrations to get the current CssModule.
|
---|
45 | */
|
---|
46 | if (cssModuleCache.has(webpack)) {
|
---|
47 | return cssModuleCache.get(webpack);
|
---|
48 | }
|
---|
49 |
|
---|
50 | class CssModule extends webpack.Module {
|
---|
51 | constructor({
|
---|
52 | context,
|
---|
53 | identifier,
|
---|
54 | identifierIndex,
|
---|
55 | content,
|
---|
56 | media,
|
---|
57 | sourceMap,
|
---|
58 | assets,
|
---|
59 | assetsInfo
|
---|
60 | }) {
|
---|
61 | super(_utils.MODULE_TYPE, context);
|
---|
62 | this.id = "";
|
---|
63 | this._context = context;
|
---|
64 | this._identifier = identifier;
|
---|
65 | this._identifierIndex = identifierIndex;
|
---|
66 | this.content = content;
|
---|
67 | this.media = media;
|
---|
68 | this.sourceMap = sourceMap;
|
---|
69 | this.assets = assets;
|
---|
70 | this.assetsInfo = assetsInfo;
|
---|
71 | this._needBuild = true;
|
---|
72 | } // no source() so webpack 4 doesn't do add stuff to the bundle
|
---|
73 |
|
---|
74 |
|
---|
75 | size() {
|
---|
76 | return this.content.length;
|
---|
77 | }
|
---|
78 |
|
---|
79 | identifier() {
|
---|
80 | return `css|${this._identifier}|${this._identifierIndex}`;
|
---|
81 | }
|
---|
82 |
|
---|
83 | readableIdentifier(requestShortener) {
|
---|
84 | return `css ${requestShortener.shorten(this._identifier)}${this._identifierIndex ? ` (${this._identifierIndex})` : ""}`;
|
---|
85 | } // eslint-disable-next-line class-methods-use-this
|
---|
86 |
|
---|
87 |
|
---|
88 | getSourceTypes() {
|
---|
89 | return TYPES;
|
---|
90 | } // eslint-disable-next-line class-methods-use-this
|
---|
91 |
|
---|
92 |
|
---|
93 | codeGeneration() {
|
---|
94 | return CODE_GENERATION_RESULT;
|
---|
95 | }
|
---|
96 |
|
---|
97 | nameForCondition() {
|
---|
98 | const resource = this._identifier.split("!").pop();
|
---|
99 |
|
---|
100 | const idx = resource.indexOf("?");
|
---|
101 |
|
---|
102 | if (idx >= 0) {
|
---|
103 | return resource.substring(0, idx);
|
---|
104 | }
|
---|
105 |
|
---|
106 | return resource;
|
---|
107 | }
|
---|
108 |
|
---|
109 | updateCacheModule(module) {
|
---|
110 | if (this.content !== module.content || this.media !== module.media || this.sourceMap !== module.sourceMap || this.assets !== module.assets || this.assetsInfo !== module.assetsInfo) {
|
---|
111 | this._needBuild = true;
|
---|
112 | this.content = module.content;
|
---|
113 | this.media = module.media;
|
---|
114 | this.sourceMap = module.sourceMap;
|
---|
115 | this.assets = module.assets;
|
---|
116 | this.assetsInfo = module.assetsInfo;
|
---|
117 | }
|
---|
118 | } // eslint-disable-next-line class-methods-use-this
|
---|
119 |
|
---|
120 |
|
---|
121 | needRebuild() {
|
---|
122 | return this._needBuild;
|
---|
123 | } // eslint-disable-next-line class-methods-use-this
|
---|
124 |
|
---|
125 |
|
---|
126 | needBuild(context, callback) {
|
---|
127 | callback(null, this._needBuild);
|
---|
128 | }
|
---|
129 |
|
---|
130 | build(options, compilation, resolver, fileSystem, callback) {
|
---|
131 | this.buildInfo = {
|
---|
132 | assets: this.assets,
|
---|
133 | assetsInfo: this.assetsInfo,
|
---|
134 | cacheable: true,
|
---|
135 | hash: this._computeHash(compilation.outputOptions.hashFunction)
|
---|
136 | };
|
---|
137 | this.buildMeta = {};
|
---|
138 | this._needBuild = false;
|
---|
139 | callback();
|
---|
140 | }
|
---|
141 |
|
---|
142 | _computeHash(hashFunction) {
|
---|
143 | const hash = webpack.util.createHash(hashFunction);
|
---|
144 | hash.update(this.content);
|
---|
145 | hash.update(this.media || "");
|
---|
146 | hash.update(this.sourceMap || "");
|
---|
147 | return hash.digest("hex");
|
---|
148 | }
|
---|
149 |
|
---|
150 | updateHash(hash, context) {
|
---|
151 | super.updateHash(hash, context);
|
---|
152 | hash.update(this.buildInfo.hash);
|
---|
153 | }
|
---|
154 |
|
---|
155 | serialize(context) {
|
---|
156 | const {
|
---|
157 | write
|
---|
158 | } = context;
|
---|
159 | write(this._context);
|
---|
160 | write(this._identifier);
|
---|
161 | write(this._identifierIndex);
|
---|
162 | write(this.content);
|
---|
163 | write(this.media);
|
---|
164 | write(this.sourceMap);
|
---|
165 | write(this.assets);
|
---|
166 | write(this.assetsInfo);
|
---|
167 | write(this._needBuild);
|
---|
168 | super.serialize(context);
|
---|
169 | }
|
---|
170 |
|
---|
171 | deserialize(context) {
|
---|
172 | this._needBuild = context.read();
|
---|
173 | super.deserialize(context);
|
---|
174 | }
|
---|
175 |
|
---|
176 | }
|
---|
177 |
|
---|
178 | cssModuleCache.set(webpack, CssModule);
|
---|
179 | webpack.util.serialization.register(CssModule, "mini-css-extract-plugin/dist/CssModule", null, {
|
---|
180 | serialize(instance, context) {
|
---|
181 | instance.serialize(context);
|
---|
182 | },
|
---|
183 |
|
---|
184 | deserialize(context) {
|
---|
185 | const {
|
---|
186 | read
|
---|
187 | } = context;
|
---|
188 | const contextModule = read();
|
---|
189 | const identifier = read();
|
---|
190 | const identifierIndex = read();
|
---|
191 | const content = read();
|
---|
192 | const media = read();
|
---|
193 | const sourceMap = read();
|
---|
194 | const assets = read();
|
---|
195 | const assetsInfo = read();
|
---|
196 | const dep = new CssModule({
|
---|
197 | context: contextModule,
|
---|
198 | identifier,
|
---|
199 | identifierIndex,
|
---|
200 | content,
|
---|
201 | media,
|
---|
202 | sourceMap,
|
---|
203 | assets,
|
---|
204 | assetsInfo
|
---|
205 | });
|
---|
206 | dep.deserialize(context);
|
---|
207 | return dep;
|
---|
208 | }
|
---|
209 |
|
---|
210 | });
|
---|
211 | return CssModule;
|
---|
212 | }
|
---|
213 |
|
---|
214 | static getCssDependency(webpack) {
|
---|
215 | /**
|
---|
216 | * Prevent creation of multiple CssDependency classes to allow other integrations to get the current CssDependency.
|
---|
217 | */
|
---|
218 | if (cssDependencyCache.has(webpack)) {
|
---|
219 | return cssDependencyCache.get(webpack);
|
---|
220 | } // eslint-disable-next-line no-shadow
|
---|
221 |
|
---|
222 |
|
---|
223 | class CssDependency extends webpack.Dependency {
|
---|
224 | constructor({
|
---|
225 | identifier,
|
---|
226 | content,
|
---|
227 | media,
|
---|
228 | sourceMap
|
---|
229 | }, context, identifierIndex) {
|
---|
230 | super();
|
---|
231 | this.identifier = identifier;
|
---|
232 | this.identifierIndex = identifierIndex;
|
---|
233 | this.content = content;
|
---|
234 | this.media = media;
|
---|
235 | this.sourceMap = sourceMap;
|
---|
236 | this.context = context; // eslint-disable-next-line no-undefined
|
---|
237 |
|
---|
238 | this.assets = undefined; // eslint-disable-next-line no-undefined
|
---|
239 |
|
---|
240 | this.assetsInfo = undefined;
|
---|
241 | }
|
---|
242 |
|
---|
243 | getResourceIdentifier() {
|
---|
244 | return `css-module-${this.identifier}-${this.identifierIndex}`;
|
---|
245 | } // eslint-disable-next-line class-methods-use-this
|
---|
246 |
|
---|
247 |
|
---|
248 | getModuleEvaluationSideEffectsState() {
|
---|
249 | return webpack.ModuleGraphConnection.TRANSITIVE_ONLY;
|
---|
250 | }
|
---|
251 |
|
---|
252 | serialize(context) {
|
---|
253 | const {
|
---|
254 | write
|
---|
255 | } = context;
|
---|
256 | write(this.identifier);
|
---|
257 | write(this.content);
|
---|
258 | write(this.media);
|
---|
259 | write(this.sourceMap);
|
---|
260 | write(this.context);
|
---|
261 | write(this.identifierIndex);
|
---|
262 | write(this.assets);
|
---|
263 | write(this.assetsInfo);
|
---|
264 | super.serialize(context);
|
---|
265 | }
|
---|
266 |
|
---|
267 | deserialize(context) {
|
---|
268 | super.deserialize(context);
|
---|
269 | }
|
---|
270 |
|
---|
271 | }
|
---|
272 |
|
---|
273 | cssDependencyCache.set(webpack, CssDependency);
|
---|
274 | webpack.util.serialization.register(CssDependency, "mini-css-extract-plugin/dist/CssDependency", null, {
|
---|
275 | serialize(instance, context) {
|
---|
276 | instance.serialize(context);
|
---|
277 | },
|
---|
278 |
|
---|
279 | deserialize(context) {
|
---|
280 | const {
|
---|
281 | read
|
---|
282 | } = context;
|
---|
283 | const dep = new CssDependency({
|
---|
284 | identifier: read(),
|
---|
285 | content: read(),
|
---|
286 | media: read(),
|
---|
287 | sourceMap: read()
|
---|
288 | }, read(), read());
|
---|
289 | const assets = read();
|
---|
290 | const assetsInfo = read();
|
---|
291 | dep.assets = assets;
|
---|
292 | dep.assetsInfo = assetsInfo;
|
---|
293 | dep.deserialize(context);
|
---|
294 | return dep;
|
---|
295 | }
|
---|
296 |
|
---|
297 | });
|
---|
298 | return CssDependency;
|
---|
299 | }
|
---|
300 |
|
---|
301 | constructor(options = {}) {
|
---|
302 | (0, _schemaUtils.validate)(_pluginOptions.default, options, {
|
---|
303 | baseDataPath: "options"
|
---|
304 | });
|
---|
305 | this._sortedModulesCache = new WeakMap();
|
---|
306 | this.options = Object.assign({
|
---|
307 | filename: DEFAULT_FILENAME,
|
---|
308 | ignoreOrder: false,
|
---|
309 | experimentalUseImportModule: false
|
---|
310 | }, options);
|
---|
311 | this.runtimeOptions = {
|
---|
312 | insert: options.insert,
|
---|
313 | linkType: // Todo in next major release set default to "false"
|
---|
314 | options.linkType === true || typeof options.linkType === "undefined" ? "text/css" : options.linkType,
|
---|
315 | attributes: options.attributes
|
---|
316 | };
|
---|
317 |
|
---|
318 | if (!this.options.chunkFilename) {
|
---|
319 | const {
|
---|
320 | filename
|
---|
321 | } = this.options;
|
---|
322 |
|
---|
323 | if (typeof filename !== "function") {
|
---|
324 | const hasName = filename.includes("[name]");
|
---|
325 | const hasId = filename.includes("[id]");
|
---|
326 | const hasChunkHash = filename.includes("[chunkhash]");
|
---|
327 | const hasContentHash = filename.includes("[contenthash]"); // Anything changing depending on chunk is fine
|
---|
328 |
|
---|
329 | if (hasChunkHash || hasContentHash || hasName || hasId) {
|
---|
330 | this.options.chunkFilename = filename;
|
---|
331 | } else {
|
---|
332 | // Otherwise prefix "[id]." in front of the basename to make it changing
|
---|
333 | this.options.chunkFilename = filename.replace(/(^|\/)([^/]*(?:\?|$))/, "$1[id].$2");
|
---|
334 | }
|
---|
335 | } else {
|
---|
336 | this.options.chunkFilename = "[id].css";
|
---|
337 | }
|
---|
338 | }
|
---|
339 | }
|
---|
340 | /** @param {import("webpack").Compiler} compiler */
|
---|
341 |
|
---|
342 |
|
---|
343 | apply(compiler) {
|
---|
344 | const {
|
---|
345 | webpack
|
---|
346 | } = compiler;
|
---|
347 |
|
---|
348 | if (this.options.experimentalUseImportModule) {
|
---|
349 | if (!compiler.options.experiments) {
|
---|
350 | throw new Error("experimentalUseImportModule is only support for webpack >= 5.33.2");
|
---|
351 | }
|
---|
352 |
|
---|
353 | if (typeof compiler.options.experiments.executeModule === "undefined") {
|
---|
354 | // eslint-disable-next-line no-param-reassign
|
---|
355 | compiler.options.experiments.executeModule = true;
|
---|
356 | }
|
---|
357 | } // TODO bug in webpack, remove it after it will be fixed
|
---|
358 | // webpack tries to `require` loader firstly when serializer doesn't found
|
---|
359 |
|
---|
360 |
|
---|
361 | if (!registered.has(webpack)) {
|
---|
362 | registered.add(webpack);
|
---|
363 | webpack.util.serialization.registerLoader(/^mini-css-extract-plugin\//, _utils.trueFn);
|
---|
364 | }
|
---|
365 |
|
---|
366 | const {
|
---|
367 | splitChunks
|
---|
368 | } = compiler.options.optimization;
|
---|
369 |
|
---|
370 | if (splitChunks) {
|
---|
371 | if (splitChunks.defaultSizeTypes.includes("...")) {
|
---|
372 | splitChunks.defaultSizeTypes.push(_utils.MODULE_TYPE);
|
---|
373 | }
|
---|
374 | }
|
---|
375 |
|
---|
376 | const CssModule = MiniCssExtractPlugin.getCssModule(webpack);
|
---|
377 | const CssDependency = MiniCssExtractPlugin.getCssDependency(webpack);
|
---|
378 | const {
|
---|
379 | NormalModule
|
---|
380 | } = compiler.webpack;
|
---|
381 | compiler.hooks.compilation.tap(pluginName, compilation => {
|
---|
382 | const {
|
---|
383 | loader: normalModuleHook
|
---|
384 | } = NormalModule.getCompilationHooks(compilation);
|
---|
385 | normalModuleHook.tap(pluginName, loaderContext => {
|
---|
386 | // eslint-disable-next-line no-param-reassign
|
---|
387 | loaderContext[pluginSymbol] = {
|
---|
388 | experimentalUseImportModule: this.options.experimentalUseImportModule
|
---|
389 | };
|
---|
390 | });
|
---|
391 | });
|
---|
392 | compiler.hooks.thisCompilation.tap(pluginName, compilation => {
|
---|
393 | class CssModuleFactory {
|
---|
394 | // eslint-disable-next-line class-methods-use-this
|
---|
395 | create({
|
---|
396 | dependencies: [dependency]
|
---|
397 | }, callback) {
|
---|
398 | callback(null, new CssModule(dependency));
|
---|
399 | }
|
---|
400 |
|
---|
401 | }
|
---|
402 |
|
---|
403 | compilation.dependencyFactories.set(CssDependency, new CssModuleFactory());
|
---|
404 |
|
---|
405 | class CssDependencyTemplate {
|
---|
406 | // eslint-disable-next-line class-methods-use-this
|
---|
407 | apply() {}
|
---|
408 |
|
---|
409 | }
|
---|
410 |
|
---|
411 | compilation.dependencyTemplates.set(CssDependency, new CssDependencyTemplate());
|
---|
412 | compilation.hooks.renderManifest.tap(pluginName, (result, {
|
---|
413 | chunk
|
---|
414 | }) => {
|
---|
415 | const {
|
---|
416 | chunkGraph
|
---|
417 | } = compilation;
|
---|
418 | const {
|
---|
419 | HotUpdateChunk
|
---|
420 | } = webpack; // We don't need hot update chunks for css
|
---|
421 | // We will use the real asset instead to update
|
---|
422 |
|
---|
423 | if (chunk instanceof HotUpdateChunk) {
|
---|
424 | return;
|
---|
425 | }
|
---|
426 |
|
---|
427 | const renderedModules = Array.from(this.getChunkModules(chunk, chunkGraph)).filter(module => module.type === _utils.MODULE_TYPE);
|
---|
428 | const filenameTemplate = chunk.canBeInitial() ? this.options.filename : this.options.chunkFilename;
|
---|
429 |
|
---|
430 | if (renderedModules.length > 0) {
|
---|
431 | result.push({
|
---|
432 | render: () => this.renderContentAsset(compiler, compilation, chunk, renderedModules, compilation.runtimeTemplate.requestShortener, filenameTemplate, {
|
---|
433 | contentHashType: _utils.MODULE_TYPE,
|
---|
434 | chunk
|
---|
435 | }),
|
---|
436 | filenameTemplate,
|
---|
437 | pathOptions: {
|
---|
438 | chunk,
|
---|
439 | contentHashType: _utils.MODULE_TYPE
|
---|
440 | },
|
---|
441 | identifier: `${pluginName}.${chunk.id}`,
|
---|
442 | hash: chunk.contentHash[_utils.MODULE_TYPE]
|
---|
443 | });
|
---|
444 | }
|
---|
445 | });
|
---|
446 | compilation.hooks.contentHash.tap(pluginName, chunk => {
|
---|
447 | const {
|
---|
448 | outputOptions,
|
---|
449 | chunkGraph
|
---|
450 | } = compilation;
|
---|
451 | const modules = this.sortModules(compilation, chunk, chunkGraph.getChunkModulesIterableBySourceType(chunk, _utils.MODULE_TYPE), compilation.runtimeTemplate.requestShortener);
|
---|
452 |
|
---|
453 | if (modules) {
|
---|
454 | const {
|
---|
455 | hashFunction,
|
---|
456 | hashDigest,
|
---|
457 | hashDigestLength
|
---|
458 | } = outputOptions;
|
---|
459 | const {
|
---|
460 | createHash
|
---|
461 | } = compiler.webpack.util;
|
---|
462 | const hash = createHash(hashFunction);
|
---|
463 |
|
---|
464 | for (const m of modules) {
|
---|
465 | hash.update(chunkGraph.getModuleHash(m, chunk.runtime));
|
---|
466 | } // eslint-disable-next-line no-param-reassign
|
---|
467 |
|
---|
468 |
|
---|
469 | chunk.contentHash[_utils.MODULE_TYPE] = hash.digest(hashDigest).substring(0, hashDigestLength);
|
---|
470 | }
|
---|
471 | });
|
---|
472 | const {
|
---|
473 | Template
|
---|
474 | } = webpack;
|
---|
475 | const {
|
---|
476 | RuntimeGlobals,
|
---|
477 | runtime
|
---|
478 | } = webpack; // eslint-disable-next-line no-shadow
|
---|
479 |
|
---|
480 | const getCssChunkObject = (mainChunk, compilation) => {
|
---|
481 | const obj = {};
|
---|
482 | const {
|
---|
483 | chunkGraph
|
---|
484 | } = compilation;
|
---|
485 |
|
---|
486 | for (const chunk of mainChunk.getAllAsyncChunks()) {
|
---|
487 | const modules = chunkGraph.getOrderedChunkModulesIterable(chunk, _utils.compareModulesByIdentifier);
|
---|
488 |
|
---|
489 | for (const module of modules) {
|
---|
490 | if (module.type === _utils.MODULE_TYPE) {
|
---|
491 | obj[chunk.id] = 1;
|
---|
492 | break;
|
---|
493 | }
|
---|
494 | }
|
---|
495 | }
|
---|
496 |
|
---|
497 | return obj;
|
---|
498 | };
|
---|
499 |
|
---|
500 | const {
|
---|
501 | RuntimeModule
|
---|
502 | } = webpack;
|
---|
503 |
|
---|
504 | class CssLoadingRuntimeModule extends RuntimeModule {
|
---|
505 | constructor(runtimeRequirements, runtimeOptions) {
|
---|
506 | super("css loading", 10);
|
---|
507 | this.runtimeRequirements = runtimeRequirements;
|
---|
508 | this.runtimeOptions = runtimeOptions;
|
---|
509 | }
|
---|
510 |
|
---|
511 | generate() {
|
---|
512 | const {
|
---|
513 | chunk,
|
---|
514 | runtimeRequirements
|
---|
515 | } = this;
|
---|
516 | const {
|
---|
517 | runtimeTemplate,
|
---|
518 | outputOptions: {
|
---|
519 | crossOriginLoading
|
---|
520 | }
|
---|
521 | } = this.compilation;
|
---|
522 | const chunkMap = getCssChunkObject(chunk, this.compilation);
|
---|
523 | const withLoading = runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) && Object.keys(chunkMap).length > 0;
|
---|
524 | const withHmr = runtimeRequirements.has(RuntimeGlobals.hmrDownloadUpdateHandlers);
|
---|
525 |
|
---|
526 | if (!withLoading && !withHmr) {
|
---|
527 | return null;
|
---|
528 | }
|
---|
529 |
|
---|
530 | return Template.asString([`var createStylesheet = ${runtimeTemplate.basicFunction("chunkId, fullhref, resolve, reject", ['var linkTag = document.createElement("link");', this.runtimeOptions.attributes ? Template.asString(Object.entries(this.runtimeOptions.attributes).map(entry => {
|
---|
531 | const [key, value] = entry;
|
---|
532 | return `linkTag.setAttribute(${JSON.stringify(key)}, ${JSON.stringify(value)});`;
|
---|
533 | })) : "", 'linkTag.rel = "stylesheet";', this.runtimeOptions.linkType ? `linkTag.type = ${JSON.stringify(this.runtimeOptions.linkType)};` : "", `var onLinkComplete = ${runtimeTemplate.basicFunction("event", ["// avoid mem leaks.", "linkTag.onerror = linkTag.onload = null;", "if (event.type === 'load') {", Template.indent(["resolve();"]), "} else {", Template.indent(["var errorType = event && (event.type === 'load' ? 'missing' : event.type);", "var realHref = event && event.target && event.target.href || fullhref;", 'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + realHref + ")");', 'err.code = "CSS_CHUNK_LOAD_FAILED";', "err.type = errorType;", "err.request = realHref;", "linkTag.parentNode.removeChild(linkTag)", "reject(err);"]), "}"])}`, "linkTag.onerror = linkTag.onload = onLinkComplete;", "linkTag.href = fullhref;", crossOriginLoading ? Template.asString([`if (linkTag.href.indexOf(window.location.origin + '/') !== 0) {`, Template.indent(`linkTag.crossOrigin = ${JSON.stringify(crossOriginLoading)};`), "}"]) : "", typeof this.runtimeOptions.insert !== "undefined" ? typeof this.runtimeOptions.insert === "function" ? `(${this.runtimeOptions.insert.toString()})(linkTag)` : Template.asString([`var target = document.querySelector("${this.runtimeOptions.insert}");`, `target.parentNode.insertBefore(linkTag, target.nextSibling);`]) : Template.asString(["document.head.appendChild(linkTag);"]), "return linkTag;"])};`, `var findStylesheet = ${runtimeTemplate.basicFunction("href, fullhref", ['var existingLinkTags = document.getElementsByTagName("link");', "for(var i = 0; i < existingLinkTags.length; i++) {", Template.indent(["var tag = existingLinkTags[i];", 'var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");', 'if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return tag;']), "}", 'var existingStyleTags = document.getElementsByTagName("style");', "for(var i = 0; i < existingStyleTags.length; i++) {", Template.indent(["var tag = existingStyleTags[i];", 'var dataHref = tag.getAttribute("data-href");', "if(dataHref === href || dataHref === fullhref) return tag;"]), "}"])};`, `var loadStylesheet = ${runtimeTemplate.basicFunction("chunkId", `return new Promise(${runtimeTemplate.basicFunction("resolve, reject", [`var href = ${RuntimeGlobals.require}.miniCssF(chunkId);`, `var fullhref = ${RuntimeGlobals.publicPath} + href;`, "if(findStylesheet(href, fullhref)) return resolve();", "createStylesheet(chunkId, fullhref, resolve, reject);"])});`)}`, withLoading ? Template.asString(["// object to store loaded CSS chunks", "var installedCssChunks = {", Template.indent(chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(",\n")), "};", "", `${RuntimeGlobals.ensureChunkHandlers}.miniCss = ${runtimeTemplate.basicFunction("chunkId, promises", [`var cssChunks = ${JSON.stringify(chunkMap)};`, "if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);", "else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {", Template.indent([`promises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(${runtimeTemplate.basicFunction("", "installedCssChunks[chunkId] = 0;")}, ${runtimeTemplate.basicFunction("e", ["delete installedCssChunks[chunkId];", "throw e;"])}));`]), "}"])};`]) : "// no chunk loading", "", withHmr ? Template.asString(["var oldTags = [];", "var newTags = [];", `var applyHandler = ${runtimeTemplate.basicFunction("options", [`return { dispose: ${runtimeTemplate.basicFunction("", ["for(var i = 0; i < oldTags.length; i++) {", Template.indent(["var oldTag = oldTags[i];", "if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);"]), "}", "oldTags.length = 0;"])}, apply: ${runtimeTemplate.basicFunction("", ['for(var i = 0; i < newTags.length; i++) newTags[i].rel = "stylesheet";', "newTags.length = 0;"])} };`])}`, `${RuntimeGlobals.hmrDownloadUpdateHandlers}.miniCss = ${runtimeTemplate.basicFunction("chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList", ["applyHandlers.push(applyHandler);", `chunkIds.forEach(${runtimeTemplate.basicFunction("chunkId", [`var href = ${RuntimeGlobals.require}.miniCssF(chunkId);`, `var fullhref = ${RuntimeGlobals.publicPath} + href;`, "var oldTag = findStylesheet(href, fullhref);", "if(!oldTag) return;", `promises.push(new Promise(${runtimeTemplate.basicFunction("resolve, reject", [`var tag = createStylesheet(chunkId, fullhref, ${runtimeTemplate.basicFunction("", ['tag.as = "style";', 'tag.rel = "preload";', "resolve();"])}, reject);`, "oldTags.push(oldTag);", "newTags.push(tag);"])}));`])});`])}`]) : "// no hmr"]);
|
---|
534 | }
|
---|
535 |
|
---|
536 | }
|
---|
537 |
|
---|
538 | const enabledChunks = new WeakSet();
|
---|
539 |
|
---|
540 | const handler = (chunk, set) => {
|
---|
541 | if (enabledChunks.has(chunk)) {
|
---|
542 | return;
|
---|
543 | }
|
---|
544 |
|
---|
545 | enabledChunks.add(chunk);
|
---|
546 |
|
---|
547 | if (typeof this.options.chunkFilename === "string" && /\[(full)?hash(:\d+)?\]/.test(this.options.chunkFilename)) {
|
---|
548 | set.add(RuntimeGlobals.getFullHash);
|
---|
549 | }
|
---|
550 |
|
---|
551 | set.add(RuntimeGlobals.publicPath);
|
---|
552 | compilation.addRuntimeModule(chunk, new runtime.GetChunkFilenameRuntimeModule(_utils.MODULE_TYPE, "mini-css", `${RuntimeGlobals.require}.miniCssF`, referencedChunk => {
|
---|
553 | if (!referencedChunk.contentHash[_utils.MODULE_TYPE]) {
|
---|
554 | return false;
|
---|
555 | }
|
---|
556 |
|
---|
557 | return referencedChunk.canBeInitial() ? this.options.filename : this.options.chunkFilename;
|
---|
558 | }, true));
|
---|
559 | compilation.addRuntimeModule(chunk, new CssLoadingRuntimeModule(set, this.runtimeOptions));
|
---|
560 | };
|
---|
561 |
|
---|
562 | compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.ensureChunkHandlers).tap(pluginName, handler);
|
---|
563 | compilation.hooks.runtimeRequirementInTree.for(RuntimeGlobals.hmrDownloadUpdateHandlers).tap(pluginName, handler);
|
---|
564 | });
|
---|
565 | }
|
---|
566 |
|
---|
567 | getChunkModules(chunk, chunkGraph) {
|
---|
568 | return typeof chunkGraph !== "undefined" ? chunkGraph.getOrderedChunkModulesIterable(chunk, _utils.compareModulesByIdentifier) : chunk.modulesIterable;
|
---|
569 | }
|
---|
570 |
|
---|
571 | sortModules(compilation, chunk, modules, requestShortener) {
|
---|
572 | let usedModules = this._sortedModulesCache.get(chunk);
|
---|
573 |
|
---|
574 | if (usedModules || !modules) {
|
---|
575 | return usedModules;
|
---|
576 | }
|
---|
577 |
|
---|
578 | const modulesList = [...modules]; // Store dependencies for modules
|
---|
579 |
|
---|
580 | const moduleDependencies = new Map(modulesList.map(m => [m, new Set()]));
|
---|
581 | const moduleDependenciesReasons = new Map(modulesList.map(m => [m, new Map()])); // Get ordered list of modules per chunk group
|
---|
582 | // This loop also gathers dependencies from the ordered lists
|
---|
583 | // Lists are in reverse order to allow to use Array.pop()
|
---|
584 |
|
---|
585 | const modulesByChunkGroup = Array.from(chunk.groupsIterable, chunkGroup => {
|
---|
586 | const sortedModules = modulesList.map(module => {
|
---|
587 | return {
|
---|
588 | module,
|
---|
589 | index: chunkGroup.getModulePostOrderIndex(module)
|
---|
590 | };
|
---|
591 | }) // eslint-disable-next-line no-undefined
|
---|
592 | .filter(item => item.index !== undefined).sort((a, b) => b.index - a.index).map(item => item.module);
|
---|
593 |
|
---|
594 | for (let i = 0; i < sortedModules.length; i++) {
|
---|
595 | const set = moduleDependencies.get(sortedModules[i]);
|
---|
596 | const reasons = moduleDependenciesReasons.get(sortedModules[i]);
|
---|
597 |
|
---|
598 | for (let j = i + 1; j < sortedModules.length; j++) {
|
---|
599 | const module = sortedModules[j];
|
---|
600 | set.add(module);
|
---|
601 | const reason = reasons.get(module) || new Set();
|
---|
602 | reason.add(chunkGroup);
|
---|
603 | reasons.set(module, reason);
|
---|
604 | }
|
---|
605 | }
|
---|
606 |
|
---|
607 | return sortedModules;
|
---|
608 | }); // set with already included modules in correct order
|
---|
609 |
|
---|
610 | usedModules = new Set();
|
---|
611 |
|
---|
612 | const unusedModulesFilter = m => !usedModules.has(m);
|
---|
613 |
|
---|
614 | while (usedModules.size < modulesList.length) {
|
---|
615 | let success = false;
|
---|
616 | let bestMatch;
|
---|
617 | let bestMatchDeps; // get first module where dependencies are fulfilled
|
---|
618 |
|
---|
619 | for (const list of modulesByChunkGroup) {
|
---|
620 | // skip and remove already added modules
|
---|
621 | while (list.length > 0 && usedModules.has(list[list.length - 1])) {
|
---|
622 | list.pop();
|
---|
623 | } // skip empty lists
|
---|
624 |
|
---|
625 |
|
---|
626 | if (list.length !== 0) {
|
---|
627 | const module = list[list.length - 1];
|
---|
628 | const deps = moduleDependencies.get(module); // determine dependencies that are not yet included
|
---|
629 |
|
---|
630 | const failedDeps = Array.from(deps).filter(unusedModulesFilter); // store best match for fallback behavior
|
---|
631 |
|
---|
632 | if (!bestMatchDeps || bestMatchDeps.length > failedDeps.length) {
|
---|
633 | bestMatch = list;
|
---|
634 | bestMatchDeps = failedDeps;
|
---|
635 | }
|
---|
636 |
|
---|
637 | if (failedDeps.length === 0) {
|
---|
638 | // use this module and remove it from list
|
---|
639 | usedModules.add(list.pop());
|
---|
640 | success = true;
|
---|
641 | break;
|
---|
642 | }
|
---|
643 | }
|
---|
644 | }
|
---|
645 |
|
---|
646 | if (!success) {
|
---|
647 | // no module found => there is a conflict
|
---|
648 | // use list with fewest failed deps
|
---|
649 | // and emit a warning
|
---|
650 | const fallbackModule = bestMatch.pop();
|
---|
651 |
|
---|
652 | if (!this.options.ignoreOrder) {
|
---|
653 | const reasons = moduleDependenciesReasons.get(fallbackModule);
|
---|
654 | compilation.warnings.push(new Error([`chunk ${chunk.name || chunk.id} [${pluginName}]`, "Conflicting order. Following module has been added:", ` * ${fallbackModule.readableIdentifier(requestShortener)}`, "despite it was not able to fulfill desired ordering with these modules:", ...bestMatchDeps.map(m => {
|
---|
655 | const goodReasonsMap = moduleDependenciesReasons.get(m);
|
---|
656 | const goodReasons = goodReasonsMap && goodReasonsMap.get(fallbackModule);
|
---|
657 | const failedChunkGroups = Array.from(reasons.get(m), cg => cg.name).join(", ");
|
---|
658 | const goodChunkGroups = goodReasons && Array.from(goodReasons, cg => cg.name).join(", ");
|
---|
659 | return [` * ${m.readableIdentifier(requestShortener)}`, ` - couldn't fulfill desired order of chunk group(s) ${failedChunkGroups}`, goodChunkGroups && ` - while fulfilling desired order of chunk group(s) ${goodChunkGroups}`].filter(Boolean).join("\n");
|
---|
660 | })].join("\n")));
|
---|
661 | }
|
---|
662 |
|
---|
663 | usedModules.add(fallbackModule);
|
---|
664 | }
|
---|
665 | }
|
---|
666 |
|
---|
667 | this._sortedModulesCache.set(chunk, usedModules);
|
---|
668 |
|
---|
669 | return usedModules;
|
---|
670 | }
|
---|
671 |
|
---|
672 | renderContentAsset(compiler, compilation, chunk, modules, requestShortener, filenameTemplate, pathData) {
|
---|
673 | const usedModules = this.sortModules(compilation, chunk, modules, requestShortener);
|
---|
674 | const {
|
---|
675 | ConcatSource,
|
---|
676 | SourceMapSource,
|
---|
677 | RawSource
|
---|
678 | } = compiler.webpack.sources;
|
---|
679 | const source = new ConcatSource();
|
---|
680 | const externalsSource = new ConcatSource();
|
---|
681 |
|
---|
682 | for (const module of usedModules) {
|
---|
683 | let content = module.content.toString();
|
---|
684 | const readableIdentifier = module.readableIdentifier(requestShortener);
|
---|
685 | const startsWithAtRuleImport = /^@import url/.test(content);
|
---|
686 | let header;
|
---|
687 |
|
---|
688 | if (compilation.outputOptions.pathinfo) {
|
---|
689 | // From https://github.com/webpack/webpack/blob/29eff8a74ecc2f87517b627dee451c2af9ed3f3f/lib/ModuleInfoHeaderPlugin.js#L191-L194
|
---|
690 | const reqStr = readableIdentifier.replace(/\*\//g, "*_/");
|
---|
691 | const reqStrStar = "*".repeat(reqStr.length);
|
---|
692 | const headerStr = `/*!****${reqStrStar}****!*\\\n !*** ${reqStr} ***!\n \\****${reqStrStar}****/\n`;
|
---|
693 | header = new RawSource(headerStr);
|
---|
694 | }
|
---|
695 |
|
---|
696 | if (startsWithAtRuleImport) {
|
---|
697 | if (typeof header !== "undefined") {
|
---|
698 | externalsSource.add(header);
|
---|
699 | } // HACK for IE
|
---|
700 | // http://stackoverflow.com/a/14676665/1458162
|
---|
701 |
|
---|
702 |
|
---|
703 | if (module.media) {
|
---|
704 | // insert media into the @import
|
---|
705 | // this is rar
|
---|
706 | // TODO improve this and parse the CSS to support multiple medias
|
---|
707 | content = content.replace(/;|\s*$/, module.media);
|
---|
708 | }
|
---|
709 |
|
---|
710 | externalsSource.add(content);
|
---|
711 | externalsSource.add("\n");
|
---|
712 | } else {
|
---|
713 | if (typeof header !== "undefined") {
|
---|
714 | source.add(header);
|
---|
715 | }
|
---|
716 |
|
---|
717 | if (module.media) {
|
---|
718 | source.add(`@media ${module.media} {\n`);
|
---|
719 | }
|
---|
720 |
|
---|
721 | const {
|
---|
722 | path: filename
|
---|
723 | } = compilation.getPathWithInfo(filenameTemplate, pathData);
|
---|
724 | const undoPath = (0, _identifier.getUndoPath)(filename, compiler.outputPath, false);
|
---|
725 | content = content.replace(new RegExp(_utils.AUTO_PUBLIC_PATH, "g"), undoPath);
|
---|
726 |
|
---|
727 | if (module.sourceMap) {
|
---|
728 | source.add(new SourceMapSource(content, readableIdentifier, module.sourceMap.toString()));
|
---|
729 | } else {
|
---|
730 | source.add(new RawSource(content, readableIdentifier));
|
---|
731 | }
|
---|
732 |
|
---|
733 | source.add("\n");
|
---|
734 |
|
---|
735 | if (module.media) {
|
---|
736 | source.add("}\n");
|
---|
737 | }
|
---|
738 | }
|
---|
739 | }
|
---|
740 |
|
---|
741 | return new ConcatSource(externalsSource, source);
|
---|
742 | }
|
---|
743 |
|
---|
744 | }
|
---|
745 |
|
---|
746 | MiniCssExtractPlugin.loader = require.resolve("./loader");
|
---|
747 | var _default = MiniCssExtractPlugin;
|
---|
748 | exports.default = _default; |
---|