blob: 2a3ce85f5240175ff9462ce23b8c5335c29d42e1 [file] [log] [blame]
Ed Tanousbbcf6702017-10-06 13:53:06 -07001'use strict';
2
Gunnar Mills85884002021-11-03 14:58:43 -05003// 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
Ed Tanousbbcf6702017-10-06 13:53:06 -070012// Modules
13var webpack = require('webpack');
14var autoprefixer = require('autoprefixer');
Ed Tanousfc7a33f2018-09-06 16:52:19 -070015var HtmlWebpackInlineSourcePlugin =
16 require('html-webpack-inline-source-plugin');
Ed Tanousbbcf6702017-10-06 13:53:06 -070017var HtmlWebpackPlugin = require('html-webpack-plugin');
Ed Tanousbbcf6702017-10-06 13:53:06 -070018var CopyWebpackPlugin = require('copy-webpack-plugin');
19var CompressionPlugin = require('compression-webpack-plugin');
Ed Tanousbbcf6702017-10-06 13:53:06 -070020var path = require('path');
Ed Tanousfc7a33f2018-09-06 16:52:19 -070021var FilterChunkWebpackPlugin = require('filter-chunk-webpack-plugin');
22var MiniCssExtractPlugin = require('mini-css-extract-plugin');
Ed Tanousbbcf6702017-10-06 13:53:06 -070023
Ed Tanousdc25db02019-07-31 16:42:11 -070024const isPathInside = require('is-path-inside')
25const pkgDir = require('pkg-dir')
26const coreJsDir = pkgDir.sync(require.resolve('core-js'))
27
Ed Tanousfc7a33f2018-09-06 16:52:19 -070028module.exports = (env, options) => {
29 var isProd = options.mode === 'production';
Ed Tanousbbcf6702017-10-06 13:53:06 -070030
Andrew Geisslerd27bb132018-05-24 11:07:27 -070031 /**
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 = {};
Ed Tanousbbcf6702017-10-06 13:53:06 -070037
Andrew Geisslerd27bb132018-05-24 11:07:27 -070038 /**
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 */
Ed Tanousfc7a33f2018-09-06 16:52:19 -070044 config.entry = {app: './app/index.js'};
Ed Tanousbbcf6702017-10-06 13:53:06 -070045
Andrew Geisslerd27bb132018-05-24 11:07:27 -070046 /**
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 */
Ed Tanousfc7a33f2018-09-06 16:52:19 -070052 config.output = {
Andrew Geisslerd27bb132018-05-24 11:07:27 -070053 // Absolute output directory
54 path: __dirname + '/dist',
Ed Tanousbbcf6702017-10-06 13:53:06 -070055
Andrew Geisslerd27bb132018-05-24 11:07:27 -070056 // Output path from the view of the page
57 // Uses webpack-dev-server in development
58 publicPath: '/',
Ed Tanousbbcf6702017-10-06 13:53:06 -070059
Andrew Geisslerd27bb132018-05-24 11:07:27 -070060 // Filename for entry points
61 // Only adds hash in build mode
Ed Tanousfc7a33f2018-09-06 16:52:19 -070062 filename: '[name].bundle.js',
Ed Tanousbbcf6702017-10-06 13:53:06 -070063
Andrew Geisslerd27bb132018-05-24 11:07:27 -070064 // Filename for non-entry points
65 // Only adds hash in build mode
Ed Tanousfc7a33f2018-09-06 16:52:19 -070066 chunkFilename: '[name].bundle.js'
Andrew Geisslerd27bb132018-05-24 11:07:27 -070067 };
Ed Tanousbbcf6702017-10-06 13:53:06 -070068
Andrew Geisslerd27bb132018-05-24 11:07:27 -070069 /**
Andrew Geisslerd27bb132018-05-24 11:07:27 -070070 * 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 */
Ed Tanousbbcf6702017-10-06 13:53:06 -070076
Andrew Geisslerd27bb132018-05-24 11:07:27 -070077 // 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
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070085 test: /\.js$/,
Ed Tanousdc25db02019-07-31 16:42:11 -070086 exclude: (input) => isPathInside(input, coreJsDir),
87 use: {
88 loader: 'babel-loader',
89 options: {
90 presets: [['@babel/preset-env', {useBuiltIns: 'entry', corejs: 3}]]
91 }
92 }
Andrew Geisslerd27bb132018-05-24 11:07:27 -070093 },
Ed Tanous0f2f9812018-12-19 17:59:28 -080094 {
Andrew Geisslerd27bb132018-05-24 11:07:27 -070095 // 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
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -0500101 // You can add here any file extension you want to get copied
102 // to your output
103 // Excludes .svg files in icons directory
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700104 test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -0500105 exclude: /icons\/.*\.svg$/,
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700106 loader: 'file-loader',
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700107 options: {name: '[path][name].[ext]'}
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700108 },
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700109 {
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -0500110 // 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 {
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700117 // HTML LOADER
118 // Reference: https://github.com/webpack/raw-loader
119 // Allow loading html through js
120 test: /\.html$/,
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700121 loader: 'html-loader'
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700122 },
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -0500123 {
124 test: /\.css$/,
125 use: [MiniCssExtractPlugin.loader, 'css-loader'],
126 },
127 {
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700128 test: /\.scss$/,
Ed Tanous0f2f9812018-12-19 17:59:28 -0800129 use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700130 }
131 ]
132 };
Ed Tanousbbcf6702017-10-06 13:53:06 -0700133
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700134 config.plugins = [
135 new HtmlWebpackPlugin({
136 template: './app/index.html',
137 inject: 'body',
138 favicon: './app/assets/images/favicon.ico',
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700139 minify: {removeComments: true, collapseWhitespace: true},
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700140
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700141 }),
Ed Tanous0f2f9812018-12-19 17:59:28 -0800142 new MiniCssExtractPlugin(),
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700143
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700144 new FilterChunkWebpackPlugin({
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700145 patterns: [
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700146 '*glyphicons-halflings-regular*.ttf',
147 '*glyphicons-halflings-regular*.svg',
148 '*glyphicons-halflings-regular*.eot',
149 '*glyphicons-halflings-regular*.woff2',
150 ]
151 })
152 ];
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700153
Ed Tanousd8713592020-07-16 07:33:07 -0700154 // 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
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700181 // Add build specific plugins
182 if (isProd) {
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700183 config.plugins.push(new CompressionPlugin({deleteOriginalAssets: true}));
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700184 }
Ed Tanousbbcf6702017-10-06 13:53:06 -0700185
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700186 /**
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'};
Ed Tanousbbcf6702017-10-06 13:53:06 -0700192
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700193 return config;
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700194};