const path = require('path'); const { merge } = require('webpack-merge'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const baseConfig = { mode: 'production', entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'js/[name].[contenthash].js', chunkFilename: 'js/[name].[contenthash].js', clean: true, assetModuleFilename: 'assets/[name].[contenthash][ext]' }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'], alias: { '@': path.resolve(__dirname, 'src'), '@components': path.resolve(__dirname, 'src/components'), '@utils': path.resolve(__dirname, 'src/utils'), '@styles': path.resolve(__dirname, 'src/styles') } }, module: { rules: [ { test: /\.(js|jsx|ts|tsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env', '@babel/preset-react'], plugins: ['@babel/plugin-transform-runtime'] } } }, { test: /\.css$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', { loader: 'postcss-loader', options: { postcssOptions: { plugins: [ 'postcss-preset-env', 'autoprefixer' ] } } } ] }, { test: /\.scss$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader' ] }, { test: /\.(png|jpe?g|gif|svg|webp)$/, type: 'asset/resource', generator: { filename: 'images/[name].[contenthash][ext]' } }, { test: /\.(woff|woff2|eot|ttf|otf)$/, type: 'asset/resource', generator: { filename: 'fonts/[name].[contenthash][ext]' } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './public/index.html', minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true, minifyCSS: true, minifyJS: true } }), new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash].css', chunkFilename: 'css/[name].[contenthash].css' }) ] };
const developmentConfig = { mode: 'development', devtool: 'eval-source-map', devServer: { static: { directory: path.join(__dirname, 'dist') }, compress: true, port: 3000, hot: true, open: true, historyApiFallback: true, proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true, pathRewrite: { '^/api': '' } } } } };
const productionConfig = { mode: 'production', devtool: 'source-map', optimization: { minimize: true, minimizer: [ new TerserPlugin({ terserOptions: { compress: { drop_console: true, drop_debugger: true } } }), new CssMinimizerPlugin() ], splitChunks: { chunks: 'all', minSize: 20000, maxSize: 244000, minChunks: 1, maxAsyncRequests: 30, maxInitialRequests: 30, automaticNameDelimiter: '~', cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, priority: -10 }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true } } } }, plugins: [ new BundleAnalyzerPlugin({ analyzerMode: 'static', openAnalyzer: false }) ] };
module.exports = (env) => { if (env === 'development') { return merge(baseConfig, developmentConfig); } return merge(baseConfig, productionConfig); };
|