33import { validate } from 'schema-utils' ;
44
55import schema from './plugin-options.json' ;
6- import { shared , MODULE_TYPE , compareModulesByIdentifier } from './utils' ;
6+ import {
7+ MODULE_TYPE ,
8+ compareModulesByIdentifier ,
9+ provideLoaderContext ,
10+ } from './utils' ;
711
8- const pluginName = 'mini-css-extract-plugin' ;
12+ export const pluginName = 'mini-css-extract-plugin' ;
13+ export const pluginSymbol = Symbol ( pluginName ) ;
914
1015const REGEXP_CHUNKHASH = / \[ c h u n k h a s h (?: : ( \d + ) ) ? \] / i;
1116const REGEXP_CONTENTHASH = / \[ c o n t e n t h a s h (?: : ( \d + ) ) ? \] / i;
@@ -18,8 +23,23 @@ const CODE_GENERATION_RESULT = {
1823 runtimeRequirements : new Set ( ) ,
1924} ;
2025
26+ /**
27+ * @type WeakMap<webpack, CssModule>
28+ */
29+ const cssModuleCache = new WeakMap ( ) ;
30+ /**
31+ * @type WeakMap<webpack, CssDependency>
32+ */
33+ const cssDependencyCache = new WeakMap ( ) ;
34+
2135class MiniCssExtractPlugin {
2236 static getCssModule ( webpack ) {
37+ /**
38+ * Prevent creation of multiple CssModule classes to allow other integrations to get the current CssModule.
39+ */
40+ if ( cssModuleCache . has ( webpack ) ) {
41+ return cssModuleCache . get ( webpack ) ;
42+ }
2343 class CssModule extends webpack . Module {
2444 constructor ( {
2545 context,
@@ -134,6 +154,8 @@ class MiniCssExtractPlugin {
134154 }
135155 }
136156
157+ cssModuleCache . set ( webpack , CssModule ) ;
158+
137159 if (
138160 webpack . util &&
139161 webpack . util . serialization &&
@@ -181,6 +203,12 @@ class MiniCssExtractPlugin {
181203 }
182204
183205 static getCssDependency ( webpack ) {
206+ /**
207+ * Prevent creation of multiple CssDependency classes to allow other integrations to get the current CssDependency.
208+ */
209+ if ( cssDependencyCache . has ( webpack ) ) {
210+ return cssDependencyCache . get ( webpack ) ;
211+ }
184212 // eslint-disable-next-line no-shadow
185213 class CssDependency extends webpack . Dependency {
186214 constructor (
@@ -231,6 +259,8 @@ class MiniCssExtractPlugin {
231259 }
232260 }
233261
262+ cssDependencyCache . set ( webpack , CssDependency ) ;
263+
234264 if (
235265 webpack . util &&
236266 webpack . util . serialization &&
@@ -356,16 +386,18 @@ class MiniCssExtractPlugin {
356386 }
357387 }
358388
359- // initializeCssDependency
360- // eslint-disable-next-line no-shadow
361- const { CssModule, CssDependency } = shared ( webpack , ( webpack ) => {
362- // eslint-disable-next-line no-shadow
363- const CssModule = MiniCssExtractPlugin . getCssModule ( webpack ) ;
364- // eslint-disable-next-line no-shadow
365- const CssDependency = MiniCssExtractPlugin . getCssDependency ( webpack ) ;
366-
367- return { CssModule, CssDependency } ;
368- } ) ;
389+ const CssModule = MiniCssExtractPlugin . getCssModule ( webpack ) ;
390+ const CssDependency = MiniCssExtractPlugin . getCssDependency ( webpack ) ;
391+
392+ provideLoaderContext (
393+ compiler ,
394+ `${ pluginName } loader context` ,
395+ ( loaderContext ) => {
396+ // eslint-disable-next-line no-param-reassign
397+ loaderContext [ pluginSymbol ] = true ;
398+ } ,
399+ false
400+ ) ;
369401
370402 compiler . hooks . thisCompilation . tap ( pluginName , ( compilation ) => {
371403 class CssModuleFactory {
@@ -1093,7 +1125,7 @@ class MiniCssExtractPlugin {
10931125 return usedModules ;
10941126 }
10951127
1096- modules = [ ...modules ] ;
1128+ const modulesList = [ ...modules ] ;
10971129
10981130 const [ chunkGroup ] = chunk . groupsIterable ;
10991131 const moduleIndexFunctionName =
@@ -1103,16 +1135,18 @@ class MiniCssExtractPlugin {
11031135
11041136 if ( typeof chunkGroup [ moduleIndexFunctionName ] === 'function' ) {
11051137 // Store dependencies for modules
1106- const moduleDependencies = new Map ( modules . map ( ( m ) => [ m , new Set ( ) ] ) ) ;
1138+ const moduleDependencies = new Map (
1139+ modulesList . map ( ( m ) => [ m , new Set ( ) ] )
1140+ ) ;
11071141 const moduleDependenciesReasons = new Map (
1108- modules . map ( ( m ) => [ m , new Map ( ) ] )
1142+ modulesList . map ( ( m ) => [ m , new Map ( ) ] )
11091143 ) ;
11101144
11111145 // Get ordered list of modules per chunk group
11121146 // This loop also gathers dependencies from the ordered lists
11131147 // Lists are in reverse order to allow to use Array.pop()
11141148 const modulesByChunkGroup = Array . from ( chunk . groupsIterable , ( cg ) => {
1115- const sortedModules = modules
1149+ const sortedModules = modulesList
11161150 . map ( ( m ) => {
11171151 return {
11181152 module : m ,
@@ -1145,7 +1179,7 @@ class MiniCssExtractPlugin {
11451179
11461180 const unusedModulesFilter = ( m ) => ! usedModules . has ( m ) ;
11471181
1148- while ( usedModules . size < modules . length ) {
1182+ while ( usedModules . size < modulesList . length ) {
11491183 let success = false ;
11501184 let bestMatch ;
11511185 let bestMatchDeps ;
@@ -1227,8 +1261,8 @@ class MiniCssExtractPlugin {
12271261 // (to avoid a breaking change)
12281262 // TODO remove this in next major version
12291263 // and increase minimum webpack version to 4.12.0
1230- modules . sort ( ( a , b ) => a . index2 - b . index2 ) ;
1231- usedModules = modules ;
1264+ modulesList . sort ( ( a , b ) => a . index2 - b . index2 ) ;
1265+ usedModules = modulesList ;
12321266 }
12331267
12341268 this . _sortedModulesCache . set ( chunk , usedModules ) ;
0 commit comments