手动搭建react项目的配置

216 阅读2分钟

配置中遇到的问题

  • 开发环境react HMR 的配置(只会更新修改的内容,而不是所有的大更新)

yarn add -D @pmmmwh/react-refresh-webpack-plugin react-refresh www.npmjs.com/package/@pm…

配置👇

const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

module:{
    rules:[
        {
           test: /\.(jsx|js)$/,
           exclude: /(node_modules)/,
           use: {
             loader: 'babel-loader',
             options: {
                 plugins: ['react-refresh/babel'],
             },
          },
        }
    ]
},
plugins:[
  new ReactRefreshWebpackPlugin(),  //react的热更新
]
  • 引入antd.less的样式

yarn add antd

可能会遇到如下问题,

image.png

解决方案👇

image.png

  • 使用import 以及export eslint报错

image.png

解决方案👇

  • ecmaVersion :使用的ECMAScript 版本
  • sourceType - 设置为 "script" (默认) 或 "module"(如果你的代码是 ECMAScript 模块)。
  • ecmaFeatures - 这是个对象,表示你想使用的额外的语言特性

image.png

  • react-router的配置
1.安装组件npm install --save react-router react-router-dom
2.启用全局路由模式
路由模式:HashRouter 和 BrowserRouter HashRouter
HashRouter:http://localhost:3030/#/home
BrowserRouter:http://localhost:3030/home

入口main.js中配置 image.png 需要路由的页面配置 image.png

常用的组件:其它的可以查看官网

组件名作用说明
<Routers>一组路由代替原有<Switch>,所有子路由都用基础的Router children来表示
<Router>基础路由Router是可以嵌套的,解决原有V5中严格模式,后面与V5区别会详细介绍
<Link>导航组件在实际页面中跳转使用
<Outlet/>自适应渲染组件根据实际路由url自动选择组件

问题1

这是因为他会去Source里面去找资源,但是Source里面是不存在home资源的,Source里面只有打包的静态资源和main.js

image.png

image.png

解决方案:webpack.docschina.org/configurati…

刷新后重定向到入口文件

image.png

配置

开发环境的配置

let path = require("path")
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ESLintPlugin = require('eslint-webpack-plugin')
const TerserPlugin = require("terser-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const getStyleFn=(pre)=>{
    return [
        MiniCssExtractPlugin.loader,
        'css-loader',
        {
            loader: "postcss-loader",   //处理样式的兼容性问题
            options: {
              postcssOptions: {
                plugins: [
                    "postcss-preset-env",
                ],
              },
            },
          },
        pre && {
            loader :pre,
            options:pre === 'less-loader' ?
            {
                lessOptions: { // 如果使用less-loader@5,请移除 lessOptions 这一级直接配置选项。
                    modifyVars: {
                      'primary-color': '#1DA57A',
                       'link-color': '#1DA57A',
                      'border-radius-base': '2px',
                    },
                    javascriptEnabled: true,
                },
            }
            :{}
        }
    ].filter(Boolean) 
}
module.exports={
    entry:'./src/main.js',
    output:{
        filename:'js/[name].js',  //生产模式下'js/[name].[chunkhash:10].bundle.js',
        path:path.resolve(__dirname,'../dist'),
        assetModuleFilename:'media/[hash:10][ext][query]',  //图片等资源
        clean:true,  //清除缓存。----生产模式下不需要
    },
    module: {
        rules:[
            {
                oneOf: [
                    {
                      test: /\.css$/,
                      use: getStyleFn()
                    },
                    {
                      test: /\.less$/,
                      use: getStyleFn('less-loader')
                    }
                ]
            },
            {
               test: /\.(png|jpg|gif)$/i,
               type: 'asset',
               parser: {
                dataUrlCondition: {
                  maxSize: 10 * 1024 // 小于10kb的图片会被base64处理
                }
              },
            },
            {
                test: /\.(woff|woff2|eot|ttf|otf)$/,
                type: 'asset/resource',
            },
            {
                test: /\.(jsx|js)$/,
                exclude: /(node_modules)/,
                use: {
                  loader: 'babel-loader',
                  options: {
                    plugins: ['react-refresh/babel'],
                    },
                },
               
            }
        ]
        

    },
    plugins:[
        new HtmlWebpackPlugin({
            template:path.resolve(__dirname,'../src/public/index.html'),
        }),
        new MiniCssExtractPlugin({
            filename: "css/[name].css",  //生产 "css/[name].[contenthash:10].css",
            chunkFilename: "css/[name].[contenthash:10].chunk.css",
        }),  //拆分css为单独文件
        new ESLintPlugin({
            //检测哪些文件
            context:path.resolve(__dirname,'../src'),
            cache:true,  //开启缓存
            cacheLocation:path.resolve(__dirname,'../node_modules/.cache/eslintcache'),  //eslint缓存文件
        }),
        new ReactRefreshWebpackPlugin(),  //react的热更新----生产模式下不需要
          // 将public下面的资源复制到dist目录去(除了index.html)
        new CopyPlugin({
            patterns: [
            {
                from: path.resolve(__dirname, "../src/public"),
                to: path.resolve(__dirname, "../dist"),
                toType: "dir",
                noErrorOnMissing: true, // 不生成错误
                globOptions: {
                // 忽略文件
                ignore: ["**/index.html"],
                },
                info: {
                // 跳过terser压缩js
                minimized: true,
                },
            },
            ],
      }),
    ],
    //webpack解析模块加载选项
    resolve: {
        extensions: [".jsx", ".js", ".json"],//自动补全文件扩展名
    },
    optimization:{
        moduleIds: 'deterministic',  //解决文件内容不变,重复打包的问题
        minimizer:true,  //是否开启压缩,生产需要 true,开发false
        minimizer: [
            //优化和压缩 CSS只在生产模式下生效
            new CssMinimizerPlugin(),
            //开启多进程以及压缩js
            new TerserPlugin({
                parallel:true,
            })
        ],
        splitChunks:{
            chunks:'all'
        },

    },
    mode:'development',
     //开发服务器:不会输出资源,在内存中编译打包的。----生产模式下不需要
    devServer:{
        host:"localhost",
        port:'3030',
        open:false,
        hot:true,  //开启HMR
        historyApiFallback: true, //解决前端路由404的问题
    },
    //打包文件和源文件作映射,方便定位问题
    devtool:'source-map'
}

babel-config.js配置

module.exports = {
  //babel-preset-app
    presets:[
      "react-app"
    ],
}

  • eslint在react中的配置

请注意,支持 JSX 语法并不等同于支持 React。React 对 ESLint 无法识别的JSX语法应用特定的语义。如果你正在使用 React 并且想要 React 语义支持,我们建议你使用 eslint-plugin-react

eslint配置👇

module.exports={
    //继承其他规则
    extends: [
      "eslint:recommended",
      "plugin:react/recommended"
    ], 
    "env": {
      "browser": true,   //启用浏览器中的全局变量
      "es6": true,
      "node": true     //启用node中的全局变量
  },
    //解释选项
    parserOptions: {
      "ecmaVersion": 6,
      "sourceType": "module",
      "ecmaFeatures": {
          "jsx": true
      },
      babelOptions: {
        presets: [
          // 解决页面报错问题
          ["babel-preset-react-app", false],
          "babel-preset-react-app/prod",
        ],
      },
    },
    plugins: [
      "react"
    ],
    rules: {
      "react/jsx-uses-react": "error",
      "react/jsx-uses-vars": "error",
    }

}

package.json配置

{
  "name": "cherry-webpack",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "start": "npm run dev",
    "dev": "cross-env NODE_ENV=development webpack server --config ./config/webpack.dev.js",
    "build": "cross-env NODE_ENV=production webpack --config ./config/webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
 
  "devDependencies": {
    "@babel/core": "^7.19.6",
    "@babel/plugin-transform-runtime": "^7.19.6",
    "@babel/preset-env": "^7.19.4",
    "@pmmmwh/react-refresh-webpack-plugin": "^0.5.8",
    "babel-loader": "^8.2.5",
    "babel-preset-react-app": "^10.0.1",
    "copy-webpack-plugin": "^11.0.0",
    "cross-env": "^7.0.3",
    "css-loader": "^6.7.1",
    "css-minimizer-webpack-plugin": "^4.2.2",
    "eslint": "^8.26.0",
    "eslint-plugin-react": "^7.31.10",
    "eslint-webpack-plugin": "^3.2.0",
    "html-webpack-plugin": "^5.5.0",
    "less": "^4.1.3",
    "less-loader": "^11.1.0",
    "mini-css-extract-plugin": "^2.6.1",
    "postcss": "^8.4.18",
    "postcss-loader": "^7.0.1",
    "postcss-preset-env": "^7.8.2",
    "react-refresh": "^0.14.0",
    "style-loader": "^3.3.1",
    "terser-webpack-plugin": "^5.3.6",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.11.1"
  },
  "browserslist": [
    "last 2 version",
    "> 0.25%",
    "not dead"
  ],
  "dependencies": {
    "antd": "^4.23.6",
    "core-js": "^3.26.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router": "^6.4.2",
    "react-router-dom": "^6.4.2"
  }
}