Skip to content

Commit 39b36e9

Browse files
committed
feat: ability to disable extract async modules
1 parent 0bacfac commit 39b36e9

33 files changed

+289
-5
lines changed

src/index.js

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
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';
58

69
const { ConcatSource, SourceMapSource, OriginalSource } = sources;
710
const {
@@ -148,6 +151,17 @@ class MiniCssExtractPlugin {
148151

149152
apply(compiler) {
150153
compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
154+
const asyncModuleToBeRebuild = new Set();
155+
compilation[MODULE_TYPE] = {
156+
asyncModuleToBeRebuild,
157+
};
158+
159+
compilation.dependencyFactories.set(ReplaceDependency, new NullFactory());
160+
compilation.dependencyTemplates.set(
161+
ReplaceDependency,
162+
new ReplaceDependency.Template()
163+
);
164+
151165
compilation.hooks.normalModuleLoader.tap(pluginName, (lc, m) => {
152166
const loaderContext = lc;
153167
const module = m;
@@ -215,7 +229,8 @@ class MiniCssExtractPlugin {
215229
pluginName,
216230
(result, { chunk }) => {
217231
const renderedModules = Array.from(chunk.modulesIterable).filter(
218-
(module) => module.type === MODULE_TYPE
232+
(module) =>
233+
module.type === MODULE_TYPE && !asyncModuleToBeRebuild.has(module)
219234
);
220235

221236
if (renderedModules.length > 0) {
@@ -283,7 +298,7 @@ class MiniCssExtractPlugin {
283298
const { mainTemplate } = compilation;
284299

285300
mainTemplate.hooks.localVars.tap(pluginName, (source, chunk) => {
286-
const chunkMap = this.getCssChunkObject(chunk);
301+
const chunkMap = this.getCssChunkObject(chunk, compilation);
287302

288303
if (Object.keys(chunkMap).length > 0) {
289304
return Template.asString([
@@ -304,7 +319,7 @@ class MiniCssExtractPlugin {
304319
mainTemplate.hooks.requireEnsure.tap(
305320
pluginName,
306321
(source, chunk, hash) => {
307-
const chunkMap = this.getCssChunkObject(chunk);
322+
const chunkMap = this.getCssChunkObject(chunk, compilation);
308323

309324
if (Object.keys(chunkMap).length > 0) {
310325
const chunkMaps = chunk.getChunkMaps();
@@ -433,17 +448,65 @@ class MiniCssExtractPlugin {
433448
return source;
434449
}
435450
);
451+
452+
const len = `// extracted by ${pluginName}`.length;
453+
mainTemplate.hooks.beforeStartup.tap(
454+
pluginName,
455+
(source, chunk, hash) => {
456+
for (const _m of asyncModuleToBeRebuild) {
457+
const issuerDeps = _m.issuer.dependencies;
458+
let firstIndex = -1;
459+
const content = [];
460+
461+
for (let i = issuerDeps.length - 1; i >= 0; i--) {
462+
const {module} = issuerDeps[i];
463+
if (asyncModuleToBeRebuild.has(module)) {
464+
firstIndex = i;
465+
content.push(module.content.replace(/(?:[\r\n]+)/g, '\\n'));
466+
issuerDeps.splice(i, 1);
467+
}
468+
}
469+
470+
if (firstIndex > -1) {
471+
issuerDeps.splice(
472+
firstIndex,
473+
0,
474+
new ReplaceDependency(
475+
`module.exports = "${content.join('')}";`,
476+
[0, len]
477+
)
478+
);
479+
}
480+
}
481+
return source;
482+
}
483+
);
436484
});
437485
}
438486

439-
getCssChunkObject(mainChunk) {
487+
shouldDisableAsync({ module }) {
488+
const {disableAsync} = this.options;
489+
let shouldDisable = false;
490+
if (disableAsync === true) {
491+
shouldDisable = true;
492+
} else if (typeof disableAsync === 'function') {
493+
shouldDisable = disableAsync({ module });
494+
}
495+
496+
return shouldDisable;
497+
}
498+
499+
getCssChunkObject(mainChunk, compilation) {
440500
const obj = {};
441501

442502
for (const chunk of mainChunk.getAllAsyncChunks()) {
443503
for (const module of chunk.modulesIterable) {
444504
if (module.type === MODULE_TYPE) {
505+
if (this.shouldDisableAsync({ module })) {
506+
compilation[MODULE_TYPE].asyncModuleToBeRebuild.add(module);
507+
}
508+
445509
obj[chunk.id] = 1;
446-
break;
447510
}
448511
}
449512
}

src/lib/ReplaceDependency.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const NullDependency = require('webpack/lib/dependencies/NullDependency');
2+
3+
class ReplaceDependency extends NullDependency {
4+
constructor(replacement, range) {
5+
super();
6+
this.replacement = replacement;
7+
this.range = range;
8+
}
9+
10+
get type() {
11+
return 'mini-css-extract-replace';
12+
}
13+
14+
updateHash(hash) {
15+
super.updateHash(hash);
16+
hash.update(this.replacement);
17+
}
18+
}
19+
20+
ReplaceDependency.Template = class ReplaceDependencyTemplate {
21+
apply(dep, source) {
22+
source.replace(dep.range[0], dep.range[1] - 1, dep.replacement);
23+
}
24+
};
25+
26+
module.exports = ReplaceDependency;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.async-import {
2+
background: black;
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.async {
2+
background: blue;
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import './in-async';
2+
import './in-async.css';
3+
import './in-async2.css';
4+
import './both-async.css';
5+
6+
console.log('async.js');
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import 'shared.css';
2+
3+
.both-async {
4+
color: red;
5+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.shared {
2+
background: pink;
3+
}
4+
body {
5+
background: red;
6+
}
7+
8+
.both-async {
9+
color: red;
10+
}
11+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import './async-import.css';
2+
3+
.in-async {
4+
background: green;
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('in-async.js');
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import './async-import.css';
2+
3+
.in-async-2 {
4+
background: green;
5+
}

0 commit comments

Comments
 (0)