1'use strict';
2
3// Modules
4var webpack = require('webpack');
5var autoprefixer = require('autoprefixer');
6var HtmlWebpackPlugin = require('html-webpack-plugin');
7var ExtractTextPlugin = require('extract-text-webpack-plugin');
8var CopyWebpackPlugin = require('copy-webpack-plugin');
9var CompressionPlugin = require('compression-webpack-plugin');
10var AssetsPlugin = require('assets-webpack-plugin');
11var CopyWebpackPlugin = require('copy-webpack-plugin');
12var path = require('path');
13
14/**
15 * Env
16 * Get npm lifecycle event to identify the environment
17 */
18var ENV = process.env.npm_lifecycle_event;
19var isTest = ENV === 'test' || ENV === 'test-watch';
20var isProd = ENV === 'build';
21
22module.exports = [
23  function makeWebpackConfig() {
24    /**
25     * Config
26     * Reference: http://webpack.github.io/docs/configuration.html
27     * This is the object where all configuration gets set
28     */
29    var config = {};
30
31    /**
32     * Entry
33     * Reference: http://webpack.github.io/docs/configuration.html#entry
34     * Should be an empty object if it's generating a test build
35     * Karma will set this when it's a test build
36     */
37    config.entry = isTest ? void 0 : {
38      app : './app/index.js'
39
40    };
41
42    /**
43     * Output
44     * Reference: http://webpack.github.io/docs/configuration.html#output
45     * Should be an empty object if it's generating a test build
46     * Karma will handle setting it up for you when it's a test build
47     */
48    config.output = isTest ? {} : {
49      // Absolute output directory
50      path : __dirname + '/dist',
51
52      // Output path from the view of the page
53      // Uses webpack-dev-server in development
54      publicPath : '/',
55
56      // Filename for entry points
57      // Only adds hash in build mode
58      filename : isProd ? '[name].[hash].js' : '[name].bundle.js',
59
60      // Filename for non-entry points
61      // Only adds hash in build mode
62      chunkFilename : isProd ? '[name].[hash].js' : '[name].bundle.js'
63    };
64
65    /**
66     * Devtool
67     * Reference: http://webpack.github.io/docs/configuration.html#devtool
68     * Type of sourcemap to use per build type
69     */
70    if (isTest) {
71      https:
72          // unix.stackexchange.com/questions/144208/find-files-without-extension
73          config.devtool = 'inline-source-map';
74      }
75    else if (isProd) {
76      config.devtool = 'source-map';
77      }
78    else {
79      config.devtool = 'eval-source-map';
80    }
81
82    /**
83     * Loaders
84     * Reference:
85     * http://webpack.github.io/docs/configuration.html#module-loaders
86     * List: http://webpack.github.io/docs/list-of-loaders.html
87     * This handles most of the magic responsible for converting modules
88     */
89
90    // Initialize module
91    config.module = {
92      rules : [
93        {
94          // JS LOADER
95          // Reference: https://github.com/babel/babel-loader
96          // Transpile .js files using babel-loader
97          // Compiles ES6 and ES7 into ES5 code
98          test : /\.js$/,
99          loader : 'babel-loader',
100          exclude : /node_modules/
101        },
102        {
103          // CSS LOADER
104          // Reference: https://github.com/webpack/css-loader
105          // Allow loading css through js
106          //
107          // Reference: https://github.com/postcss/postcss-loader
108          // Postprocess your css with PostCSS plugins
109          test : /\.css$/,
110          // Reference: https://github.com/webpack/extract-text-webpack-plugin
111          // Extract css files in production builds
112          //
113          // Reference: https://github.com/webpack/style-loader
114          // Use style-loader in development.
115
116          loader : isTest ? 'null-loader' : ExtractTextPlugin.extract({
117            fallback : 'style-loader',
118            use : [
119              {loader : 'css-loader', query : {sourceMap : true}},
120              {loader : 'postcss-loader'}
121            ],
122          })
123        },
124        {
125          // ASSET LOADER
126          // Reference: https://github.com/webpack/file-loader
127          // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to
128          // output
129          // Rename the file using the asset hash
130          // Pass along the updated reference to your code
131          // You can add here any file extension you want to get copied to your
132          // output
133          test : /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
134          loader : 'file-loader',
135          options : {
136            name(file) {
137              if (!isProd) {
138                return '[path][name].[ext]'
139                }
140
141              return '[hash].[ext]'
142            }
143          }
144        },
145        {
146          // HTML LOADER
147          // Reference: https://github.com/webpack/raw-loader
148          // Allow loading html through js
149          test : /\.html$/,
150          use : {loader : 'html-loader'}
151        },
152        // JSON LOADER
153        {test : /\.json$/, loader : 'json-loader'}, {
154          test : /\.scss$/,
155          use : [
156            {
157              loader : 'style-loader'  // creates style nodes from JS strings
158            },
159            {
160              loader : 'css-loader'  // translates CSS into CommonJS
161            },
162            {
163              loader : 'sass-loader'  // compiles Sass to CSS
164            }
165          ]
166        }
167      ]
168    };
169
170    // ISTANBUL LOADER
171    // https://github.com/deepsweet/istanbul-instrumenter-loader
172    // Instrument JS files with istanbul-lib-instrument for subsequent code
173    // coverage reporting
174    // Skips node_modules and files that end with .spec.js
175    if (isTest) {
176      config.module.rules.push({
177        enforce : 'pre',
178        test : /\.js$/,
179        exclude : [ /node_modules/, /\.spec\.js$/],
180        loader : 'istanbul-instrumenter-loader',
181        query : {esModules : true}
182      })
183    }
184
185    /**
186     * PostCSS
187     * Reference: https://github.com/postcss/autoprefixer-core
188     * Add vendor prefixes to your css
189     */
190    // NOTE: This is now handled in the `postcss.config.js`
191    //       webpack2 has some issues, making the config file necessary
192
193    /**
194     * Plugins
195     * Reference: http://webpack.github.io/docs/configuration.html#plugins
196     * List: http://webpack.github.io/docs/list-of-plugins.html
197     */
198    config.plugins = [ new webpack.LoaderOptionsPlugin({
199      test : /\.scss$/i,
200      options : {postcss : {plugins : [ autoprefixer ]}},
201      debug : !isProd
202    }) ];
203
204    // Skip rendering index.html in test mode
205    if (!isTest) {
206      // Reference: https://github.com/ampedandwired/html-webpack-plugin
207      // Render index.html
208      config.plugins.push(
209          new HtmlWebpackPlugin(
210              {
211                template : './app/index.html',
212                inject : 'body',
213                favicon: './app/assets/images/favicon.ico'
214              }),
215
216          // Reference: https://github.com/webpack/extract-text-webpack-plugin
217          // Extract css files
218          // Disabled when in test mode or not in build mode
219          new ExtractTextPlugin({
220            filename : 'css/[name].css',
221            disable : !isProd,
222            allChunks : true
223          }))
224      }
225
226    // Add build specific plugins
227    if (isProd) {
228      config.plugins.push(
229          // Reference:
230          // http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
231          // Minify all javascript, switch loaders to minimizing mode
232          // TODO: openbmc/openbmc#2781  Mangling currently breaks the GUI.
233          new webpack.optimize.UglifyJsPlugin({
234            mangle: false
235          }),
236
237          // Copy assets from the public folder
238          // Reference: https://github.com/kevlened/copy-webpack-plugin
239          new CopyWebpackPlugin([ {from : __dirname + '/app/assets'} ]),
240          new CompressionPlugin({deleteOriginalAssets : true}))
241    }
242
243    /**
244     * Dev server configuration
245     * Reference: http://webpack.github.io/docs/configuration.html#devserver
246     * Reference: http://webpack.github.io/docs/webpack-dev-server.html
247     */
248    config.devServer = {contentBase : './src/public', stats : 'minimal'};
249
250    return config;
251  }()];
252