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 ProgressPlugin = require ( 'webpack/lib/ProgressPlugin' ) ;
810const HtmlWebpackPlugin = require ( 'html-webpack-plugin' ) ;
911const autoprefixer = require ( 'autoprefixer' ) ;
1012
11-
1213export function getWebpackCommonConfig (
1314 projectRoot : string ,
1415 environment : string ,
@@ -23,21 +24,60 @@ export function getWebpackCommonConfig(
2324 const appRoot = path . resolve ( projectRoot , appConfig . root ) ;
2425 const appMain = path . resolve ( appRoot , appConfig . main ) ;
2526 const nodeModules = path . resolve ( projectRoot , 'node_modules' ) ;
26- const styles = appConfig . styles
27- ? appConfig . styles . map ( ( style : string ) => path . resolve ( appRoot , style ) )
28- : [ ] ;
29- const scripts = appConfig . scripts
30- ? appConfig . scripts . map ( ( script : string ) => path . resolve ( appRoot , script ) )
31- : [ ] ;
32- const extraPlugins : any [ ] = [ ] ;
33-
34- let entry : { [ key : string ] : string [ ] } = {
27+
28+ let extraPlugins : any [ ] = [ ] ;
29+ let extraRules : any [ ] = [ ] ;
30+ let lazyChunks : string [ ] = [ ] ;
31+
32+ let entryPoints : { [ key : string ] : string [ ] } = {
3533 main : [ appMain ]
3634 } ;
3735
38- // Only add styles/scripts if there's actually entries there
39- if ( appConfig . styles . length > 0 ) { entry [ 'styles' ] = styles ; }
40- if ( appConfig . scripts . length > 0 ) { entry [ 'scripts' ] = scripts ; }
36+ // process global scripts
37+ if ( appConfig . scripts . length > 0 ) {
38+ const globalScrips = extraEntryParser ( appConfig . scripts , appRoot , 'scripts' ) ;
39+
40+ // add entry points and lazy chunks
41+ globalScrips . forEach ( script => {
42+ if ( script . lazy ) { lazyChunks . push ( script . entry ) ; }
43+ entryPoints [ script . entry ] = ( entryPoints [ script . entry ] || [ ] ) . concat ( script . path ) ;
44+ } ) ;
45+
46+ // load global scripts using script-loader
47+ extraRules . push ( {
48+ include : globalScrips . map ( ( script ) => script . path ) , test : / \. j s $ / , loader : 'script-loader'
49+ } ) ;
50+ }
51+
52+ // process global styles
53+ if ( appConfig . styles . length === 0 ) {
54+ // create css loaders for component css
55+ extraRules . push ( ...makeCssLoaders ( ) ) ;
56+ } else {
57+ const globalStyles = extraEntryParser ( appConfig . styles , appRoot , 'styles' ) ;
58+ let extractedCssEntryPoints : string [ ] = [ ] ;
59+ // add entry points and lazy chunks
60+ globalStyles . forEach ( style => {
61+ if ( style . lazy ) { lazyChunks . push ( style . entry ) ; }
62+ if ( ! entryPoints [ style . entry ] ) {
63+ // since this entry point doesn't exist yet, it's going to only have
64+ // extracted css and we can supress the entry point
65+ extractedCssEntryPoints . push ( style . entry ) ;
66+ entryPoints [ style . entry ] = ( entryPoints [ style . entry ] || [ ] ) . concat ( style . path ) ;
67+ } else {
68+ // existing entry point, just push the css in
69+ entryPoints [ style . entry ] . push ( style . path ) ;
70+ }
71+ } ) ;
72+
73+ // create css loaders for component css and for global css
74+ extraRules . push ( ...makeCssLoaders ( globalStyles . map ( ( style ) => style . path ) ) ) ;
75+
76+ if ( extractedCssEntryPoints . length > 0 ) {
77+ // don't emit the .js entry point for extracted styles
78+ extraPlugins . push ( new SuppressEntryChunksWebpackPlugin ( { chunks : extractedCssEntryPoints } ) ) ;
79+ }
80+ }
4181
4282 if ( vendorChunk ) {
4383 extraPlugins . push ( new webpack . optimize . CommonsChunkPlugin ( {
@@ -47,12 +87,7 @@ export function getWebpackCommonConfig(
4787 } ) ) ;
4888 }
4989
50- if ( progress ) {
51- extraPlugins . push ( new ProgressPlugin ( {
52- profile : verbose ,
53- colors : true
54- } ) ) ;
55- }
90+ if ( progress ) { extraPlugins . push ( new ProgressPlugin ( { profile : verbose , colors : true } ) ) ; }
5691
5792 return {
5893 devtool : sourcemap ? 'source-map' : false ,
@@ -61,10 +96,10 @@ export function getWebpackCommonConfig(
6196 modules : [ nodeModules ] ,
6297 } ,
6398 resolveLoader : {
64- modules : [ path . resolve ( projectRoot , 'node_modules' ) ]
99+ modules : [ nodeModules ]
65100 } ,
66101 context : projectRoot ,
67- entry : entry ,
102+ entry : entryPoints ,
68103 output : {
69104 path : path . resolve ( projectRoot , appConfig . outDir ) ,
70105 filename : '[name].bundle.js' ,
@@ -73,48 +108,22 @@ export function getWebpackCommonConfig(
73108 } ,
74109 module : {
75110 rules : [
76- {
77- enforce : 'pre' ,
78- test : / \. j s $ / ,
79- loader : 'source-map-loader' ,
80- exclude : [ nodeModules ]
81- } ,
82- // in main, load css as raw text
83- {
84- exclude : styles ,
85- test : / \. c s s $ / ,
86- loaders : [ 'raw-loader' , 'postcss-loader' ]
87- } , {
88- exclude : styles ,
89- test : / \. s t y l $ / ,
90- loaders : [ 'raw-loader' , 'postcss-loader' , 'stylus-loader' ] } ,
91- {
92- exclude : styles ,
93- test : / \. l e s s $ / ,
94- loaders : [ 'raw-loader' , 'postcss-loader' , 'less-loader' ]
95- } , {
96- exclude : styles ,
97- test : / \. s c s s $ | \. s a s s $ / ,
98- loaders : [ 'raw-loader' , 'postcss-loader' , 'sass-loader' ]
99- } ,
100-
101-
102- // load global scripts using script-loader
103- { include : scripts , test : / \. j s $ / , loader : 'script-loader' } ,
111+ { enforce : 'pre' , test : / \. j s $ / , loader : 'source-map-loader' , exclude : [ nodeModules ] } ,
104112
105- { test : / \. j s o n $ / , loader : 'json-loader' } ,
106- { test : / \. ( j p g | p n g | g i f ) $ / , loader : 'url-loader?limit=10000' } ,
107- { test : / \. h t m l $ / , loader : 'raw-loader' } ,
113+ { test : / \. j s o n $ / , loader : 'json-loader' } ,
114+ { test : / \. ( j p g | p n g | g i f ) $ / , loader : 'url-loader?limit=10000' } ,
115+ { test : / \. h t m l $ / , loader : 'raw-loader' } ,
108116
109117 { test : / \. ( o t f | t t f | w o f f | w o f f 2 ) $ / , loader : 'url-loader?limit=10000' } ,
110118 { test : / \. ( e o t | s v g ) $ / , loader : 'file-loader' }
111- ]
119+ ] . concat ( extraRules )
112120 } ,
113121 plugins : [
114122 new HtmlWebpackPlugin ( {
115123 template : path . resolve ( appRoot , appConfig . index ) ,
116124 filename : path . resolve ( appConfig . outDir , appConfig . index ) ,
117- chunksSortMode : packageChunkSort ( [ 'inline' , 'styles' , 'scripts' , 'vendor' , 'main' ] )
125+ chunksSortMode : packageChunkSort ( [ 'inline' , 'styles' , 'scripts' , 'vendor' , 'main' ] ) ,
126+ excludeChunks : lazyChunks
118127 } ) ,
119128 new BaseHrefWebpackPlugin ( {
120129 baseHref : baseHref
@@ -133,12 +142,18 @@ export function getWebpackCommonConfig(
133142 } ) ,
134143 new GlobCopyWebpackPlugin ( {
135144 patterns : appConfig . assets ,
136- globOptions : { cwd : appRoot , dot : true , ignore : '**/.gitkeep' }
145+ globOptions : { cwd : appRoot , dot : true , ignore : '**/.gitkeep' }
137146 } ) ,
138147 new webpack . LoaderOptionsPlugin ( {
139148 test : / \. ( c s s | s c s s | s a s s | l e s s | s t y l ) $ / ,
140149 options : {
141- postcss : [ autoprefixer ( ) ]
150+ postcss : [ autoprefixer ( ) ] ,
151+ cssLoader : { sourceMap : sourcemap } ,
152+ sassLoader : { sourceMap : sourcemap } ,
153+ lessLoader : { sourceMap : sourcemap } ,
154+ stylusLoader : { sourceMap : sourcemap } ,
155+ // context needed as a workaround https://github.com/jtangelder/sass-loader/issues/285
156+ context : projectRoot ,
142157 } ,
143158 } )
144159 ] . concat ( extraPlugins ) ,
0 commit comments