const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const TerserPlugin = require('terser-webpack-plugin') const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin()
module.exports = smp.wrap({ mode: 'production', devServer: { static: './dist', hot: true, compress: true, port: 3000, historyApiFallback: true }, cache: { type: 'filesystem' }, entry: { main: './src/index.js', vendor: ['react', 'react-dom'] }, output: { path: path.resolve(__dirname, 'dist'), filename: 'js/[name].[contenthash:8].js', chunkFilename: 'js/[name].[contenthash:8].js', clean: true }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'], alias: { '@': path.resolve(__dirname, 'src'), '@components': path.resolve(__dirname, 'src/components'), '@utils': path.resolve(__dirname, 'src/utils') } }, module: { rules: [ { test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, include: path.resolve(__dirname, 'src'), use: { loader: 'babel-loader', options: { cacheDirectory: true, presets: [ ['@babel/preset-env', { modules: false }], '@babel/preset-react', '@babel/preset-typescript' ] } } }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { modules: { auto: true, localIdentName: '[name]__[local]--[hash:base64:5]' }, importLoaders: 1, sourceMap: true, cache: true } }, 'postcss-loader' ] }, { test: /\.(png|jpe?g|gif|webp|avif)$/i, type: 'asset/resource', generator: { filename: 'assets/images/[name].[hash:8][ext]' }, use: [ { loader: 'image-webpack-loader', options: { mozjpeg: { progressive: true, quality: 65 }, optipng: { enabled: false }, pngquant: { quality: [0.65, 0.9], speed: 4 } } } ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/i, type: 'asset/resource', generator: { filename: 'assets/fonts/[name].[hash:8][ext]' } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', minify: { collapseWhitespace: true, removeComments: true } }), new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash:8].css', chunkFilename: 'css/[name].[contenthash:8].css' }), new webpack.optimize.SplitChunksPlugin({ chunks: 'all', minSize: 20000, maxSize: 244000, cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10, name: 'vendors' } } }) ], optimization: { minimizer: [ new TerserPlugin({ parallel: true, terserOptions: { compress: { drop_console: true, drop_debugger: true } } }), new CssMinimizerPlugin({ minimizerOptions: { preset: ['default'] } }) ], runtimeChunk: 'single' }, plugins: [ new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false, reportFilename: 'bundle-analysis/report.html' }) ] })
|