react-cli脚手架配置【webpack】

react-cli 脚手架配置
运行命令:
"dev": "cross-env MODE_ENV=deveploment webpack serve --config ./config/webpack.config.js"
"build": "cross-env MODE_ENV=production webpack --config ./config/webpack.config.js"

在webpack.config.js文件中进行配置

const path = require('path')
const EslintWebpackPlugin = require('eslint-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerWebpackPlugin = require('css-minizer-webpack-plugin')
const TerserWebpackPlugin = require('terser-webpack-plugin')
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin') // 解决html问题

// 判断环境变量 是否为生产模式
const isPro = process.env.MODE_ENV === 'production'

// 处理样式loader函数
const getStyleLoader = (pre) => {
   return [
      // 提取css样式文件
      isPro ? MiniCssExtractPlugin.loader : 'style-loader',
      'css-loader',
      {
         loader: 'postcss-loader',
         options: {
            postcssOptions:{ plugins: ['postcss-preset-env']}
         }
      },
      pre && {
         loader: pre,
         options : pre ==='less-loader' 
           ? {
                // antd 自定义主题颜色配置
                // 在main.js文件中引入为.less文件
                lessOptions: {
                    modifyVars: { '@primary-color': '#1da57a'},
                    javascriptEnabled: true
                }
             } 
           : {}
      },
   ].filter(Boolean)
}

module.exports = {
   entry: './src/main.js',
   output: {
      // 输出目录,生产环境下使用绝对路径,开发模式下不需要 undefined
      path: isPro ? path.resolve(__dirname,'../dist') : undefined,
      filename: isPro ? 'static/js/[name].[contenthash:10].js' : 'static/js/[name].js' ,
      chunkFilename: isPro ? 'static/js/[name].[contenthash:10].chunk.js' : 'static/js/[name].chunk.js' ,
      assetModuleFilename: 'static/media/[hash:10].chunk.js',
      // 清空上一次打包内容
      clean: true
   },
   module: {
      rules: [
         {
            test: /\.css$/,
            use: getStyleLoader(),
         },
         {
            test: /\.less$/,
            use: getStyleLoader('less-loader')
         },
         {
            test: /\.s[ac]ss/,
            use: getStyleLoader('sass-loader')
         },
         // 处理图片
         {
            test: /\.(jpe?g|png|gif|webp|svg)$/,
            type: 'asset',
            parser: {
               dataUrlCondition: { maxSize: 10*1024 }
            },
         },
         // 处理其他资源
         {
            test: /\.(woff2?|ttf)$/,
            type: 'asset/resoure',
         }
         // 处理js
         {
            test: /\.jsx?$/,
            include: path.resolve(__dirname,'./src'),
            loader: 'babel-loader',
            options: {
               cacheDirectory: true,
               cacheCompression: false,
               plugins: [
                  !isPro && 'react-refresh/babel', // 激活js的HMR
               ].filter(Boolean)
            }
         }
      ]
   },
   // 插件处理
   plugins: [
      new EslintWebpackPlugin({
         context: path.resolve(__dirname,'../src'),
         exclude: 'node_modules',
         cache: true,
         cacheLocation: path.resolve(__dirname,'./node_modules/.cache/.eslintcache'),
      }),
      new HtmlWebpackPlugin({ template: path.resolve(__dirname,'../public/index.html')}),
      isPro && new MiniCssExtractPlugin({
         filename: 'static/css/[name].[contenthash:10].css',
         chunkFilename: 'static/css/[name].[contenthash:10].chunk.css'
      }),
      // 复制图标
      isPro && new CopyWebpackPlugin({
         patterns: [
            from: path.resolve(__dirname,'../public'),
            to: path.resolve(__dirname,'../dist'),
            globOptions:{ ignore: ['**/index.html'] } // 忽略html文件
         ]
      }),
      !isPro && new ReactRefreshWebpackPlugin()
   ].filter(Boolean),
   mode: isPro ? 'production' : 'development',
   devtool: isPro ? 'source-map' : 'cleap-module-source-map',
   optimization: {
      splitChunks:{ 
         chunks: 'all', 
         cacheGroups: {
          // 减小文件打包体积
          react: {
             test: /[\\/]node_modules[\\/]react(.*)?[\\/]/, // 打包相关react文件
             name: 'chunk-react', // 打包到哪个文件
             priority: 40, // 打包权重
          },
          antd: {
             test: /[\\/]node_modules[\\/]antd[\\/]/, // 打包相关antd文件
             name: 'chunk-antd', // 打包到哪个文件
             priority: 30, // 打包权重
          },
          libs: {
             test: /[\\/]node_modules[\\/]/, // 打包剩余文件
             name: 'chunk-libs', // 打包到哪个文件
             priority: 20, // 打包权重
          }
         }
      },
      runtimeChunk: { name: (entrypoint)=> `runtime~${entrypoint.name}.js` },
      // 是否需要进行压缩
      minimize: isPro,
      minimizer: [
         new CssMinimizerWebpackPlugin(),
         new TerserWebpackPlugin(),
         new ImageMinimizerPlugin({
            minimizer: {
               implementation: ImageMinimizerPlugin.imageminGenerate,
               options: {
                  plugins: [
                     ['gifsicle',{ interlaced: true}],
                     ['jpegtran',{ progreessive: true}],
                     ['optipng',{ optimizationLevel: 5}],
                     ['svgo',{ plugins: [ 
                        'preset-default',
                        'prefixIds',
                        {
                           name: 'sortAttrs',
                           params: { xmInsOrder: 'alphabetical'}
                        }
                     ]}]
                  ]
               }
            }
         })
      ]
   },
   // webpack 解析模版加载选项
   resolve: {
      // 自动补全文件扩展名
      extensions: ['.jsx','.js','.json']
   },
   devServer: {
      host: 'localhost',
      port: 3000,
      open: true,
      hot: true,
      historyApiFallback: true, // 解决前端路由刷新404问题
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值