使用webpack 搭建react项目

1. 初始化项目

mkdir webpack-react
cd webpack-*
npm init -y
  • cd webpack-*: 用到了 glob 语法,可自行了解
  • npm init -y: 迅速初始化 npm 项目

2. 安装

  1. 下载 Webpack 基础依赖
    npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin clean-webpack-plugin
    
    • webpack-dev-server的作用:启动一个express服务器,并在内存中生产bundle文件。
    • html-webpack-plugin的作用: image.png
      • clean-webpack-plugin: 打包前清除dist文件夹
  2. 下载 babel 相关
    npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-react
    
  3. 下载 css相关的loader
    npm i -D css-loader style-loader less less-loader
    
    • css-loader:解析css
    • style-loader: 将解析后的css放在style标签中,并添加到html文件
  4. 下载 react 相关的loader
    npm i react react-dom
    

3. 创建 react 文件

  1. 在主目录下创建public文件夹,并在该文件夹下创建index.html文件中
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>React Title</title>
    </head>
    <body>
      <div id="root"></div>
    </body>
    </html>
    
  2. 在主目录下创建src文件夹,并在该文件夹下创建index.js文件
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import App from '../App';
    
    const root = document.getElementById('root');
    ReactDOM.createRoot(root).render(<App />);
    
  3. 在主目录的src文件夹下,创建App.js文件
    import React from 'react';
    
    function App() {
      return (
        <div>Hello World</div>
      )
    }
    
    export default App;
    

4. 配置 webpack

  • 在主目录下创建webpack.config.js文件
    const path = require('path');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    
    module.exports = {
      // 入口文件,webpack会首先从这里开始编译
      mode: 'development',
      entry: {
        index: './src/index'
      },
      module: {
        rules: [
          {
            test: /\.(tsx?|jsx?)$/,
            exclude: /node_modules/,
            use: [
              {
                loader: 'babel-loader',
                options: {
                  presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript']
                }
              },
            ]
          },
          {
            test: /\.css$/,
            use: [
              { loader: 'style-loader' },
              { loader: 'css-loader' }
            ]
          },
          {
            test: /\.less$/,
            use: [
              { loader: 'style-loader' },
              { loader: 'css-loader' },
              { loader: 'less-loader' },
            ]
          }
        ]
      },
      devtool: 'inline-source-map', // 更好的追踪代码和给出错误代码的位置
      // 解析-相关配置
      resolve: {
        // 扩展名
        extensions: ['.js', jsx, '.tsx', '.ts', '.less', 'css'],
        // 设置别名
        alias: {
          components: path.resolve(__dirname, 'src/components/'),
          utils: path.resolve(__dirname, 'src/utils/'),
        }
      },
      // 3000 端口打开网页
      devServer: {
        static: './dist',
        port: 3000,
        hot: true,
      },
      // 打包后输出的位置
      output: {
        filename: 'index.js',
        path: path.resolve(__dirname, 'dist'),
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './public/index.html'
        }),
        new CleanWebpackPlugin(['dist']),
      ]
    };
    

5. 配置 package.json文件

{
  "name": "webpack-react",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server" // 添加运行脚本
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.18.9",
    "@babel/preset-env": "^7.18.9",
    "@babel/preset-react": "^7.18.6",
    "babel-loader": "^8.2.5",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^6.7.1",
    "html-webpack-plugin": "^5.5.0",
    "less": "^4.1.3",
    "less-loader": "^11.0.0",
    "style-loader": "^3.3.1",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.3"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  }
}

6. 项目添加 typescript

  1. 安装依赖
    npm i -D typescript @babel/preset-typescript        
    
  2. 安装 react的 types
    npm i -D @types/react @types/react-dom
    
  3. 生成配置文件
    npx tsc --init
    
    • 然后就会在主目录下生成 tsconfig.json文件
    • 对 npx 不太熟悉的 可以看阮一峰老师的这篇文章:npx 使用教程
  • 修改 主目录下的 tsconfig.json文件
    {
      "compilerOptions": {
        "target": "es2016",
        "jsx": "react", // 1. 配置 jsx
        "module": "commonjs",
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true,
        "baseUrl": "./", // 2. 配置 baseUrl
        "paths": {
          "utils/*": ["src/utils/*"], // 3. 配置 paths
          "components/*": ["src/components/*"],
        },
      },
      "include": ["src/**/*"],  // 4. 配置 include
      "exclude": ["node_modules"] // 5. 配置 exclude
    }
    
  1. 配置 webpack.config.js

    image.png

  2. 解决 ts 报错

    修改文件:App.js => App.tsx, src/index.js => src/index.tsx

    • Cannot use JSX unless the '--jsx' flag is provided: 根目录下的tsconfig.json文件中加入
      {
          // ...
          "jsx": "react", 
          // ...
      }
      
    • 类型“HTMLElement | null”的参数不能赋给类型“Element | DocumentFragment”的参数。不能将类型“null”分配给类型“Element | DocumentFragment”。: App.tsx 文件的root后加! image.png
    • # 找不到模块“utils/index”或其相应的类型声明”: 配置根目录下的tsconfig.json
    {
      "compilerOptions": {
        "target": "es2016", 
        "jsx": "react",
        "module": "commonjs",
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true,
        "baseUrl": "./", // 1. 配置 baseUrl
        "paths": {
          "utils/*": ["src/utils/*"], // 2. 配置 paths
          "components/*": ["src/components/*"],
        },
      },
      "include": ["src/**/*"],  // 3. include 和 exclude 也配置上
      "exclude": ["node_modules"]
    }
    
  3. ts的配置方式

    1. 项目没有配置 babel 时,选择 typescript + ts-loader
    2. 项目配置了 babel 时,可以使用 typescript + @babel/preset-typescrip,它是TypeScript 和 Babel 团队官方合作的项目
    3. 两种方式的webpack配置差异如下 image.png

7. 添加 eslint

  1. 安装
    npm i -D eslint
    
  2. 配置
    npx eslint --init
    
    You can also run this command directly using 'npm init @eslint/config'
    // y
    ✔ How would you like to use ESLint? 
    // To check syntax, find problems, and enforce code style 
    ✔ What type of modules does your project use? 
    // JavaScript modules (import/export) 
    ✔ Which framework does your project use? 
    // react 
    ✔ Does your project use TypeScript? 
    // Yes 
    ✔ Where does your code run? 
    // browser 
    ✔ How would you like to define a style for your project? 
    // Use a popular style guide 
    ✔ Which style guide do you want to follow? 
    // Airbnb 
    ✔ What format do you want your config file to be in? 
    // JavaScript
    
    然后根目录下就生成了.eslint.js文件
  3. 解决 eslint 报错
  • Newline required at end of file but not found: 换行就可以了
  • ``Unable to resolve path to module './App': 在.eslintrc.json中添加rules设置
    { 
      rules: {
        'import/no-unresolved': 0,
        'import/extensions': 0,
        'import/no-absolute-path': 0,
      },
    };
    
  • JSX not allowed in files with extension '.tsx': 在.eslintrc.json中添加rules设置
    {
      'react/jsx-filename-extension': [
        2,
        {
          extensions: ['.js', '.jsx', '.tsx', '.ts'],
        },
      ],
    }
    
  1. 配置 package.json
    {
      "scripts": {
        "start": "webpack-dev-server",
        "build": "webpack build",
        "eslint": "eslint --ext .js,.jsx,ts,.tsx src" /* 添加 eslint 脚本 */
      },
    }
    
  2. 运行
    npm run lint
    

8. 添加 prettier

  • 安装

    npm i -D prettier eslint-config-prettier eslint-plugin-prettier
    
    • prettier: 核心模块
    • eslint-config-prettier: 关闭所有不必要或可能跟prettier产生冲突的规则
    • eslint-plugin-prettier: 可以让eslint使用prettier规则进行检查
  • 配置

    根目录下.eslintrc.js文件中添加extends设置

    {
        // ...
        "extends": [
            // ...
            'plugin:prettier/recommended'
        ],
    }
    

    根目录下创建.prettierrc.json文件

    {
      "printWidth": 80,
      "tabWidth": 2,
      "semi": true,
      "singleQuote": true,
      "trailingComma": "none"
    }
    

    注意⚠️:

    1. 修改.prettierrc.json文件后,需要重启vscode才生效
    2. 如果配置后,配置不生效,尝试以下设置:

    image.png

    image.png

    image.png

9. 添加 huskylint-staged

  • 安装

    npm i -D lint-staged husky
    
  • 配置

    1. package.json中添加脚本

      npm set-script prepare "husky install"
      

      package.json文件的scripts中,就会自动添加prepareimage.png

    2. 初始化husky,将 git hooks钩子交由husky执行

      npm run prepare
      

      会在根目录创建.husky文件夹 image.png

    3. 配置package.json

    image.png

    1. 添加钩子pre-commit
    npx husky add .husky/pre-commit "npx lint-staged"
    

    package.json文件如下

    {
      "name": "webpack-react",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "start": "webpack-dev-server",
        "build": "webpack build",
        "eslint": "eslint --ext .js,.jsx,ts,.tsx src",
        "prepare": "husky install",
        "lint": "lint-staged"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@babel/core": "^7.18.9",
        "@babel/preset-env": "^7.18.9",
        "@babel/preset-react": "^7.18.6",
        "@babel/preset-typescript": "^7.18.6",
        "@types/react": "^18.0.15",
        "@types/react-dom": "^18.0.6",
        "@typescript-eslint/eslint-plugin": "^5.30.7",
        "@typescript-eslint/parser": "^5.30.7",
        "babel-loader": "^8.2.5",
        "clean-webpack-plugin": "^4.0.0",
        "css-loader": "^6.7.1",
        "eslint": "^8.20.0",
        "eslint-config-airbnb": "^19.0.4",
        "eslint-config-prettier": "^8.5.0",
        "eslint-plugin-import": "^2.26.0",
        "eslint-plugin-jsx-a11y": "^6.6.0",
        "eslint-plugin-prettier": "^4.2.1",
        "eslint-plugin-react": "^7.30.1",
        "eslint-plugin-react-hooks": "^4.6.0",
        "html-webpack-plugin": "^5.5.0",
        "husky": "^8.0.1",
        "less": "^4.1.3",
        "less-loader": "^11.0.0",
        "lint-staged": "^13.0.3",
        "prettier": "^2.7.1",
        "style-loader": "^3.3.1",
        "typescript": "^4.7.4",
        "webpack": "^5.73.0",
        "webpack-cli": "^4.10.0",
        "webpack-dev-server": "^4.9.3"
      },
      "dependencies": {
        "react": "^18.2.0",
        "react-dom": "^18.2.0"
      },
      "lint-staged": {
        "src/**": "eslint"
      }
    }
    
    

10. 配置commitlint

  • 作用:规范提交信息

  • 格式:git commit -m '类型: 描述性文字'

    类型 概念
    build 编译相关的修改,例如发布版本、对项目构建或者依赖的改动
    ci 持续集成修改
    docs 文档修改
    feat 新特性、新功能
    fix 修改bug
    perf 优化相关,比如提升性能、体验
    refactor 代码重构
    revert 回滚到上一个版本
    style 代码格式修改, 注意不是 css 修改
    test 测试用例修改
    chore 其他修改,比如改变构建流程、或者增加依赖库、工具等
  • 安装

npm i -D commitlint @commitlint/config-conventional
复制代码
  • 配置 package.json中配置commitlint
{
    // ...
    "commitlint": {
        "extends": [
            "@commitlint/config-conventional"
        ]
    }
}
复制代码
  • 添加钩子
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

git commit 就会触发提交规范的校验;

引用

  1. Glob 语法及解析
  2. npx 使用教程
  3. 为 vite 项目添加 eslint 和 prettier 和 husky

猜你喜欢

转载自juejin.im/post/7123761584035332109