const webpack = require('webpack'); const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const ManifestPlugin = require('webpack-manifest-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const CopyPlugin = require('copy-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const yaml = require('js-yaml'); var webpackVersion = require('webpack/package.json').version.split('.').slice(0, 2).join('.'); module.exports = { module: { rules: [ { loader: 'babel-loader', options: { plugins: ['syntax-dynamic-import'], presets: [ [ '@babel/preset-env', { modules: false, targets: { edge: "17", firefox: "50", chrome: "60", safari: "11.1", ie: "11", }, useBuiltIns: "usage", corejs: 3 } ] ] }, test: /\.js$/i, exclude: /node_modules/, }, { test: /\.css$/i, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { sourceMap: true }}, { loader: 'postcss-loader', options: { sourceMap: true }} ] }, { test: /\.scss$/i, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { sourceMap: true }}, { loader: 'postcss-loader', options: { sourceMap: true }}, { loader: 'sass-loader', options: { sourceMap: true }} ] }, { test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/i, use: [ { loader: 'file-loader', options: { name: '[contenthash].[ext]', esModule: false } } ] } ] }, entry: { main: path.resolve(__dirname, 'frontend/src', 'main.js') }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // all options are optional filename: '[contenthash].css', chunkFilename: '[contenthash].css', ignoreOrder: false, // Enable to remove warnings about conflicting order }), new webpack.NamedChunksPlugin((chunk) => { if (chunk.name) { return chunk.name; } return chunk.modules.map(m => path.relative(m.context, m.request)).join("_"); }), new webpack.NamedModulesPlugin(), new ManifestPlugin({ fileName: path.resolve(__dirname, 'config', 'webpack.yml'), publicPath: `wp-${webpackVersion}/`, generate: (seed, files, entrypoints) => Object.keys(entrypoints).reduce((acc, fs) => ({...acc, [fs]: files.filter(file => entrypoints[fs].filter(basename => !(/\.map$/.test(basename))).some(basename => file.path.endsWith(basename))).filter(file => file.isInitial).map(file => file.path)}), {}), serialize: yaml.safeDump }), new CleanWebpackPlugin({ cleanOnceBeforeBuildPatterns: path.resolve(__dirname, 'static', 'wp-*') }), new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), new CopyPlugin([ { from: 'assets/lmu/sigillum.svg', to: path.resolve(__dirname, 'static', 'img/lmu/sigillum.svg') }, ]) ], output: { chunkFilename: '[contenthash].js', filename: '[contenthash].js', path: path.resolve(__dirname, 'static', `wp-${webpackVersion}`), publicPath: `/static/res/wp-${webpackVersion}/`, hashFunction: 'shake256', hashDigestLength: 36 }, optimization: { minimize: true, minimizer: [ new TerserPlugin({ cache: true, parallel: true, sourceMap: true }) ], runtimeChunk: 'single', splitChunks: { chunks: 'all', maxInitialRequests: Infinity, maxAsyncRequests: Infinity, minSize: 0, minChunks: 1, cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name(module, chunks, cacheGroupKey) { const moduleFileName = module.identifier().split('/').reduceRight(item => item); const allChunksNames = chunks.map((item) => item.name).join('~'); const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]; return `${cacheGroupKey}-${packageName}-${allChunksNames}-${moduleFileName}`; }, priority: -10 }, default: { priority: -20, minChunks: 1 } } }, moduleIds: 'hashed' }, mode: 'production', recordsPath: path.join(__dirname, 'records.json'), performance: { assetFilter: (assetFilename) => !(/\.(map|svg|ttf|eot)$/.test(assetFilename)) }, devtool: 'source-map' };