blob: b1c8808508936a3e39143e8b436371aaaa5becb7 [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 Tanousfc7a33f2018-09-06 16:52:19 -070016module.exports = (env, options) => {
17 var isProd = options.mode === 'production';
Ed Tanousbbcf6702017-10-06 13:53:06 -070018
Andrew Geisslerd27bb132018-05-24 11:07:27 -070019 /**
20 * Config
21 * Reference: http://webpack.github.io/docs/configuration.html
22 * This is the object where all configuration gets set
23 */
24 var config = {};
Ed Tanousbbcf6702017-10-06 13:53:06 -070025
Andrew Geisslerd27bb132018-05-24 11:07:27 -070026 /**
27 * Entry
28 * Reference: http://webpack.github.io/docs/configuration.html#entry
29 * Should be an empty object if it's generating a test build
30 * Karma will set this when it's a test build
31 */
Ed Tanousfc7a33f2018-09-06 16:52:19 -070032 config.entry = {app: './app/index.js'};
Ed Tanousbbcf6702017-10-06 13:53:06 -070033
Andrew Geisslerd27bb132018-05-24 11:07:27 -070034 /**
35 * Output
36 * Reference: http://webpack.github.io/docs/configuration.html#output
37 * Should be an empty object if it's generating a test build
38 * Karma will handle setting it up for you when it's a test build
39 */
Ed Tanousfc7a33f2018-09-06 16:52:19 -070040 config.output = {
Andrew Geisslerd27bb132018-05-24 11:07:27 -070041 // Absolute output directory
42 path: __dirname + '/dist',
Ed Tanousbbcf6702017-10-06 13:53:06 -070043
Andrew Geisslerd27bb132018-05-24 11:07:27 -070044 // Output path from the view of the page
45 // Uses webpack-dev-server in development
46 publicPath: '/',
Ed Tanousbbcf6702017-10-06 13:53:06 -070047
Andrew Geisslerd27bb132018-05-24 11:07:27 -070048 // Filename for entry points
49 // Only adds hash in build mode
Ed Tanousfc7a33f2018-09-06 16:52:19 -070050 filename: '[name].bundle.js',
Ed Tanousbbcf6702017-10-06 13:53:06 -070051
Andrew Geisslerd27bb132018-05-24 11:07:27 -070052 // Filename for non-entry points
53 // Only adds hash in build mode
Ed Tanousfc7a33f2018-09-06 16:52:19 -070054 chunkFilename: '[name].bundle.js'
Andrew Geisslerd27bb132018-05-24 11:07:27 -070055 };
Ed Tanousbbcf6702017-10-06 13:53:06 -070056
Andrew Geisslerd27bb132018-05-24 11:07:27 -070057 /**
Andrew Geisslerd27bb132018-05-24 11:07:27 -070058 * Loaders
59 * Reference:
60 * http://webpack.github.io/docs/configuration.html#module-loaders
61 * List: http://webpack.github.io/docs/list-of-loaders.html
62 * This handles most of the magic responsible for converting modules
63 */
Ed Tanousbbcf6702017-10-06 13:53:06 -070064
Andrew Geisslerd27bb132018-05-24 11:07:27 -070065 // Initialize module
66 config.module = {
67 rules: [
68 {
69 // JS LOADER
70 // Reference: https://github.com/babel/babel-loader
71 // Transpile .js files using babel-loader
72 // Compiles ES6 and ES7 into ES5 code
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070073 test: /\.js$/,
Andrew Geisslerd27bb132018-05-24 11:07:27 -070074 use: 'babel-loader',
75 exclude: /node_modules/
76 },
Ed Tanous0f2f9812018-12-19 17:59:28 -080077 {
Andrew Geisslerd27bb132018-05-24 11:07:27 -070078 // ASSET LOADER
79 // Reference: https://github.com/webpack/file-loader
80 // Copy png, jpg, jpeg, gif, svg, woff, woff2, ttf, eot files to
81 // output
82 // Rename the file using the asset hash
83 // Pass along the updated reference to your code
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -050084 // You can add here any file extension you want to get copied
85 // to your output
86 // Excludes .svg files in icons directory
Andrew Geisslerd27bb132018-05-24 11:07:27 -070087 test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -050088 exclude: /icons\/.*\.svg$/,
Andrew Geisslerd27bb132018-05-24 11:07:27 -070089 loader: 'file-loader',
Ed Tanousfc7a33f2018-09-06 16:52:19 -070090 options: {name: '[path][name].[ext]'}
Andrew Geisslerba5e3f32018-05-24 10:58:00 -070091 },
Andrew Geisslerd27bb132018-05-24 11:07:27 -070092 {
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -050093 // INLINE SVG LOADER
94 // Inlines .svg assets in icons directory
95 // needed specifically for icon-provider.js directive
96 test: /icons\/.*\.svg$/,
97 loader: 'svg-inline-loader'
98 },
99 {
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700100 // HTML LOADER
101 // Reference: https://github.com/webpack/raw-loader
102 // Allow loading html through js
103 test: /\.html$/,
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700104 loader: 'html-loader'
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700105 },
Yoshie Muranakac86ce3c2019-06-05 12:30:30 -0500106 {
107 test: /\.css$/,
108 use: [MiniCssExtractPlugin.loader, 'css-loader'],
109 },
110 {
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700111 test: /\.scss$/,
Ed Tanous0f2f9812018-12-19 17:59:28 -0800112 use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700113 }
114 ]
115 };
Ed Tanousbbcf6702017-10-06 13:53:06 -0700116
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700117 config.plugins = [
118 new HtmlWebpackPlugin({
119 template: './app/index.html',
120 inject: 'body',
121 favicon: './app/assets/images/favicon.ico',
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700122 minify: {removeComments: true, collapseWhitespace: true},
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700123
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700124 }),
Ed Tanous0f2f9812018-12-19 17:59:28 -0800125 new CSPWebpackPlugin({
126 'base-uri': '\'self\'',
127 'object-src': '\'none\'',
128 'script-src': ['\'self\''],
Ed tanouse9211cb2018-04-22 10:53:28 -0700129 'style-src': ['\'self\''],
130 // KVM requires image buffers from data: payloads, so allow that in
131 // img-src
132 // https://stackoverflow.com/questions/18447970/content-security-policy-data-not-working-for-base64-images-in-chrome-28
133 'img-src': ['\'self\'', 'data:'],
Ed Tanous0f2f9812018-12-19 17:59:28 -0800134 }),
135 new MiniCssExtractPlugin(),
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700136
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700137 new FilterChunkWebpackPlugin({
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700138 patterns: [
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700139 '*glyphicons-halflings-regular*.ttf',
140 '*glyphicons-halflings-regular*.svg',
141 '*glyphicons-halflings-regular*.eot',
142 '*glyphicons-halflings-regular*.woff2',
143 ]
144 })
145 ];
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700146
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700147 // Add build specific plugins
148 if (isProd) {
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700149 config.plugins.push(new CompressionPlugin({deleteOriginalAssets: true}));
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700150 }
Ed Tanousbbcf6702017-10-06 13:53:06 -0700151
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700152 /**
153 * Dev server configuration
154 * Reference: http://webpack.github.io/docs/configuration.html#devserver
155 * Reference: http://webpack.github.io/docs/webpack-dev-server.html
156 */
157 config.devServer = {contentBase: './src/public', stats: 'minimal'};
Ed Tanousbbcf6702017-10-06 13:53:06 -0700158
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700159 return config;
Ed Tanousfc7a33f2018-09-06 16:52:19 -0700160};