1'use strict';
2
3// Modules
4var webpack = require('webpack');
5var autoprefixer = require('autoprefixer');
6var HtmlWebpackInlineSourcePlugin =
7    require('html-webpack-inline-source-plugin');
8var CSPWebpackPlugin = require('csp-html-webpack-plugin');
9var HtmlWebpackPlugin = require('html-webpack-plugin');
10var CopyWebpackPlugin = require('copy-webpack-plugin');
11var CompressionPlugin = require('compression-webpack-plugin');
12var path = require('path');
13var FilterChunkWebpackPlugin = require('filter-chunk-webpack-plugin');
14var MiniCssExtractPlugin = require('mini-css-extract-plugin');
15
16module.exports = (env, options) => {
17  var isProd = options.mode === 'production';
18
19  /**
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 = {};
25
26  /**
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   */
32  config.entry = {app: './app/index.js'};
33
34  /**
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   */
40  config.output = {
41    // Absolute output directory
42    path: __dirname + '/dist',
43
44    // Output path from the view of the page
45    // Uses webpack-dev-server in development
46    publicPath: '/',
47
48    // Filename for entry points
49    // Only adds hash in build mode
50    filename: '[name].bundle.js',
51
52    // Filename for non-entry points
53    // Only adds hash in build mode
54    chunkFilename: '[name].bundle.js'
55  };
56
57  /**
58   * 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   */
64
65  // 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
73        test: /\.js$/,
74        use: 'babel-loader',
75        exclude: /node_modules/
76      },
77      {
78        // 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
84        // You can add here any file extension you want to get copied
85        // to your output
86        // Excludes .svg files in icons directory
87        test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot|ico)$/,
88        exclude: /icons\/.*\.svg$/,
89        loader: 'file-loader',
90        options: {name: '[path][name].[ext]'}
91      },
92      {
93        // 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      {
100        // HTML LOADER
101        // Reference: https://github.com/webpack/raw-loader
102        // Allow loading html through js
103        test: /\.html$/,
104        loader: 'html-loader'
105      },
106      {
107        test: /\.css$/,
108        use: [MiniCssExtractPlugin.loader, 'css-loader'],
109      },
110      {
111        test: /\.scss$/,
112        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader']
113      }
114    ]
115  };
116
117  config.plugins = [
118    new HtmlWebpackPlugin({
119      template: './app/index.html',
120      inject: 'body',
121      favicon: './app/assets/images/favicon.ico',
122      minify: {removeComments: true, collapseWhitespace: true},
123
124    }),
125    new CSPWebpackPlugin({
126      'base-uri': '\'self\'',
127      'object-src': '\'none\'',
128      'script-src': ['\'self\''],
129      '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:'],
134    }),
135    new MiniCssExtractPlugin(),
136
137    new FilterChunkWebpackPlugin({
138      patterns: [
139        '*glyphicons-halflings-regular*.ttf',
140        '*glyphicons-halflings-regular*.svg',
141        '*glyphicons-halflings-regular*.eot',
142        '*glyphicons-halflings-regular*.woff2',
143      ]
144    })
145  ];
146
147  // Add build specific plugins
148  if (isProd) {
149    config.plugins.push(new CompressionPlugin({deleteOriginalAssets: true}));
150  }
151
152  /**
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'};
158
159  return config;
160};
161