// Webpack config for creating the production bundle. const path = require('path'); const webpack = require('webpack'); const CleanPlugin = require('clean-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const hasuraConfig = require('../hasuraconfig'); const relativeAssetsPath = '../static/dist'; const assetsPath = path.join(__dirname, relativeAssetsPath); const WebpackIsomorphicToolsPlugin = require('webpack-isomorphic-tools/plugin'); const webpackIsomorphicToolsPlugin = new WebpackIsomorphicToolsPlugin( require('./webpack-isomorphic-tools') ); const TerserPlugin = require('terser-webpack-plugin'); const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); const cleanOptions = { root: process.cwd(), verbose: true, dry: false, }; module.exports = { mode: 'production', context: path.resolve(__dirname, '..'), entry: { main: ['bootstrap-loader?extractStyles', './src/client.js'], }, output: { path: assetsPath, filename: '[name].js', chunkFilename: '[name].js', publicPath: hasuraConfig.webpackPrefix, }, module: { rules: [ { test: /\.mjs$/, include: /node_modules/, type: 'javascript/auto', }, { test: /\.jsx?$/, exclude: /node_modules/, use: 'babel-loader', }, { test: /\.flow$/, loader: 'ignore-loader', }, { test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { importLoaders: 1, }, }, ], }, { test: /\.scss$/, use: [ MiniCssExtractPlugin.loader, 'css-loader?modules&importLoaders=2&sourceMap=false', 'sass-loader?outputStyle=expanded&sourceMap=false&sourceMapContents=false', ], }, { test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, use: [ { loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' }, }, ], }, { test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, use: [ { loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' }, }, ], }, { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, use: [ { loader: 'url-loader', options: { limit: 10000, mimetype: 'application/octet-stream' }, }, ], }, { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, use: [{ loader: 'file-loader' }], }, { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, use: [ { loader: 'url-loader', options: { limit: 10000, mimetype: 'image/svg+xml' }, }, ], }, { test: webpackIsomorphicToolsPlugin.regular_expression('images'), use: [{ loader: 'url-loader', options: { limit: 10240 } }], }, ], }, resolve: { modules: ['src', 'node_modules'], extensions: ['.json', '.js', '.jsx', '.mjs'], }, optimization: { minimize: true, runtimeChunk: { name: 'vendor', }, minimizer: [ new TerserPlugin({ terserOptions: { ecma: 8, warnings: false, compress: false, mangle: true, output: { comments: false, beautify: false, }, toplevel: false, nameCache: null, ie8: false, keep_classnames: undefined, keep_fnames: false, safari10: false, }, extractComments: false, }), new OptimizeCssAssetsPlugin({ assetNameRegExp: /\.css$/, }), ], splitChunks: { cacheGroups: { commons: { test: /[\\/]node_modules[\\/]/, name: 'vendor', chunks: 'initial', }, }, }, }, plugins: [ new CleanPlugin(['./static/dist/*.*'], cleanOptions), new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', }), new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename: 'main.css', chunkFilename: 'main.css', }), new webpack.DefinePlugin({ __CLIENT__: true, __SERVER__: false, __DEVELOPMENT__: false, __DEVTOOLS__: false, }), // ignore dev config new webpack.IgnorePlugin(/\.\/dev/, /\/config$/), // set global consts new webpack.DefinePlugin({ 'process.env': { // Useful to reduce the size of client-side libraries, e.g. react NODE_ENV: JSON.stringify('production'), }, CONSOLE_ASSET_VERSION: Date.now().toString(), }), ], };