@@ -41,44 +41,47 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
4141 const cssSourceMap = buildOptions . extractCss && buildOptions . sourcemaps ;
4242
4343 // Minify/optimize css in production.
44- const cssnanoPlugin = cssnano ( { safe : true , autoprefixer : false } ) ;
45-
44+ const minimizeCss = buildOptions . target === 'production' ;
4645 // Convert absolute resource URLs to account for base-href and deploy-url.
4746 const baseHref = wco . buildOptions . baseHref || '' ;
4847 const deployUrl = wco . buildOptions . deployUrl || '' ;
49- const postcssUrlOptions = {
50- url : ( URL : string ) => {
51- // Only convert root relative URLs, which CSS-Loader won't process into require().
52- if ( ! URL . startsWith ( '/' ) || URL . startsWith ( '//' ) ) {
53- return URL ;
54- }
5548
56- if ( deployUrl . match ( / : \/ \/ / ) ) {
57- // If deployUrl contains a scheme, ignore baseHref use deployUrl as is.
58- return `${ deployUrl . replace ( / \/ $ / , '' ) } ${ URL } ` ;
59- } else if ( baseHref . match ( / : \/ \/ / ) ) {
60- // If baseHref contains a scheme, include it as is.
61- return baseHref . replace ( / \/ $ / , '' ) +
62- `/${ deployUrl } /${ URL } ` . replace ( / \/ \/ + / g, '/' ) ;
63- } else {
64- // Join together base-href, deploy-url and the original URL.
65- // Also dedupe multiple slashes into single ones.
66- return `/${ baseHref } /${ deployUrl } /${ URL } ` . replace ( / \/ \/ + / g, '/' ) ;
67- }
68- }
49+ const postcssPluginCreator = function ( ) {
50+ return [
51+ autoprefixer ( ) ,
52+ postcssUrl ( {
53+ url : ( URL : string ) => {
54+ // Only convert root relative URLs, which CSS-Loader won't process into require().
55+ if ( ! URL . startsWith ( '/' ) || URL . startsWith ( '//' ) ) {
56+ return URL ;
57+ }
58+
59+ if ( deployUrl . match ( / : \/ \/ / ) ) {
60+ // If deployUrl contains a scheme, ignore baseHref use deployUrl as is.
61+ return `${ deployUrl . replace ( / \/ $ / , '' ) } ${ URL } ` ;
62+ } else if ( baseHref . match ( / : \/ \/ / ) ) {
63+ // If baseHref contains a scheme, include it as is.
64+ return baseHref . replace ( / \/ $ / , '' ) +
65+ `/${ deployUrl } /${ URL } ` . replace ( / \/ \/ + / g, '/' ) ;
66+ } else {
67+ // Join together base-href, deploy-url and the original URL.
68+ // Also dedupe multiple slashes into single ones.
69+ return `/${ baseHref } /${ deployUrl } /${ URL } ` . replace ( / \/ \/ + / g, '/' ) ;
70+ }
71+ }
72+ } )
73+ ] . concat (
74+ minimizeCss ? [ cssnano ( { safe : true , autoprefixer : false } ) ] : [ ]
75+ ) ;
76+ } ;
77+ ( postcssPluginCreator as any ) [ postcssArgs ] = {
78+ variableImports : {
79+ 'autoprefixer' : 'autoprefixer' ,
80+ 'postcss-url' : 'postcssUrl' ,
81+ 'cssnano' : 'cssnano'
82+ } ,
83+ variables : { minimizeCss, baseHref, deployUrl }
6984 } ;
70- const urlPlugin = postcssUrl ( postcssUrlOptions ) ;
71- // We need to save baseHref and deployUrl for the Ejected webpack config to work (we reuse
72- // the function defined above).
73- ( postcssUrlOptions as any ) . baseHref = baseHref ;
74- ( postcssUrlOptions as any ) . deployUrl = deployUrl ;
75- // Save the original options as arguments for eject.
76- urlPlugin [ postcssArgs ] = postcssUrlOptions ;
77-
78- // PostCSS plugins.
79- const postCssPlugins = [ autoprefixer ( ) , urlPlugin ] . concat (
80- buildOptions . target === 'production' ? [ cssnanoPlugin ] : [ ]
81- ) ;
8285
8386 // determine hashing format
8487 const hashFormat = getOutputHashFormat ( buildOptions . outputHashing ) ;
@@ -108,59 +111,86 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
108111 }
109112
110113 // set base rules to derive final rules from
111- const baseRules = [
112- { test : / \. c s s $ / , loaders : [ ] } ,
113- { test : / \. s c s s $ | \. s a s s $ / , loaders : [ 'sass-loader' ] } ,
114- { test : / \. l e s s $ / , loaders : [ 'less-loader' ] } ,
115- // stylus-loader doesn't support webpack.LoaderOptionsPlugin properly,
116- // so we need to add options in its query
114+ const baseRules : webpack . NewUseRule [ ] = [
115+ { test : / \. c s s $ / , use : [ ] } ,
116+ { test : / \. s c s s $ | \. s a s s $ / , use : [ {
117+ loader : 'sass-loader' ,
118+ options : {
119+ sourceMap : cssSourceMap ,
120+ includePaths
121+ }
122+ } ]
123+ } ,
124+ { test : / \. l e s s $ / , use : [ {
125+ loader : 'less-loader' ,
126+ options : {
127+ sourceMap : cssSourceMap
128+ }
129+ } ]
130+ } ,
117131 {
118- test : / \. s t y l $ / , loaders : [ `stylus-loader?${ JSON . stringify ( {
119- sourceMap : cssSourceMap ,
120- paths : includePaths
121- } ) } `]
132+ test : / \. s t y l $ / , use : [ {
133+ loader : 'stylus-loader' ,
134+ options : {
135+ sourceMap : cssSourceMap ,
136+ paths : includePaths
137+ }
138+ } ]
122139 }
123140 ] ;
124141
125- const commonLoaders = [
126- // css-loader doesn't support webpack.LoaderOptionsPlugin properly,
127- // so we need to add options in its query
128- `css-loader?${ JSON . stringify ( { sourceMap : cssSourceMap , importLoaders : 1 } ) } ` ,
129- 'postcss-loader'
142+ const commonLoaders : webpack . Loader [ ] = [
143+ {
144+ loader : 'css-loader' ,
145+ options : {
146+ sourceMap : cssSourceMap ,
147+ importLoaders : 1
148+ }
149+ } ,
150+ {
151+ loader : 'postcss-loader' ,
152+ options : {
153+ // A non-function property is required to workaround a webpack option handling bug
154+ ident : 'postcss' ,
155+ plugins : postcssPluginCreator
156+ }
157+ }
130158 ] ;
131159
132160 // load component css as raw strings
133- let rules : any = baseRules . map ( ( { test, loaders } ) => ( {
134- exclude : globalStylePaths , test, loaders : [
161+ const rules : webpack . Rule [ ] = baseRules . map ( ( { test, use } ) => ( {
162+ exclude : globalStylePaths , test, use : [
135163 'exports-loader?module.exports.toString()' ,
136164 ...commonLoaders ,
137- ...loaders
165+ ...( use as webpack . Loader [ ] )
138166 ]
139167 } ) ) ;
140168
141169 // load global css as css files
142170 if ( globalStylePaths . length > 0 ) {
143- rules . push ( ...baseRules . map ( ( { test, loaders } ) => {
171+ rules . push ( ...baseRules . map ( ( { test, use } ) => {
144172 const extractTextPlugin = {
145173 use : [
146174 ...commonLoaders ,
147- ...loaders
175+ ...( use as webpack . Loader [ ] )
148176 ] ,
149177 fallback : 'style-loader' ,
150178 // publicPath needed as a workaround https://github.com/angular/angular-cli/issues/4035
151179 publicPath : ''
152180 } ;
153181 const ret : any = {
154- include : globalStylePaths , test, loaders : ExtractTextPlugin . extract ( extractTextPlugin )
182+ include : globalStylePaths ,
183+ test,
184+ use : ExtractTextPlugin . extract ( extractTextPlugin )
155185 } ;
156186 // Save the original options as arguments for eject.
157187 ret [ pluginArgs ] = extractTextPlugin ;
158188 return ret ;
159189 } ) ) ;
160190 }
161191
162- // supress empty .js files in css only entry points
163192 if ( buildOptions . extractCss ) {
193+ // suppress empty .js files in css only entry points
164194 extraPlugins . push ( new SuppressExtractedTextChunksWebpackPlugin ( ) ) ;
165195 }
166196
@@ -172,19 +202,6 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
172202 new ExtractTextPlugin ( {
173203 filename : `[name]${ hashFormat . extract } .bundle.css` ,
174204 disable : ! buildOptions . extractCss
175- } ) ,
176- new webpack . LoaderOptionsPlugin ( {
177- sourceMap : cssSourceMap ,
178- options : {
179- postcss : postCssPlugins ,
180- // css-loader, stylus-loader don't support LoaderOptionsPlugin properly
181- // options are in query instead
182- sassLoader : { sourceMap : cssSourceMap , includePaths } ,
183- // less-loader doesn't support paths
184- lessLoader : { sourceMap : cssSourceMap } ,
185- // context needed as a workaround https://github.com/jtangelder/sass-loader/issues/285
186- context : projectRoot ,
187- } ,
188205 } )
189206 ] . concat ( extraPlugins )
190207 } ;
0 commit comments