1
1
// webpack.config.js
2
+ const CleanWebpackPlugin = require ( 'clean-webpack-plugin' ) ;
2
3
const UglifyJsPlugin = require ( 'uglifyjs-webpack-plugin' ) ;
4
+ const NoEmitPlugin = require ( 'no-emit-webpack-plugin' ) ;
5
+ const autoprefixer = require ( 'autoprefixer' ) ;
6
+ // const webpack = require('webpack');
7
+ const CriticalCssPlugin = require ( 'critical-css-webpack-plugin' ) ;
8
+ const HtmlWebpackPlugin = require ( 'html-webpack-plugin' ) ;
9
+ const MiniCssExtractPlugin = require ( 'mini-css-extract-plugin' ) ;
10
+ const path = require ( 'path' ) ;
11
+
12
+ // @todo : wire these two ocnfigs up to use cosmicconfig!
13
+ const config = {
14
+ buildDir : './dist' ,
15
+ prod : true , // or false for local dev
16
+ sourceMaps : true ,
17
+ } ;
18
+
19
+ // organize the series of plugins to run our Sass through as an external array -- this is necessary since we need to add additional loaders when compiling Sass to standalone CSS files vs compiling Sass and returning an inline-able <style> block of CSS (which we need to do both)
20
+ const scssLoaders = [
21
+ {
22
+ loader : 'css-loader' ,
23
+ options : {
24
+ sourceMap : config . sourceMaps ,
25
+ } ,
26
+ } ,
27
+ {
28
+ loader : 'postcss-loader' ,
29
+ options : {
30
+ sourceMap : config . sourceMaps ,
31
+ plugins : ( ) => [
32
+ autoprefixer ( {
33
+ browsers : [
34
+ 'last 2 version' ,
35
+ 'safari 5' ,
36
+ 'ie 8' ,
37
+ 'ie 9' ,
38
+ 'opera 12.1' ,
39
+ 'android 4' ,
40
+ ] ,
41
+ } ) ,
42
+ ] ,
43
+ } ,
44
+ } ,
45
+ {
46
+ loader : 'clean-css-loader' ,
47
+ options : {
48
+ compatibility : 'ie9' ,
49
+ level : 1 , // @todo : test bumping this up to 2
50
+ inline : [ 'remote' ] ,
51
+ } ,
52
+ } ,
53
+ {
54
+ loader : 'sass-loader' ,
55
+ options : {
56
+ sourceMap : config . sourceMaps ,
57
+ outputStyle : 'expanded' ,
58
+ } ,
59
+ } ,
60
+ ] ;
3
61
4
62
module . exports = {
5
63
entry : {
6
- 'patternlab-pattern' : './src/scripts/patternlab-pattern' ,
7
- 'patternlab-viewer' : './src/scripts/patternlab-viewer' ,
64
+ 'js/patternlab-pattern' : './src/scripts/patternlab-pattern.js' ,
65
+ 'js/patternlab-viewer' : './src/scripts/patternlab-viewer.js' ,
66
+ 'css/pattern-lab' : './src/sass/pattern-lab.scss' ,
8
67
} ,
9
68
output : {
10
- path : ` ${ process . cwd ( ) } /dist/ styleguide/js` ,
69
+ path : path . resolve ( process . cwd ( ) , ` ${ config . buildDir } / styleguide` ) ,
11
70
filename : '[name].js' ,
12
71
chunkFilename : `[name]-chunk-[chunkhash].js` ,
13
72
} ,
14
73
module : {
15
74
rules : [
75
+ {
76
+ test : / \. h t m l $ / ,
77
+ use : [
78
+ {
79
+ loader : 'html-loader' ,
80
+ options : {
81
+ interpolate : true ,
82
+ minimize : config . prod ? true : false ,
83
+ minifyCSS : false ,
84
+ minifyJS : config . prod ? true : false ,
85
+ // super important -- this prevents the embedded iframe srcdoc HTML from breaking!
86
+ preventAttributesEscaping : true ,
87
+ } ,
88
+ } ,
89
+ ] ,
90
+ } ,
16
91
{
17
92
test : / \. j s $ / ,
18
93
exclude : / ( n o d e _ m o d u l e s | b o w e r _ c o m p o n e n t s ) / ,
@@ -23,28 +98,86 @@ module.exports = {
23
98
} ,
24
99
} ,
25
100
} ,
101
+ {
102
+ test : / \. s c s s $ / ,
103
+ oneOf : [
104
+ {
105
+ // if .scss files are included by JS or HTML files, inline and don't spit out a file
106
+ issuer : / ( \. j s $ | \. h t m l $ ) / ,
107
+ use : [ scssLoaders ] . reduce ( ( acc , val ) => acc . concat ( val ) , [ ] ) ,
108
+ } ,
109
+ {
110
+ // otherwise extract the result and write out a .css file per usual
111
+ use : [ MiniCssExtractPlugin . loader , scssLoaders ] . reduce (
112
+ ( acc , val ) => acc . concat ( val ) ,
113
+ [ ]
114
+ ) ,
115
+ } ,
116
+ ] ,
117
+ } ,
26
118
] ,
27
119
} ,
28
120
cache : true ,
29
- mode : 'production' ,
121
+ mode : config . prod ? 'production' : 'development ',
30
122
optimization : {
31
123
mergeDuplicateChunks : true ,
32
124
concatenateModules : true ,
33
- minimizer : [
34
- new UglifyJsPlugin ( {
35
- sourceMap : true ,
36
- parallel : true ,
37
- cache : true ,
38
- uglifyOptions : {
39
- compress : true ,
40
- mangle : true ,
41
- output : {
42
- comments : false ,
43
- beautify : false ,
44
- } ,
45
- } ,
46
- } ) ,
47
- ] ,
125
+ minimizer : config . prod
126
+ ? [
127
+ new UglifyJsPlugin ( {
128
+ sourceMap : true ,
129
+ parallel : true ,
130
+ cache : true ,
131
+ uglifyOptions : {
132
+ compress : true ,
133
+ mangle : true ,
134
+ output : {
135
+ comments : false ,
136
+ beautify : false ,
137
+ } ,
138
+ } ,
139
+ } ) ,
140
+ ]
141
+ : [ ] ,
48
142
} ,
49
- plugins : [ ] ,
143
+ plugins : [
144
+ // clear out the buildDir on every fresh Webpack build
145
+ new CleanWebpackPlugin ( [ config . buildDir ] ) ,
146
+ new HtmlWebpackPlugin ( {
147
+ filename : '../index.html' ,
148
+ template : 'src/html/index.html' ,
149
+ inject : false ,
150
+ } ) ,
151
+ new MiniCssExtractPlugin ( {
152
+ filename : `[name].css` ,
153
+ chunkFilename : `[id].css` ,
154
+ allChunks : true ,
155
+ } ) ,
156
+ new NoEmitPlugin ( [ 'css/pattern-lab.js' ] ) ,
157
+ new CriticalCssPlugin ( {
158
+ base : path . resolve ( __dirname , config . buildDir ) ,
159
+ src : 'index.html' ,
160
+ dest : 'index.html' ,
161
+ inline : true ,
162
+ minify : true ,
163
+ extract : true ,
164
+ width : 1300 ,
165
+ height : 900 ,
166
+ penthouse : {
167
+ keepLargerMediaQueries : true ,
168
+
169
+ // @todo : troubleshoot why forceInclude works w/ Penthouse directly but not w/ Critical
170
+ forceInclude : [
171
+ '.pl-c-body--theme-light' ,
172
+ '.pl-c-body--theme-sidebar' ,
173
+ '.pl-c-body--theme-sidebar .pl-c-viewport' ,
174
+ '.pl-c-body--theme-density-compact' ,
175
+ ] ,
176
+ timeout : 30000 , // ms; abort critical CSS generation after this timeout
177
+ maxEmbeddedBase64Length : 1000 ,
178
+ renderWaitTime : 1000 ,
179
+ blockJSRequests : false ,
180
+ } ,
181
+ } ) ,
182
+ ] ,
50
183
} ;
0 commit comments