3
3
import { validate } from 'schema-utils' ;
4
4
5
5
import 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' ;
7
11
8
- const pluginName = 'mini-css-extract-plugin' ;
12
+ export const pluginName = 'mini-css-extract-plugin' ;
13
+ export const pluginSymbol = Symbol ( pluginName ) ;
9
14
10
15
const REGEXP_CHUNKHASH = / \[ c h u n k h a s h (?: : ( \d + ) ) ? \] / i;
11
16
const REGEXP_CONTENTHASH = / \[ c o n t e n t h a s h (?: : ( \d + ) ) ? \] / i;
@@ -18,8 +23,23 @@ const CODE_GENERATION_RESULT = {
18
23
runtimeRequirements : new Set ( ) ,
19
24
} ;
20
25
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
+
21
35
class MiniCssExtractPlugin {
22
36
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
+ }
23
43
class CssModule extends webpack . Module {
24
44
constructor ( {
25
45
context,
@@ -134,6 +154,8 @@ class MiniCssExtractPlugin {
134
154
}
135
155
}
136
156
157
+ cssModuleCache . set ( webpack , CssModule ) ;
158
+
137
159
if (
138
160
webpack . util &&
139
161
webpack . util . serialization &&
@@ -181,6 +203,12 @@ class MiniCssExtractPlugin {
181
203
}
182
204
183
205
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
+ }
184
212
// eslint-disable-next-line no-shadow
185
213
class CssDependency extends webpack . Dependency {
186
214
constructor (
@@ -231,6 +259,8 @@ class MiniCssExtractPlugin {
231
259
}
232
260
}
233
261
262
+ cssDependencyCache . set ( webpack , CssDependency ) ;
263
+
234
264
if (
235
265
webpack . util &&
236
266
webpack . util . serialization &&
@@ -356,16 +386,18 @@ class MiniCssExtractPlugin {
356
386
}
357
387
}
358
388
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
+ ) ;
369
401
370
402
compiler . hooks . thisCompilation . tap ( pluginName , ( compilation ) => {
371
403
class CssModuleFactory {
@@ -1093,7 +1125,7 @@ class MiniCssExtractPlugin {
1093
1125
return usedModules ;
1094
1126
}
1095
1127
1096
- modules = [ ...modules ] ;
1128
+ const modulesList = [ ...modules ] ;
1097
1129
1098
1130
const [ chunkGroup ] = chunk . groupsIterable ;
1099
1131
const moduleIndexFunctionName =
@@ -1103,16 +1135,18 @@ class MiniCssExtractPlugin {
1103
1135
1104
1136
if ( typeof chunkGroup [ moduleIndexFunctionName ] === 'function' ) {
1105
1137
// 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
+ ) ;
1107
1141
const moduleDependenciesReasons = new Map (
1108
- modules . map ( ( m ) => [ m , new Map ( ) ] )
1142
+ modulesList . map ( ( m ) => [ m , new Map ( ) ] )
1109
1143
) ;
1110
1144
1111
1145
// Get ordered list of modules per chunk group
1112
1146
// This loop also gathers dependencies from the ordered lists
1113
1147
// Lists are in reverse order to allow to use Array.pop()
1114
1148
const modulesByChunkGroup = Array . from ( chunk . groupsIterable , ( cg ) => {
1115
- const sortedModules = modules
1149
+ const sortedModules = modulesList
1116
1150
. map ( ( m ) => {
1117
1151
return {
1118
1152
module : m ,
@@ -1145,7 +1179,7 @@ class MiniCssExtractPlugin {
1145
1179
1146
1180
const unusedModulesFilter = ( m ) => ! usedModules . has ( m ) ;
1147
1181
1148
- while ( usedModules . size < modules . length ) {
1182
+ while ( usedModules . size < modulesList . length ) {
1149
1183
let success = false ;
1150
1184
let bestMatch ;
1151
1185
let bestMatchDeps ;
@@ -1227,8 +1261,8 @@ class MiniCssExtractPlugin {
1227
1261
// (to avoid a breaking change)
1228
1262
// TODO remove this in next major version
1229
1263
// 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 ;
1232
1266
}
1233
1267
1234
1268
this . _sortedModulesCache . set ( chunk , usedModules ) ;
0 commit comments