11import * as webpack from 'webpack' ;
22import * as path from 'path' ;
3- import { GlobCopyWebpackPlugin } from '../plugins/glob-copy-webpack-plugin' ;
4- import { packageChunkSort } from '../utilities/package-chunk-sort' ;
5- import { BaseHrefWebpackPlugin } from '@angular-cli/base-href-webpack' ;
3+ import { GlobCopyWebpackPlugin } from '../plugins/glob-copy-webpack-plugin' ;
4+ import { SuppressEntryChunksWebpackPlugin } from '../plugins/suppress-entry-chunks-webpack-plugin' ;
5+ import { packageChunkSort } from '../utilities/package-chunk-sort' ;
6+ import { BaseHrefWebpackPlugin } from '@angular-cli/base-href-webpack' ;
7+ import { extraEntryParser , makeCssLoaders } from './webpack-build-utils' ;
68
7- const ProgressPlugin = require ( 'webpack/lib/ProgressPlugin' ) ;
9+ const autoprefixer = require ( 'autoprefixer' ) ;
10+ const ProgressPlugin = require ( 'webpack/lib/ProgressPlugin' ) ;
811const HtmlWebpackPlugin = require ( 'html-webpack-plugin' ) ;
912const SilentError = require ( 'silent-error' ) ;
1013
@@ -14,21 +17,12 @@ const SilentError = require('silent-error');
1417 *
1518 * require('source-map-loader')
1619 * require('raw-loader')
17- * require('postcss-loader')
18- * require('stylus-loader')
19- * require('less-loader')
20- * require('sass-loader')
2120 * require('script-loader')
2221 * require('json-loader')
2322 * require('url-loader')
2423 * require('file-loader')
25- *
26- * require('node-sass')
27- * require('less')
28- * require('stylus')
2924 */
3025
31-
3226export function getWebpackCommonConfig (
3327 projectRoot : string ,
3428 environment : string ,
@@ -43,25 +37,64 @@ export function getWebpackCommonConfig(
4337 const appRoot = path . resolve ( projectRoot , appConfig . root ) ;
4438 const appMain = path . resolve ( appRoot , appConfig . main ) ;
4539 const nodeModules = path . resolve ( projectRoot , 'node_modules' ) ;
46- const styles = appConfig . styles
47- ? appConfig . styles . map ( ( style : string ) => path . resolve ( appRoot , style ) )
48- : [ ] ;
49- const scripts = appConfig . scripts
50- ? appConfig . scripts . map ( ( script : string ) => path . resolve ( appRoot , script ) )
51- : [ ] ;
52- const extraPlugins : any [ ] = [ ] ;
53-
54- let entry : { [ key : string ] : string [ ] } = {
40+
41+ let extraPlugins : any [ ] = [ ] ;
42+ let extraRules : any [ ] = [ ] ;
43+ let lazyChunks : string [ ] = [ ] ;
44+
45+ let entryPoints : { [ key : string ] : string [ ] } = {
5546 main : [ appMain ]
5647 } ;
5748
5849 if ( ! ( environment in appConfig . environments ) ) {
5950 throw new SilentError ( `Environment "${ environment } " does not exist.` ) ;
6051 }
6152
62- // Only add styles/scripts if there's actually entries there
63- if ( appConfig . styles . length > 0 ) { entry [ 'styles' ] = styles ; }
64- if ( appConfig . scripts . length > 0 ) { entry [ 'scripts' ] = scripts ; }
53+ // process global scripts
54+ if ( appConfig . scripts . length > 0 ) {
55+ const globalScrips = extraEntryParser ( appConfig . scripts , appRoot , 'scripts' ) ;
56+
57+ // add entry points and lazy chunks
58+ globalScrips . forEach ( script => {
59+ if ( script . lazy ) { lazyChunks . push ( script . entry ) ; }
60+ entryPoints [ script . entry ] = ( entryPoints [ script . entry ] || [ ] ) . concat ( script . path ) ;
61+ } ) ;
62+
63+ // load global scripts using script-loader
64+ extraRules . push ( {
65+ include : globalScrips . map ( ( script ) => script . path ) , test : / \. j s $ / , loader : 'script-loader'
66+ } ) ;
67+ }
68+
69+ // process global styles
70+ if ( appConfig . styles . length === 0 ) {
71+ // create css loaders for component css
72+ extraRules . push ( ...makeCssLoaders ( ) ) ;
73+ } else {
74+ const globalStyles = extraEntryParser ( appConfig . styles , appRoot , 'styles' ) ;
75+ let extractedCssEntryPoints : string [ ] = [ ] ;
76+ // add entry points and lazy chunks
77+ globalStyles . forEach ( style => {
78+ if ( style . lazy ) { lazyChunks . push ( style . entry ) ; }
79+ if ( ! entryPoints [ style . entry ] ) {
80+ // since this entry point doesn't exist yet, it's going to only have
81+ // extracted css and we can supress the entry point
82+ extractedCssEntryPoints . push ( style . entry ) ;
83+ entryPoints [ style . entry ] = ( entryPoints [ style . entry ] || [ ] ) . concat ( style . path ) ;
84+ } else {
85+ // existing entry point, just push the css in
86+ entryPoints [ style . entry ] . push ( style . path ) ;
87+ }
88+ } ) ;
89+
90+ // create css loaders for component css and for global css
91+ extraRules . push ( ...makeCssLoaders ( globalStyles . map ( ( style ) => style . path ) ) ) ;
92+
93+ if ( extractedCssEntryPoints . length > 0 ) {
94+ // don't emit the .js entry point for extracted styles
95+ extraPlugins . push ( new SuppressEntryChunksWebpackPlugin ( { chunks : extractedCssEntryPoints } ) ) ;
96+ }
97+ }
6598
6699 if ( vendorChunk ) {
67100 extraPlugins . push ( new webpack . optimize . CommonsChunkPlugin ( {
@@ -71,12 +104,7 @@ export function getWebpackCommonConfig(
71104 } ) ) ;
72105 }
73106
74- if ( progress ) {
75- extraPlugins . push ( new ProgressPlugin ( {
76- profile : verbose ,
77- colors : true
78- } ) ) ;
79- }
107+ if ( progress ) { extraPlugins . push ( new ProgressPlugin ( { profile : verbose , colors : true } ) ) ; }
80108
81109 return {
82110 devtool : sourcemap ? 'source-map' : false ,
@@ -85,10 +113,10 @@ export function getWebpackCommonConfig(
85113 modules : [ nodeModules ] ,
86114 } ,
87115 resolveLoader : {
88- modules : [ path . resolve ( projectRoot , 'node_modules' ) ]
116+ modules : [ nodeModules ]
89117 } ,
90118 context : projectRoot ,
91- entry : entry ,
119+ entry : entryPoints ,
92120 output : {
93121 path : path . resolve ( projectRoot , appConfig . outDir ) ,
94122 filename : '[name].bundle.js' ,
@@ -97,48 +125,22 @@ export function getWebpackCommonConfig(
97125 } ,
98126 module : {
99127 rules : [
100- {
101- enforce : 'pre' ,
102- test : / \. j s $ / ,
103- loader : 'source-map-loader' ,
104- exclude : [ nodeModules ]
105- } ,
106- // in main, load css as raw text
107- {
108- exclude : styles ,
109- test : / \. c s s $ / ,
110- loaders : [ 'raw-loader' , 'postcss-loader' ]
111- } , {
112- exclude : styles ,
113- test : / \. s t y l $ / ,
114- loaders : [ 'raw-loader' , 'postcss-loader' , 'stylus-loader' ] } ,
115- {
116- exclude : styles ,
117- test : / \. l e s s $ / ,
118- loaders : [ 'raw-loader' , 'postcss-loader' , 'less-loader' ]
119- } , {
120- exclude : styles ,
121- test : / \. s c s s $ | \. s a s s $ / ,
122- loaders : [ 'raw-loader' , 'postcss-loader' , 'sass-loader' ]
123- } ,
124-
125-
126- // load global scripts using script-loader
127- { include : scripts , test : / \. j s $ / , loader : 'script-loader' } ,
128+ { enforce : 'pre' , test : / \. j s $ / , loader : 'source-map-loader' , exclude : [ nodeModules ] } ,
128129
129- { test : / \. j s o n $ / , loader : 'json-loader' } ,
130- { test : / \. ( j p g | p n g | g i f ) $ / , loader : 'url-loader?limit=10000' } ,
131- { test : / \. h t m l $ / , loader : 'raw-loader' } ,
130+ { test : / \. j s o n $ / , loader : 'json-loader' } ,
131+ { test : / \. ( j p g | p n g | g i f ) $ / , loader : 'url-loader?limit=10000' } ,
132+ { test : / \. h t m l $ / , loader : 'raw-loader' } ,
132133
133134 { test : / \. ( o t f | t t f | w o f f | w o f f 2 ) $ / , loader : 'url-loader?limit=10000' } ,
134135 { test : / \. ( e o t | s v g ) $ / , loader : 'file-loader' }
135- ]
136+ ] . concat ( extraRules )
136137 } ,
137138 plugins : [
138139 new HtmlWebpackPlugin ( {
139140 template : path . resolve ( appRoot , appConfig . index ) ,
140141 filename : path . resolve ( appConfig . outDir , appConfig . index ) ,
141- chunksSortMode : packageChunkSort ( [ 'inline' , 'styles' , 'scripts' , 'vendor' , 'main' ] )
142+ chunksSortMode : packageChunkSort ( [ 'inline' , 'styles' , 'scripts' , 'vendor' , 'main' ] ) ,
143+ excludeChunks : lazyChunks
142144 } ) ,
143145 new BaseHrefWebpackPlugin ( {
144146 baseHref : baseHref
@@ -157,14 +159,18 @@ export function getWebpackCommonConfig(
157159 } ) ,
158160 new GlobCopyWebpackPlugin ( {
159161 patterns : appConfig . assets ,
160- globOptions : { cwd : appRoot , dot : true , ignore : '**/.gitkeep' }
162+ globOptions : { cwd : appRoot , dot : true , ignore : '**/.gitkeep' }
161163 } ) ,
162164 new webpack . LoaderOptionsPlugin ( {
163165 test : / \. ( c s s | s c s s | s a s s | l e s s | s t y l ) $ / ,
164166 options : {
165- postcss : [
166- require ( 'autoprefixer' )
167- ]
167+ postcss : [ autoprefixer ( ) ] ,
168+ cssLoader : { sourceMap : sourcemap } ,
169+ sassLoader : { sourceMap : sourcemap } ,
170+ lessLoader : { sourceMap : sourcemap } ,
171+ stylusLoader : { sourceMap : sourcemap } ,
172+ // context needed as a workaround https://github.com/jtangelder/sass-loader/issues/285
173+ context : projectRoot ,
168174 } ,
169175 } )
170176 ] . concat ( extraPlugins ) ,
0 commit comments