11// webpack.config.js
2+ const CleanWebpackPlugin = require ( 'clean-webpack-plugin' ) ;
23const 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+ ] ;
361
462module . exports = {
563 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' ,
867 } ,
968 output : {
10- path : ` ${ process . cwd ( ) } /dist/ styleguide/js` ,
69+ path : path . resolve ( process . cwd ( ) , ` ${ config . buildDir } / styleguide` ) ,
1170 filename : '[name].js' ,
1271 chunkFilename : `[name]-chunk-[chunkhash].js` ,
1372 } ,
1473 module : {
1574 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+ } ,
1691 {
1792 test : / \. j s $ / ,
1893 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 = {
2398 } ,
2499 } ,
25100 } ,
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+ } ,
26118 ] ,
27119 } ,
28120 cache : true ,
29- mode : 'production' ,
121+ mode : config . prod ? 'production' : 'development ',
30122 optimization : {
31123 mergeDuplicateChunks : true ,
32124 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+ : [ ] ,
48142 } ,
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+ ] ,
50183} ;
0 commit comments