1
1
import * as webpack from 'webpack' ;
2
2
import * 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' ;
6
8
7
- const ProgressPlugin = require ( 'webpack/lib/ProgressPlugin' ) ;
9
+ const autoprefixer = require ( 'autoprefixer' ) ;
10
+ const ProgressPlugin = require ( 'webpack/lib/ProgressPlugin' ) ;
8
11
const HtmlWebpackPlugin = require ( 'html-webpack-plugin' ) ;
9
12
const SilentError = require ( 'silent-error' ) ;
10
13
@@ -14,21 +17,12 @@ const SilentError = require('silent-error');
14
17
*
15
18
* require('source-map-loader')
16
19
* require('raw-loader')
17
- * require('postcss-loader')
18
- * require('stylus-loader')
19
- * require('less-loader')
20
- * require('sass-loader')
21
20
* require('script-loader')
22
21
* require('json-loader')
23
22
* require('url-loader')
24
23
* require('file-loader')
25
- *
26
- * require('node-sass')
27
- * require('less')
28
- * require('stylus')
29
24
*/
30
25
31
-
32
26
export function getWebpackCommonConfig (
33
27
projectRoot : string ,
34
28
environment : string ,
@@ -43,25 +37,64 @@ export function getWebpackCommonConfig(
43
37
const appRoot = path . resolve ( projectRoot , appConfig . root ) ;
44
38
const appMain = path . resolve ( appRoot , appConfig . main ) ;
45
39
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 [ ] } = {
55
46
main : [ appMain ]
56
47
} ;
57
48
58
49
if ( ! ( environment in appConfig . environments ) ) {
59
50
throw new SilentError ( `Environment "${ environment } " does not exist.` ) ;
60
51
}
61
52
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
+ }
65
98
66
99
if ( vendorChunk ) {
67
100
extraPlugins . push ( new webpack . optimize . CommonsChunkPlugin ( {
@@ -71,12 +104,7 @@ export function getWebpackCommonConfig(
71
104
} ) ) ;
72
105
}
73
106
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 } ) ) ; }
80
108
81
109
return {
82
110
devtool : sourcemap ? 'source-map' : false ,
@@ -85,10 +113,10 @@ export function getWebpackCommonConfig(
85
113
modules : [ nodeModules ] ,
86
114
} ,
87
115
resolveLoader : {
88
- modules : [ path . resolve ( projectRoot , 'node_modules' ) ]
116
+ modules : [ nodeModules ]
89
117
} ,
90
118
context : projectRoot ,
91
- entry : entry ,
119
+ entry : entryPoints ,
92
120
output : {
93
121
path : path . resolve ( projectRoot , appConfig . outDir ) ,
94
122
filename : '[name].bundle.js' ,
@@ -97,48 +125,22 @@ export function getWebpackCommonConfig(
97
125
} ,
98
126
module : {
99
127
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 ] } ,
128
129
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' } ,
132
133
133
134
{ test : / \. ( o t f | t t f | w o f f | w o f f 2 ) $ / , loader : 'url-loader?limit=10000' } ,
134
135
{ test : / \. ( e o t | s v g ) $ / , loader : 'file-loader' }
135
- ]
136
+ ] . concat ( extraRules )
136
137
} ,
137
138
plugins : [
138
139
new HtmlWebpackPlugin ( {
139
140
template : path . resolve ( appRoot , appConfig . index ) ,
140
141
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
142
144
} ) ,
143
145
new BaseHrefWebpackPlugin ( {
144
146
baseHref : baseHref
@@ -157,14 +159,18 @@ export function getWebpackCommonConfig(
157
159
} ) ,
158
160
new GlobCopyWebpackPlugin ( {
159
161
patterns : appConfig . assets ,
160
- globOptions : { cwd : appRoot , dot : true , ignore : '**/.gitkeep' }
162
+ globOptions : { cwd : appRoot , dot : true , ignore : '**/.gitkeep' }
161
163
} ) ,
162
164
new webpack . LoaderOptionsPlugin ( {
163
165
test : / \. ( c s s | s c s s | s a s s | l e s s | s t y l ) $ / ,
164
166
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 ,
168
174
} ,
169
175
} )
170
176
] . concat ( extraPlugins ) ,
0 commit comments