1'use strict'; 2 3// OpenSSL 3 does not support md4, webpack 4 hardcodes md4 in many places 4// https://github.com/webpack/webpack/issues/13572#issuecomment-923736472 5// As the issue suggests we should update to webpack 5, doing so requires a lot 6// of changes. TODO: Remove after updating to webpack v5.54.0+ 7const crypto = require('crypto'); 8const crypto_orig_createHash = crypto.createHash; 9crypto.createHash = algorithm => 10 crypto_orig_createHash(algorithm == 'md4' ? 'sha256' : algorithm); 11 12// Modules 13var webpack = require('webpack'); 14var autoprefixer = require('autoprefixer'); 15var HtmlWebpackInlineSourcePlugin = 16 require('html-webpack-inline-source-plugin'); 17var HtmlWebpackPlugin = require('html-webpack-plugin'); 18var CopyWebpackPlugin = require('copy-webpack-plugin'); 19var CompressionPlugin = require('compression-webpack-plugin'); 20var path = require('path'); 21var FilterChunkWebpackPlugin = require('filter-chunk-webpack-plugin'); 22var MiniCssExtractPlugin = require('mini-css-extract-plugin'); 23 24const isPathInside = require('is-path-inside') 25const pkgDir = require('pkg-dir') 26const coreJsDir = pkgDir.sync(require.resolve('core-js')) 27 28module.exports = (env, options) => { 29 var isProd = options.mode === 'production'; 30 31 /** 32 * Config 33 * Reference: http://webpack.github.io/docs/configuration.html 34 * This is the object where all configuration gets set 35 */ 36 var config = {}; 37 38 /** 39 * Entry 40 * Reference: http://webpack.github.io/docs/configuration.html#entry 41 * Should be an empty object if it's generating a test build 42 * Karma will set this when it's a test build 43 */ 44 config.entry = {app: './app/index.js'}; 45 46 /** 47 * Output 48 * Reference: http://webpack.github.io/docs/configuration.html#output 49 * Should be an empty object if it's generating a test build 50 * Karma will handle setting it up for you when it's a test build 51 */ 52 config.output = { 53 // Absolute output directory 54 path: __dirname + '/dist', 55 56 // Output path from the view of the page 57 // Uses webpack-dev-server in development 58 publicPath: '/', 59 60 // Filename for entry points 61 // Only adds hash in build mode 62 filename: '[name].bundle.js', 63 64 // Filename for non-entry points 65 // Only adds hash in build mode 66 chunkFilename: '[name].bundle.js' 67 }; 68 69 /** 70 * Loaders 71 * Reference: 72 * http://webpack.github.io/docs/configuration.html#module-loaders 73 * List: http://webpack.github.io/docs/list-of-loaders.html 74 * This handles most of the magic responsible for converting modules 75 */ 76 77 // Initialize module 78 config.module = { 79 rules: [ 80 { 81 // JS LOADER 82 // Reference: https://github.com/babel/babel-loader 83 // Transpile .js files using babel-loader 84 // Compiles ES6 and ES7 into ES5 code 85 test: /\.js$/, 86 exclude: (input) => isPathInside(input, coreJsDir), 87 use: { 88 loader: 'babel-loader', 89 options: { 90 presets: [['@babel/preset-env', {useBuiltIns: 'entry', corejs: 3}]] 91 } 92 } 93 }, 94 { 95 // ASSET LOADER 96 // Reference: https://github.com/webpack/file-loader 97 // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to 98 // output 99 // Rename the file using the asset hash 100 // Pass along the updated reference to your code 101 // You can add here any file extension you want to get copied 102 // to your output 103 // Excludes .svg files in icons directory 104 test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/, 105 exclude: /icons\/.*\.svg$/, 106 loader: 'file-loader', 107 options: {name: '[path][name].[ext]'} 108 }, 109 { 110 // INLINE SVG LOADER 111 // Inlines .svg assets in icons directory 112 // needed specifically for icon-provider.js directive 113 test: /icons\/.*\.svg$/, 114 loader: 'svg-inline-loader' 115 }, 116 { 117 // HTML LOADER 118 // Reference: https://github.com/webpack/raw-loader 119 // Allow loading html through js 120 test: /\.html$/, 121 loader: 'html-loader' 122 }, 123 { 124 test: /\.css$/, 125 use: [MiniCssExtractPlugin.loader, 'css-loader'], 126 }, 127 { 128 test: /\.scss$/, 129 use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'] 130 } 131 ] 132 }; 133 134 config.plugins = [ 135 new HtmlWebpackPlugin({ 136 template: './app/index.html', 137 inject: 'body', 138 favicon: './app/assets/images/favicon.ico', 139 minify: {removeComments: true, collapseWhitespace: true}, 140 141 }), 142 new MiniCssExtractPlugin(), 143 144 new FilterChunkWebpackPlugin({ 145 patterns: [ 146 '*glyphicons-halflings-regular*.ttf', 147 '*glyphicons-halflings-regular*.svg', 148 '*glyphicons-halflings-regular*.eot', 149 '*glyphicons-halflings-regular*.woff2', 150 ] 151 }) 152 ]; 153 154 // Comment in to see per-module js sizes. This is useful in debugging "why is 155 // my binary so big" 156 /* 157 config.optimization = { 158 runtimeChunk: 'single', 159 splitChunks: { 160 chunks: 'all', 161 maxInitialRequests: Infinity, 162 minSize: 0, 163 cacheGroups: { 164 vendor: { 165 test: /[\\/]node_modules[\\/]/, 166 name(module) { 167 // get the name. E.g. node_modules/packageName/not/this/part.js 168 // or node_modules/packageName 169 const packageName = 170 module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]; 171 172 // npm package names are URL-safe, but some servers don't like @ 173 symbols return `${packageName.replace('@', '')}`; 174 }, 175 }, 176 }, 177 }, 178 }; 179 */ 180 181 // Add build specific plugins 182 if (isProd) { 183 config.plugins.push(new CompressionPlugin({deleteOriginalAssets: true})); 184 } 185 186 /** 187 * Dev server configuration 188 * Reference: http://webpack.github.io/docs/configuration.html#devserver 189 * Reference: http://webpack.github.io/docs/webpack-dev-server.html 190 */ 191 config.devServer = {contentBase: './src/public', stats: 'minimal'}; 192 193 return config; 194}; 195