Skip to content

Commit 4982afb

Browse files
committed
feat: ability to disable extract modules, remove duplicated dependencies
1 parent e2177fd commit 4982afb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+886
-203
lines changed

src/index.js

+51-49
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22

33
import webpack from 'webpack';
44
import sources from 'webpack-sources';
5-
import NullFactory from 'webpack/lib/NullFactory';
6-
7-
import ReplaceDependency from './lib/ReplaceDependency';
85

96
const { ConcatSource, SourceMapSource, OriginalSource } = sources;
107
const {
@@ -22,6 +19,16 @@ const REGEXP_NAME = /\[name\]/i;
2219
const REGEXP_PLACEHOLDERS = /\[(name|id|chunkhash)\]/g;
2320
const DEFAULT_FILENAME = '[name].css';
2421

22+
function isInitialOrHasNoParents(chunk) {
23+
let parentCount = 0;
24+
25+
for (const chunkGroup of chunk.groupsIterable) {
26+
parentCount += chunkGroup.getNumberOfParents();
27+
}
28+
29+
return chunk.isOnlyInitial() || parentCount === 0;
30+
}
31+
2532
class CssDependency extends webpack.Dependency {
2633
constructor(
2734
{ identifier, content, media, sourceMap },
@@ -157,12 +164,6 @@ class MiniCssExtractPlugin {
157164
moduleToBeRebuild,
158165
};
159166

160-
compilation.dependencyFactories.set(ReplaceDependency, new NullFactory());
161-
compilation.dependencyTemplates.set(
162-
ReplaceDependency,
163-
new ReplaceDependency.Template()
164-
);
165-
166167
compilation.hooks.normalModuleLoader.tap(pluginName, (lc, m) => {
167168
const loaderContext = lc;
168169
const module = m;
@@ -185,6 +186,10 @@ class MiniCssExtractPlugin {
185186
identifierCountMap.set(line.identifier, count + 1);
186187
}
187188
};
189+
190+
loaderContext[`${MODULE_TYPE}/disableExtract`] = () => {
191+
return !!module[`${MODULE_TYPE}/disableExtract`];
192+
};
188193
});
189194

190195
compilation.dependencyFactories.set(
@@ -202,8 +207,7 @@ class MiniCssExtractPlugin {
202207
(result, { chunk }) => {
203208
const renderedModules = Array.from(chunk.modulesIterable).filter(
204209
(module) =>
205-
module.type === MODULE_TYPE &&
206-
!this.shouldDisableExtract({ module, isAsync: false })
210+
module.type === MODULE_TYPE && !moduleToBeRebuild.has(module)
207211
);
208212

209213
if (renderedModules.length > 0) {
@@ -452,46 +456,53 @@ class MiniCssExtractPlugin {
452456
}
453457
);
454458

455-
const len = `// extracted by ${pluginName}`.length;
456-
mainTemplate.hooks.beforeStartup.tap(pluginName, (source) => {
457-
for (const currentModuleToBeRebuild of moduleToBeRebuild) {
458-
const issuerDeps = currentModuleToBeRebuild.issuer.dependencies;
459-
let firstIndex = -1;
460-
const content = [];
461-
462-
for (let i = issuerDeps.length - 1; i >= 0; i--) {
463-
const { module } = issuerDeps[i];
464-
if (moduleToBeRebuild.has(module)) {
465-
firstIndex = i;
466-
content.unshift(module.content.replace(/(?:[\r\n]+)/g, '\\n'));
467-
issuerDeps.splice(i, 1);
459+
compilation.hooks.optimizeTree.tapAsync(
460+
pluginName,
461+
(chunks, modules, callback) => {
462+
const promises = [];
463+
464+
for (const chunk of chunks) {
465+
const isAsync = !isInitialOrHasNoParents(chunk);
466+
// eslint-disable-next-line no-underscore-dangle
467+
for (const module of chunk._modules) {
468+
if (module.type === MODULE_TYPE) {
469+
if (this.shouldDisableExtract({ module, isAsync })) {
470+
moduleToBeRebuild.add(module);
471+
}
472+
}
468473
}
469474
}
470475

471-
if (firstIndex > -1) {
472-
issuerDeps.splice(
473-
firstIndex,
474-
0,
475-
new ReplaceDependency(`module.exports = "${content.join('')}";`, [
476-
0,
477-
len,
478-
])
479-
);
476+
for (const currentModuleToBeRebuild of moduleToBeRebuild) {
477+
const { issuer } = currentModuleToBeRebuild;
478+
if (!issuer[`${MODULE_TYPE}/disableExtract`]) {
479+
issuer[`${MODULE_TYPE}/disableExtract`] = true;
480+
promises.push(
481+
new Promise((resolve) => {
482+
compilation.rebuildModule(issuer, (err) => {
483+
if (err) {
484+
compilation.errors.push(err);
485+
}
486+
resolve();
487+
});
488+
})
489+
);
490+
}
480491
}
481-
}
482492

483-
return source;
484-
});
493+
Promise.all(promises).then(() => callback());
494+
}
495+
);
485496
});
486497
}
487498

488-
shouldDisableExtract({ module }) {
499+
shouldDisableExtract({ module, isAsync }) {
489500
const { disableExtract } = this.options;
490501
let shouldDisable = false;
491502
if (disableExtract === true) {
492503
shouldDisable = true;
493504
} else if (typeof disableExtract === 'function') {
494-
shouldDisable = disableExtract({ module });
505+
shouldDisable = disableExtract({ module, isAsync });
495506
}
496507

497508
return shouldDisable;
@@ -503,23 +514,14 @@ class MiniCssExtractPlugin {
503514
for (const chunk of mainChunk.getAllAsyncChunks()) {
504515
for (const module of chunk.modulesIterable) {
505516
if (module.type === MODULE_TYPE) {
506-
if (this.shouldDisableExtract({ module, isAsync: true })) {
507-
compilation[MODULE_TYPE].moduleToBeRebuild.add(module);
508-
} else {
517+
if (!compilation[MODULE_TYPE].moduleToBeRebuild.has(module)) {
509518
obj[chunk.id] = 1;
519+
break;
510520
}
511521
}
512522
}
513523
}
514524

515-
for (const module of mainChunk.modulesIterable) {
516-
if (module.type === MODULE_TYPE) {
517-
if (this.shouldDisableExtract({ module, isAsync: false })) {
518-
compilation[MODULE_TYPE].moduleToBeRebuild.add(module);
519-
}
520-
}
521-
}
522-
523525
return obj;
524526
}
525527

src/lib/ReplaceDependency.js

-27
This file was deleted.

0 commit comments

Comments
 (0)