Skip to content

Commit 7470dbf

Browse files
authored
Merge pull request #2863 from dmichon-msft/module-minifier-mini-css-compat
[module-minifier-plugin] Fix compatibility issue with mini-css-extract-plugin
2 parents f75f509 + 48e2b9a commit 7470dbf

File tree

3 files changed

+51
-25
lines changed

3 files changed

+51
-25
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@rushstack/module-minifier-plugin",
5+
"comment": "Fix compatibility issue with mini-css-extract-plugin and other plugins that introduce non-JavaScript modules and asset types.",
6+
"type": "patch"
7+
}
8+
],
9+
"packageName": "@rushstack/module-minifier-plugin",
10+
"email": "[email protected]"
11+
}

webpack/module-minifier-plugin/src/ModuleMinifierPlugin.ts

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -221,22 +221,6 @@ export class ModuleMinifierPlugin implements webpack.Plugin {
221221
}
222222
}
223223

224-
/**
225-
* Callback to invoke for a chunk during render to replace the modules with CHUNK_MODULES_TOKEN
226-
*/
227-
function dehydrateAsset(modules: Source, chunk: webpack.compilation.Chunk): Source {
228-
for (const mod of chunk.modulesIterable) {
229-
if (mod.id === null || !submittedModules.has(mod.id)) {
230-
console.error(
231-
`Chunk ${chunk.id} failed to render module ${mod.id} for ${(mod as IExtendedModule).resource}`
232-
);
233-
}
234-
}
235-
236-
// Discard the rendered modules
237-
return new RawSource(CHUNK_MODULES_TOKEN);
238-
}
239-
240224
const { minifier } = this;
241225

242226
const cleanupMinifier: (() => Promise<void>) | undefined = minifier.ref?.();
@@ -467,7 +451,7 @@ export class ModuleMinifierPlugin implements webpack.Plugin {
467451
}
468452
);
469453
} else {
470-
// Skip minification for all other assets, though the modules still are
454+
// This isn't a JS asset. Don't try to minify the asset wrapper, though if it contains modules, those might still get replaced with minified versions.
471455
minifiedAssets.set(assetName, {
472456
// Still need to restore ids
473457
source: postProcessCode(new ReplaceSource(asset), assetName),
@@ -509,9 +493,32 @@ export class ModuleMinifierPlugin implements webpack.Plugin {
509493
}
510494
);
511495

512-
for (const template of [compilation.chunkTemplate, compilation.mainTemplate]) {
513-
(template as unknown as IExtendedChunkTemplate).hooks.modules.tap(TAP_AFTER, dehydrateAsset);
514-
}
496+
// This function is written twice because the parameter order is not the same between the two hooks
497+
(compilation.chunkTemplate as unknown as IExtendedChunkTemplate).hooks.modules.tap(
498+
TAP_AFTER,
499+
(source: Source, chunk: webpack.compilation.Chunk, moduleTemplate: unknown) => {
500+
if (moduleTemplate !== compilation.moduleTemplates.javascript) {
501+
// This is not a JavaScript asset
502+
return source;
503+
}
504+
505+
// Discard the rendered modules
506+
return new RawSource(CHUNK_MODULES_TOKEN);
507+
}
508+
);
509+
510+
(compilation.mainTemplate as unknown as IExtendedChunkTemplate).hooks.modules.tap(
511+
TAP_AFTER,
512+
(source: Source, chunk: webpack.compilation.Chunk, hash: unknown, moduleTemplate: unknown) => {
513+
if (moduleTemplate !== compilation.moduleTemplates.javascript) {
514+
// This is not a JavaScript asset
515+
return source;
516+
}
517+
518+
// Discard the rendered modules
519+
return new RawSource(CHUNK_MODULES_TOKEN);
520+
}
521+
);
515522
}
516523
);
517524
}

webpack/module-minifier-plugin/src/RehydrateAsset.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,15 @@ import { IAssetInfo, IModuleMap, IModuleInfo } from './ModuleMinifierPlugin.type
1414
* @public
1515
*/
1616
export function rehydrateAsset(asset: IAssetInfo, moduleMap: IModuleMap, banner: string): Source {
17-
const { source: assetSource, modules, externalNames } = asset;
17+
const { source: assetSource, modules } = asset;
1818

1919
const assetCode: string = assetSource.source() as string;
2020

2121
const tokenIndex: number = assetCode.indexOf(CHUNK_MODULES_TOKEN);
22+
if (tokenIndex < 0) {
23+
// This is not a JS asset.
24+
return handleExternals(assetSource, asset);
25+
}
2226
const suffixStart: number = tokenIndex + CHUNK_MODULES_TOKEN.length;
2327
const suffix: string = assetCode.slice(suffixStart);
2428

@@ -138,11 +142,15 @@ export function rehydrateAsset(asset: IAssetInfo, moduleMap: IModuleMap, banner:
138142

139143
source.add(suffix);
140144

141-
const cached: CachedSource = new CachedSource(source);
145+
return handleExternals(new CachedSource(source), asset);
146+
}
147+
148+
function handleExternals(source: Source, asset: IAssetInfo): Source {
149+
const { externalNames } = asset;
142150

143151
if (externalNames.size) {
144-
const replaceSource: ReplaceSource = new ReplaceSource(cached);
145-
const code: string = cached.source() as string;
152+
const replaceSource: ReplaceSource = new ReplaceSource(source);
153+
const code: string = source.source() as string;
146154

147155
const externalIdRegex: RegExp = /__WEBPACK_EXTERNAL_MODULE_[A-Za-z0-9_$]+/g;
148156

@@ -162,5 +170,5 @@ export function rehydrateAsset(asset: IAssetInfo, moduleMap: IModuleMap, banner:
162170
return new CachedSource(replaceSource);
163171
}
164172

165-
return cached;
173+
return source;
166174
}

0 commit comments

Comments
 (0)