blob: b82bbb98ee35055e74f8754fef5bb7c7216d37b4 [file] [log] [blame]
Ed Tanousbbcf6702017-10-06 13:53:06 -07001'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');
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070013var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
Ed Tanousbbcf6702017-10-06 13:53:06 -070014
15/**
16 * Env
17 * Get npm lifecycle event to identify the environment
18 */
19var ENV = process.env.npm_lifecycle_event;
20var isTest = ENV === 'test' || ENV === 'test-watch';
21var isProd = ENV === 'build';
22
Andrew Geisslerd27bb132018-05-24 11:07:27 -070023module.exports = [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 = {};
Ed Tanousbbcf6702017-10-06 13:53:06 -070030
Andrew Geisslerd27bb132018-05-24 11:07:27 -070031 /**
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'
Ed Tanousbbcf6702017-10-06 13:53:06 -070039
Andrew Geisslerd27bb132018-05-24 11:07:27 -070040 };
Ed Tanousbbcf6702017-10-06 13:53:06 -070041
Andrew Geisslerd27bb132018-05-24 11:07:27 -070042 /**
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',
Ed Tanousbbcf6702017-10-06 13:53:06 -070051
Andrew Geisslerd27bb132018-05-24 11:07:27 -070052 // Output path from the view of the page
53 // Uses webpack-dev-server in development
54 publicPath: '/',
Ed Tanousbbcf6702017-10-06 13:53:06 -070055
Andrew Geisslerd27bb132018-05-24 11:07:27 -070056 // Filename for entry points
57 // Only adds hash in build mode
58 filename: isProd ? '[name].[hash].js' : '[name].bundle.js',
Ed Tanousbbcf6702017-10-06 13:53:06 -070059
Andrew Geisslerd27bb132018-05-24 11:07:27 -070060 // Filename for non-entry points
61 // Only adds hash in build mode
62 chunkFilename: isProd ? '[name].[hash].js' : '[name].bundle.js'
63 };
Ed Tanousbbcf6702017-10-06 13:53:06 -070064
Andrew Geisslerd27bb132018-05-24 11:07:27 -070065 /**
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:
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070072 // unix.stackexchange.com/questions/144208/find-files-without-extension
73 config.devtool = 'inline-source-map';
Andrew Geisslerd27bb132018-05-24 11:07:27 -070074 } else if (isProd) {
75 config.devtool = 'source-map';
76 } else {
77 config.devtool = 'eval-source-map';
78 }
Ed Tanousbbcf6702017-10-06 13:53:06 -070079
Andrew Geisslerd27bb132018-05-24 11:07:27 -070080 /**
81 * Loaders
82 * Reference:
83 * http://webpack.github.io/docs/configuration.html#module-loaders
84 * List: http://webpack.github.io/docs/list-of-loaders.html
85 * This handles most of the magic responsible for converting modules
86 */
Ed Tanousbbcf6702017-10-06 13:53:06 -070087
Andrew Geisslerd27bb132018-05-24 11:07:27 -070088 // Initialize module
89 config.module = {
90 rules: [
91 {
92 // JS LOADER
93 // Reference: https://github.com/babel/babel-loader
94 // Transpile .js files using babel-loader
95 // Compiles ES6 and ES7 into ES5 code
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070096 test: /\.js$/,
Andrew Geisslerd27bb132018-05-24 11:07:27 -070097 use: 'babel-loader',
98 exclude: /node_modules/
99 },
100 {
101 // CSS LOADER
102 // Reference: https://github.com/webpack/css-loader
103 // Allow loading css through js
104 //
105 // Reference: https://github.com/postcss/postcss-loader
106 // Postprocess your css with PostCSS plugins
107 test: /\.css$/,
108 // Reference: https://github.com/webpack/extract-text-webpack-plugin
109 // Extract css files in production builds
110 //
111 // Reference: https://github.com/webpack/style-loader
112 // Use style-loader in development.
Ed Tanousbbcf6702017-10-06 13:53:06 -0700113
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700114 loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({
115 fallback: 'style-loader',
116 use: [
117 {loader: 'css-loader', query: {sourceMap: true}},
118 {loader: 'postcss-loader'}
119 ],
120 })
121 },
122 {
123 // ASSET LOADER
124 // Reference: https://github.com/webpack/file-loader
125 // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to
126 // output
127 // Rename the file using the asset hash
128 // Pass along the updated reference to your code
129 // You can add here any file extension you want to get copied to your
130 // output
131 test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
132 loader: 'file-loader',
133 options: {
134 name(file) {
135 if (!isProd) {
136 return '[path][name].[ext]';
137 }
Ed Tanousbbcf6702017-10-06 13:53:06 -0700138
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700139 return '[hash].[ext]';
140 }
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700141 }
142 },
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700143 {
144 // HTML LOADER
145 // Reference: https://github.com/webpack/raw-loader
146 // Allow loading html through js
147 test: /\.html$/,
148 use: {loader: 'html-loader'}
149 },
150 // JSON LOADER
151 {test: /\.json$/, loader: 'json-loader'}, {
152 test: /\.scss$/,
153 use: [
154 {
155 loader: 'style-loader' // creates style nodes from JS strings
156 },
157 {
158 loader: 'css-loader' // translates CSS into CommonJS
159 },
160 {
161 loader: 'sass-loader' // compiles Sass to CSS
162 }
163 ]
164 }
165 ]
166 };
Ed Tanousbbcf6702017-10-06 13:53:06 -0700167
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700168 // ISTANBUL LOADER
169 // https://github.com/deepsweet/istanbul-instrumenter-loader
170 // Instrument JS files with istanbul-lib-instrument for subsequent code
171 // coverage reporting
172 // Skips node_modules and files that end with .spec.js
173 if (isTest) {
174 config.module.rules.push({
175 enforce: 'pre',
176 test: /\.js$/,
177 exclude: [/node_modules/, /\.spec\.js$/],
178 loader: 'istanbul-instrumenter-loader',
179 query: {esModules: true}
180 });
181 }
182
183 /**
184 * PostCSS
185 * Reference: https://github.com/postcss/autoprefixer-core
186 * Add vendor prefixes to your css
187 */
188 // NOTE: This is now handled in the `postcss.config.js`
189 // webpack2 has some issues, making the config file necessary
190
191 /**
192 * Plugins
193 * Reference: http://webpack.github.io/docs/configuration.html#plugins
194 * List: http://webpack.github.io/docs/list-of-plugins.html
195 */
196 config.plugins = [new webpack.LoaderOptionsPlugin({
197 test: /\.scss$/i,
198 options: {postcss: {plugins: [autoprefixer]}},
199 debug: !isProd
200 })];
201
202 // Skip rendering index.html in test mode
203 if (!isTest) {
204 // Reference: https://github.com/ampedandwired/html-webpack-plugin
205 // Render index.html
206 config.plugins.push(
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700207 new HtmlWebpackPlugin({
208 template: './app/index.html',
209 inject: 'body',
210 favicon: './app/assets/images/favicon.ico'
211 }),
Ed Tanousbbcf6702017-10-06 13:53:06 -0700212
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700213 // Reference: https://github.com/webpack/extract-text-webpack-plugin
214 // Extract css files
215 // Disabled when in test mode or not in build mode
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700216 new ExtractTextPlugin(
217 {filename: 'css/[name].css', disable: !isProd, allChunks: true}));
218 }
Ed Tanousbbcf6702017-10-06 13:53:06 -0700219
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700220 // Add build specific plugins
221 if (isProd) {
222 config.plugins.push(
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700223 // Reference:
224 // http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
225 // Minify all javascript, switch loaders to minimizing mode
226 // TODO: openbmc/openbmc#2871 Mangling currently breaks the GUI.
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700227 new UglifyJsPlugin({uglifyOptions: {mangle: false}}),
Ed Tanousbbcf6702017-10-06 13:53:06 -0700228
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700229 // Copy assets from the public folder
230 // Reference: https://github.com/kevlened/copy-webpack-plugin
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700231 new CopyWebpackPlugin([{from: __dirname + '/app/assets'}]),
232 new CompressionPlugin({deleteOriginalAssets: true}));
233 }
Ed Tanousbbcf6702017-10-06 13:53:06 -0700234
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700235 /**
236 * Dev server configuration
237 * Reference: http://webpack.github.io/docs/configuration.html#devserver
238 * Reference: http://webpack.github.io/docs/webpack-dev-server.html
239 */
240 config.devServer = {contentBase: './src/public', stats: 'minimal'};
Ed Tanousbbcf6702017-10-06 13:53:06 -0700241
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700242 return config;
243}()];