/*eslint global-require: "off"*/ const path = require('path'); const webpack = require('webpack'); const TerserWebpackPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); require('@babel/register'); module.exports = (env, argv) => { const devMode = argv.mode === 'development'; const config = { target: 'web', entry: ['@babel/polyfill', './src/index.js'], resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], fallback: { fs: false } }, devServer: { host: '0.0.0.0', port: 8000, hot: true, publicPath: '/build/', contentBase: __dirname, watchContentBase: true, historyApiFallback: { index: 'index.html', }, }, output: { path: path.resolve(__dirname, 'build'), filename: '[name].js', chunkFilename: '[name].js', publicPath: '/build/', }, optimization: { minimize: (devMode) ? false : true, minimizer: [ new TerserWebpackPlugin({ parallel: true, extractComments: true, terserOptions: { parse: { ecma: 8 }, output: { comments: false } } }), new CssMinimizerPlugin() ], moduleIds: "deterministic", splitChunks: { cacheGroups: { default: false, vendors: { // name of the chunk name: 'vendor', // sync + async chunks chunks: 'all', // import file path containing node_modules test: /[\\/]node_modules[\\/]/, priority: 20, }, styles: { name: 'styles', test: /\.css$/, chunks: "all", enforce: true, }, common: { name: 'common', minChunks: 2, chunks: 'all', priority: 10, reuseExistingChunk: true, enforce: true, }, }, }, }, module: { rules: [ { test: /\.(js|ts)x?$/, exclude: /node_modules/, loader: 'babel-loader', options: { presets: [ '@babel/typescript', ['@babel/preset-env', { loose: true }], '@babel/preset-react', ], plugins: [ '@babel/plugin-transform-runtime', '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-syntax-dynamic-import', ['@babel/plugin-proposal-decorators', { legacy: true }], ['@babel/plugin-proposal-class-properties', { loose: true }], ['@babel/plugin-transform-computed-properties', { loose: true }], ], }, }, { test: /\.s?[ac]ss$/, use: [ devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader', ], }, ], }, // First array is dev only, second is production plugins: devMode ? [ ] : [ new CleanWebpackPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production'), }), new MiniCssExtractPlugin({ filename: '[name].css' }), ], }; if (devMode) { config.devtool = 'inline-source-map'; } return config; };