blob: 71b029e4e8a17ac4ae6847d39139b7577dff735a [file] [log] [blame]
Ed Tanousbbcf6702017-10-06 13:53:06 -07001'use strict';
2
3// Modules
4var webpack = require('webpack');
5var autoprefixer = require('autoprefixer');
Ed Tanousfc7a33f2018-09-06 16:52:19 -07006var HtmlWebpackInlineSourcePlugin =
7 require('html-webpack-inline-source-plugin');
Ed Tanous0f2f9812018-12-19 17:59:28 -08008var CSPWebpackPlugin = require('csp-html-webpack-plugin');
Ed Tanousbbcf6702017-10-06 13:53:06 -07009var HtmlWebpackPlugin = require('html-webpack-plugin');
Ed Tanousbbcf6702017-10-06 13:53:06 -070010var CopyWebpackPlugin = require('copy-webpack-plugin');
11var CompressionPlugin = require('compression-webpack-plugin');
Ed Tanousbbcf6702017-10-06 13:53:06 -070012var path = require('path');
Ed Tanousfc7a33f2018-09-06 16:52:19 -070013var FilterChunkWebpackPlugin = require('filter-chunk-webpack-plugin');
14var MiniCssExtractPlugin = require('mini-css-extract-plugin');
Ed Tanousbbcf6702017-10-06 13:53:06 -070015
Ed Tanousdc25db02019-07-31 16:42:11 -070016const isPathInside = require('is-path-inside')
17const pkgDir = require('pkg-dir')
18const coreJsDir = pkgDir.sync(require.resolve('core-js'))
19
Ed Tanousfc7a33f2018-09-06 16:52:19 -070020module.exports = (env, options) => {
21 var isProd = options.mode === 'production';
Ed Tanousbbcf6702017-10-06 13:53:06 -070022
Andrew Geisslerd27bb132018-05-24 11:07:27 -070023 /**
24 * Config
25 * Reference: http://webpack.github.io/docs/configuration.html
26 * This is the object where all configuration gets set
27 */
28 var config = {};
Ed Tanousbbcf6702017-10-06 13:53:06 -070029
Andrew Geisslerd27bb132018-05-24 11:07:27 -070030 /**
31 * Entry
32 * Reference: http://webpack.github.io/docs/configuration.html#entry
33 * Should be an empty object if it's generating a test build
34 * Karma will set this when it's a test build
35 */
Ed Tanousfc7a33f2018-09-06 16:52:19 -070036 config.entry = {app: './app/index.js'};
Ed Tanousbbcf6702017-10-06 13:53:06 -070037
Andrew Geisslerd27bb132018-05-24 11:07:27 -070038 /**
39 * Output
40 * Reference: http://webpack.github.io/docs/configuration.html#output
41 * Should be an empty object if it's generating a test build
42 * Karma will handle setting it up for you when it's a test build
43 */
Ed Tanousfc7a33f2018-09-06 16:52:19 -070044 config.output = {
Andrew Geisslerd27bb132018-05-24 11:07:27 -070045 // Absolute output directory
46 path: __dirname + '/dist',
Ed Tanousbbcf6702017-10-06 13:53:06 -070047
Andrew Geisslerd27bb132018-05-24 11:07:27 -070048 // Output path from the view of the page
49 // Uses webpack-dev-server in development
50 publicPath: '/',
Ed Tanousbbcf6702017-10-06 13:53:06 -070051
Andrew Geisslerd27bb132018-05-24 11:07:27 -070052 // Filename for entry points
53 // Only adds hash in build mode
Ed Tanousfc7a33f2018-09-06 16:52:19 -070054 filename: '[name].bundle.js',
Ed Tanousbbcf6702017-10-06 13:53:06 -070055
Andrew Geisslerd27bb132018-05-24 11:07:27 -070056 // Filename for non-entry points
57 // Only adds hash in build mode
Ed Tanousfc7a33f2018-09-06 16:52:19 -070058 chunkFilename: '[name].bundle.js'
Andrew Geisslerd27bb132018-05-24 11:07:27 -070059 };
Ed Tanousbbcf6702017-10-06 13:53:06 -070060
Andrew Geisslerd27bb132018-05-24 11:07:27 -070061 /**
Andrew Geisslerd27bb132018-05-24 11:07:27 -070062 * Loaders
63 * Reference:
64 * http://webpack.github.io/docs/configuration.html#module-loaders
65 * List: http://webpack.github.io/docs/list-of-loaders.html
66 * This handles most of the magic responsible for converting modules
67 */
Ed Tanousbbcf6702017-10-06 13:53:06 -070068
Andrew Geisslerd27bb132018-05-24 11:07:27 -070069 // Initialize module
70 config.module = {
71 rules: [
72 {
73 // JS LOADER
74 // Reference: https://github.com/babel/babel-loader
75 // Transpile .js files using babel-loader
76 // Compiles ES6 and ES7 into ES5 code
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070077 test: /\.js$/,
Ed Tanousdc25db02019-07-31 16:42:11 -070078 exclude: (input) => isPathInside(input, coreJsDir),
79 use: {
80 loader: 'babel-loader',
81 options: {
82 presets: [['@babel/preset-env', {useBuiltIns: 'entry', corejs: 3}]]
83 }
84 }
Andrew Geisslerd27bb132018-05-24 11:07:27 -070085 },
Ed Tanous0f2f9812018-12-19 17:59:28 -080086 {
Andrew Geisslerd27bb132018-05-24 11:07:27 -070087 // ASSET LOADER
88 // Reference: https://github.com/webpack/file-loader
89 // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to
90 // output
91 // Rename the file using the asset hash
92 // Pass along the updated reference to your code
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -050093 // You can add here any file extension you want to get copied
94 // to your output
95 // Excludes .svg files in icons directory
Andrew Geisslerd27bb132018-05-24 11:07:27 -070096 test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -050097 exclude: /icons\/.*\.svg$/,
Andrew Geisslerd27bb132018-05-24 11:07:27 -070098 loader: 'file-loader',
Ed Tanousfc7a33f2018-09-06 16:52:19 -070099 options: {name: '[path][name].[ext]'}
Andrew Geisslerba5e3f32018-05-24 10:58:00 -0700100 },
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700101 {
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -0500102 // INLINE SVG LOADER
103 // Inlines .svg assets in icons directory
104 // needed specifically for icon-provider.js directive
105 test: /icons\/.*\.svg$/,
106 loader: 'svg-inline-loader'
107 },
108 {
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700109 // HTML LOADER
110 // Reference: https://github.com/webpack/raw-loader
111 // Allow loading html through js
112 test: /\.html$/,
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700113 loader: 'html-loader'
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700114 },
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -0500115 {
116 test: /\.css$/,
117 use: [MiniCssExtractPlugin.loader, 'css-loader'],
118 },
119 {
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700120 test: /\.scss$/,
Ed Tanous0f2f9812018-12-19 17:59:28 -0800121 use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700122 }
123 ]
124 };
Ed Tanousbbcf6702017-10-06 13:53:06 -0700125
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700126 config.plugins = [
127 new HtmlWebpackPlugin({
128 template: './app/index.html',
129 inject: 'body',
130 favicon: './app/assets/images/favicon.ico',
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700131 minify: {removeComments: true, collapseWhitespace: true},
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700132
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700133 }),
Ed Tanous0f2f9812018-12-19 17:59:28 -0800134 new CSPWebpackPlugin({
135 'base-uri': '\'self\'',
136 'object-src': '\'none\'',
137 'script-src': ['\'self\''],
Ed tanouse9211cb2018-04-22 10:53:28 -0700138 'style-src': ['\'self\''],
Yoshie Muranaka0824e492019-08-27 13:03:14 -0700139 'connect-src': ['\'self\'', 'wss:'],
Ed tanouse9211cb2018-04-22 10:53:28 -0700140 // KVM requires image buffers from data: payloads, so allow that in
141 // img-src
142 // https://stackoverflow.com/questions/18447970/content-security-policy-data-not-working-for-base64-images-in-chrome-28
143 'img-src': ['\'self\'', 'data:'],
Ed Tanous0f2f9812018-12-19 17:59:28 -0800144 }),
145 new MiniCssExtractPlugin(),
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700146
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700147 new FilterChunkWebpackPlugin({
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700148 patterns: [
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700149 '*glyphicons-halflings-regular*.ttf',
150 '*glyphicons-halflings-regular*.svg',
151 '*glyphicons-halflings-regular*.eot',
152 '*glyphicons-halflings-regular*.woff2',
153 ]
154 })
155 ];
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700156
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700157 // Add build specific plugins
158 if (isProd) {
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700159 config.plugins.push(new CompressionPlugin({deleteOriginalAssets: true}));
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700160 }
Ed Tanousbbcf6702017-10-06 13:53:06 -0700161
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700162 /**
163 * Dev server configuration
164 * Reference: http://webpack.github.io/docs/configuration.html#devserver
165 * Reference: http://webpack.github.io/docs/webpack-dev-server.html
166 */
167 config.devServer = {contentBase: './src/public', stats: 'minimal'};
Ed Tanousbbcf6702017-10-06 13:53:06 -0700168
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700169 return config;
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700170};