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'); 13var UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 14 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 23module.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 = {}; 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 } else if (isProd) { 75 config.devtool = 'source-map'; 76 } else { 77 config.devtool = 'eval-source-map'; 78 } 79 80 /** 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 */ 87 88 // 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 96 test: /\.js$/, 97 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. 113 114 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 } 138 139 return '[hash].[ext]'; 140 } 141 } 142 }, 143 { 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 }; 167 168 // 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( 207 new HtmlWebpackPlugin({ 208 template: './app/index.html', 209 inject: 'body', 210 favicon: './app/assets/images/favicon.ico' 211 }), 212 213 // Reference: https://github.com/webpack/extract-text-webpack-plugin 214 // Extract css files 215 // Disabled when in test mode or not in build mode 216 new ExtractTextPlugin( 217 {filename: 'css/[name].css', disable: !isProd, allChunks: true})); 218 } 219 220 // Add build specific plugins 221 if (isProd) { 222 config.plugins.push( 223 // Reference: 224 // http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin 225 // Minify all javascript, switch loaders to minimizing mode 226 new UglifyJsPlugin(), 227 228 // Copy assets from the public folder 229 // Reference: https://github.com/kevlened/copy-webpack-plugin 230 new CopyWebpackPlugin([{from: __dirname + '/app/assets'}]), 231 new CompressionPlugin({deleteOriginalAssets: true})); 232 } 233 234 /** 235 * Dev server configuration 236 * Reference: http://webpack.github.io/docs/configuration.html#devserver 237 * Reference: http://webpack.github.io/docs/webpack-dev-server.html 238 */ 239 config.devServer = {contentBase: './src/public', stats: 'minimal'}; 240 241 return config; 242}()]; 243