const webpack = require('webpack'); const path = require('path'); const HtmlWebPackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const ErrorOverlayPlugin = require('error-overlay-webpack-plugin'); const postcssPresetEnv = require('postcss-preset-env'); const stylelint = require('stylelint'); module.exports = (env, argv) => { const dev = argv.mode !== 'production'; const config = { devtool: dev ? 'source-map' : false, mode: dev ? 'development' : 'production', entry: { 'Juick': [ 'core-js/modules/es.array.map', 'core-js/modules/es.map', 'core-js/modules/es.object.create', 'core-js/modules/es.object.define-property', 'core-js/modules/es.object.set-prototype-of', 'core-js/modules/es.promise', 'core-js/modules/es.set', 'core-js/modules/es.symbol', 'core-js/modules/web.dom-collections.iterator', 'url-polyfill', __dirname + '/src/index.js', __dirname + '/src/style/main.css' ] }, output: { filename: dev ? '[name].js' : '[name].[contenthash].bundle.js', chunkFilename: dev ? '[name].js' : '[name].[contenthash].bundle.js', publicPath: '/', path: path.resolve(__dirname, 'dist') }, module: { rules: [ { test: /\.css$/, use: [ dev? 'style-loader' : MiniCssExtractPlugin.loader, { loader: 'css-loader' }, { loader: 'postcss-loader', options: { plugins: () => [ stylelint(), postcssPresetEnv({ stage: 0, autoprefixer: { grid: true } }) ] } } ] }, { test: /\.html$/, use: [ { loader: 'html-loader', options: { minimize: false } } ] }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }, { test: /\.(jpe?g|png|gif|svg)$/i, loaders: [ 'file-loader?hash=sha512&digest=hex&name=[hash].[ext]' ] } ] }, plugins: [ new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), new MiniCssExtractPlugin({ filename: 'Juick.[contenthash].css', allChunks: true }), new HtmlWebPackPlugin({ template: './src/index.html', filename: './index.html' }), new ErrorOverlayPlugin() ], devServer: { bonjour: true, historyApiFallback: true, host: '0.0.0.0', hot: true, inline: true } }; if (dev) { config.plugins.push(new webpack.HotModuleReplacementPlugin()); } else { config.optimization = { minimizer: [ new TerserPlugin({ cache: true, parallel: true, sourceMap: dev, terserOptions: { output: { comments: /@license/i } }, extractComments: true }), new OptimizeCSSAssetsPlugin({}) ], splitChunks: { chunks: 'all', minSize: 30000, maxSize: 0, minChunks: 1, maxAsyncRequests: 5, maxInitialRequests: 3, automaticNameDelimiter: '~', name: true, cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true } } } }; } return config; };