@@ -13,69 +13,55 @@ import Warning from './Warning';
13
13
import schema from './options.json' ;
14
14
import { icssParser , importParser , urlParser } from './plugins' ;
15
15
import {
16
- getModulesOptions ,
16
+ normalizeOptions ,
17
+ shouldUseModulesPlugins ,
18
+ shouldUseImportPlugin ,
19
+ shouldUseURLPlugin ,
17
20
getPreRequester ,
18
21
getExportCode ,
19
22
getFilter ,
20
23
getImportCode ,
21
24
getModuleCode ,
22
25
getModulesPlugins ,
23
26
normalizeSourceMap ,
24
- shouldUseModulesPlugins ,
25
- isUrlRequestable ,
27
+ sortImports ,
26
28
} from './utils' ;
27
29
28
- export default function loader ( content , map , meta ) {
29
- const options = getOptions ( this ) ;
30
+ export default async function loader ( content , map , meta ) {
31
+ const rawOptions = getOptions ( this ) ;
30
32
31
- validateOptions ( schema , options , {
33
+ validateOptions ( schema , rawOptions , {
32
34
name : 'CSS Loader' ,
33
35
baseDataPath : 'options' ,
34
36
} ) ;
35
37
36
- const sourceMap =
37
- typeof options . sourceMap === 'boolean' ? options . sourceMap : this . sourceMap ;
38
38
const plugins = [ ] ;
39
+ const options = normalizeOptions ( rawOptions , this ) ;
39
40
40
- const exportType = options . onlyLocals ? 'locals' : 'full' ;
41
- const preRequester = getPreRequester ( this ) ;
42
- const urlHandler = ( url ) =>
43
- stringifyRequest ( this , preRequester ( options . importLoaders ) + url ) ;
44
-
45
- const esModule =
46
- typeof options . esModule !== 'undefined' ? options . esModule : true ;
47
-
48
- let modulesOptions ;
49
-
50
- if ( shouldUseModulesPlugins ( options . modules , this . resourcePath ) ) {
51
- modulesOptions = getModulesOptions ( options , this ) ;
52
-
53
- if ( modulesOptions . namedExport === true && esModule === false ) {
54
- this . emitError (
55
- new Error (
56
- '`Options.module.namedExport` cannot be used without `options.esModule`'
57
- )
58
- ) ;
59
- }
60
-
61
- plugins . push ( ...getModulesPlugins ( modulesOptions , this ) ) ;
62
-
41
+ if ( shouldUseModulesPlugins ( options ) ) {
63
42
const icssResolver = this . getResolve ( {
64
43
mainFields : [ 'css' , 'style' , 'main' , '...' ] ,
65
44
mainFiles : [ 'index' , '...' ] ,
45
+ extensions : [ ] ,
46
+ conditionNames : [ 'style' ] ,
66
47
} ) ;
67
48
68
49
plugins . push (
50
+ ...getModulesPlugins ( options , this ) ,
69
51
icssParser ( {
70
52
context : this . context ,
71
53
rootContext : this . rootContext ,
72
54
resolver : icssResolver ,
73
- urlHandler,
55
+ urlHandler : ( url ) =>
56
+ stringifyRequest (
57
+ this ,
58
+ getPreRequester ( this ) ( options . importLoaders ) + url
59
+ ) ,
74
60
} )
75
61
) ;
76
62
}
77
63
78
- if ( options . import !== false && exportType === 'full' ) {
64
+ if ( shouldUseImportPlugin ( options ) ) {
79
65
const resolver = this . getResolve ( {
80
66
mainFields : [ 'css' , 'style' , 'main' , '...' ] ,
81
67
mainFiles : [ 'index' , '...' ] ,
@@ -90,24 +76,27 @@ export default function loader(content, map, meta) {
90
76
rootContext : this . rootContext ,
91
77
filter : getFilter ( options . import , this . resourcePath ) ,
92
78
resolver,
93
- urlHandler,
79
+ urlHandler : ( url ) =>
80
+ stringifyRequest (
81
+ this ,
82
+ getPreRequester ( this ) ( options . importLoaders ) + url
83
+ ) ,
94
84
} )
95
85
) ;
96
86
}
97
87
98
- if ( options . url !== false && exportType === 'full' ) {
88
+ if ( shouldUseURLPlugin ( options ) ) {
99
89
const urlResolver = this . getResolve ( {
100
90
mainFields : [ 'asset' ] ,
101
91
conditionNames : [ 'asset' ] ,
92
+ extensions : [ ] ,
102
93
} ) ;
103
94
104
95
plugins . push (
105
96
urlParser ( {
106
97
context : this . context ,
107
98
rootContext : this . rootContext ,
108
- filter : getFilter ( options . url , this . resourcePath , ( value ) =>
109
- isUrlRequestable ( value )
110
- ) ,
99
+ filter : getFilter ( options . url , this . resourcePath ) ,
111
100
resolver : urlResolver ,
112
101
urlHandler : ( url ) => stringifyRequest ( this , url ) ,
113
102
} )
@@ -130,107 +119,76 @@ export default function loader(content, map, meta) {
130
119
131
120
const callback = this . async ( ) ;
132
121
133
- postcss ( plugins )
134
- . process ( content , {
122
+ let result ;
123
+
124
+ try {
125
+ result = await postcss ( plugins ) . process ( content , {
135
126
from : this . resourcePath ,
136
127
to : this . resourcePath ,
137
128
map : options . sourceMap
138
129
? {
139
130
// Some loaders (example `"postcss-loader": "1.x.x"`) always generates source map, we should remove it
140
- prev : sourceMap && map ? normalizeSourceMap ( map ) : null ,
131
+ prev : map ? normalizeSourceMap ( map ) : null ,
141
132
inline : false ,
142
133
annotation : false ,
143
134
}
144
135
: false ,
145
- } )
146
- . then ( ( result ) => {
147
- for ( const warning of result . warnings ( ) ) {
148
- this . emitWarning ( new Warning ( warning ) ) ;
149
- }
150
-
151
- const imports = [ ] ;
152
- const apiImports = [ ] ;
153
- const urlReplacements = [ ] ;
154
- const icssReplacements = [ ] ;
155
- const exports = [ ] ;
156
-
157
- for ( const message of result . messages ) {
158
- // eslint-disable-next-line default-case
159
- switch ( message . type ) {
160
- case 'import' :
161
- imports . push ( message . value ) ;
162
- break ;
163
- case 'api-import' :
164
- apiImports . push ( message . value ) ;
165
- break ;
166
- case 'url-replacement' :
167
- urlReplacements . push ( message . value ) ;
168
- break ;
169
- case 'icss-replacement' :
170
- icssReplacements . push ( message . value ) ;
171
- break ;
172
- case 'export' :
173
- exports . push ( message . value ) ;
174
- break ;
175
- }
176
- }
177
-
178
- /*
179
- * Order
180
- * CSS_LOADER_ICSS_IMPORT: [],
181
- * CSS_LOADER_AT_RULE_IMPORT: [],
182
- * CSS_LOADER_GET_URL_IMPORT: [],
183
- * CSS_LOADER_URL_IMPORT: [],
184
- * CSS_LOADER_URL_REPLACEMENT: [],
185
- * */
186
-
187
- imports . sort ( ( a , b ) => {
188
- return (
189
- ( b . order < a . order ) - ( a . order < b . order ) ||
190
- ( b . index < a . index ) - ( a . index < b . index )
191
- ) ;
192
- } ) ;
193
- apiImports . sort ( ( a , b ) => {
194
- return (
195
- ( b . order < a . order ) - ( a . order < b . order ) ||
196
- ( b . index < a . index ) - ( a . index < b . index )
197
- ) ;
198
- } ) ;
199
-
200
- const importCode = getImportCode (
201
- this ,
202
- exportType ,
203
- imports ,
204
- esModule ,
205
- modulesOptions
206
- ) ;
207
- const moduleCode = getModuleCode (
208
- result ,
209
- exportType ,
210
- sourceMap ,
211
- apiImports ,
212
- urlReplacements ,
213
- icssReplacements ,
214
- esModule ,
215
- modulesOptions
216
- ) ;
217
- const exportCode = getExportCode (
218
- exports ,
219
- exportType ,
220
- icssReplacements ,
221
- esModule ,
222
- modulesOptions
223
- ) ;
224
-
225
- return callback ( null , `${ importCode } ${ moduleCode } ${ exportCode } ` ) ;
226
- } )
227
- . catch ( ( error ) => {
228
- if ( error . file ) {
229
- this . addDependency ( error . file ) ;
230
- }
231
-
232
- callback (
233
- error . name === 'CssSyntaxError' ? new CssSyntaxError ( error ) : error
234
- ) ;
235
136
} ) ;
137
+ } catch ( error ) {
138
+ if ( error . file ) {
139
+ this . addDependency ( error . file ) ;
140
+ }
141
+
142
+ callback (
143
+ error . name === 'CssSyntaxError' ? new CssSyntaxError ( error ) : error
144
+ ) ;
145
+
146
+ return ;
147
+ }
148
+
149
+ for ( const warning of result . warnings ( ) ) {
150
+ this . emitWarning ( new Warning ( warning ) ) ;
151
+ }
152
+
153
+ const imports = [ ] ;
154
+ const apiImports = [ ] ;
155
+ const urlReplacements = [ ] ;
156
+ const icssReplacements = [ ] ;
157
+ const exports = [ ] ;
158
+
159
+ for ( const message of result . messages ) {
160
+ // eslint-disable-next-line default-case
161
+ switch ( message . type ) {
162
+ case 'import' :
163
+ imports . push ( message . value ) ;
164
+ break ;
165
+ case 'api-import' :
166
+ apiImports . push ( message . value ) ;
167
+ break ;
168
+ case 'url-replacement' :
169
+ urlReplacements . push ( message . value ) ;
170
+ break ;
171
+ case 'icss-replacement' :
172
+ icssReplacements . push ( message . value ) ;
173
+ break ;
174
+ case 'export' :
175
+ exports . push ( message . value ) ;
176
+ break ;
177
+ }
178
+ }
179
+
180
+ imports . sort ( sortImports ) ;
181
+ apiImports . sort ( sortImports ) ;
182
+
183
+ const importCode = getImportCode ( this , imports , options ) ;
184
+ const moduleCode = getModuleCode (
185
+ result ,
186
+ apiImports ,
187
+ urlReplacements ,
188
+ icssReplacements ,
189
+ options
190
+ ) ;
191
+ const exportCode = getExportCode ( exports , icssReplacements , options ) ;
192
+
193
+ callback ( null , `${ importCode } ${ moduleCode } ${ exportCode } ` ) ;
236
194
}
0 commit comments