使用webpack搭建react项目开发环境

工作中搭建开发环境这种事情基本上都会使用公司已有的工具进行搭建,但是作为程序员在家手动捣鼓一些技术也是常有的事儿,这里记录下自己的一次开发环境搭建过程,以备后续查询。

明确项目依赖项

  • 使用sass写样式
  • typescript进行类型声明、检查
  • eslint对代码进行规范检查
  • react作为基础开发
  • 对git的commit进行提交前的规范
  • 环境变量可配置。使用.env文件控制环境变量
  • 开发环境热更新

前情提要

测试环境使用的是

  • pnpm 8.3.1
  • node v18.15.0
  • VSCode

测试项目文件树

.
├── .babelrc.js
├── .env
├── .eslintrc.js
├── .gitignore
├── .husky
│   ├── _
│   │   └── husky.sh
│   └── commit-msg
├── commitlint.config.js
├── package.json
├── pnpm-lock.yaml
├── public
│   └── index.html
├── src
│   ├── index.tsx
│   ├── test.module.scss
│   └── test.tsx
├── tsconfig.json
├── typings
│   └── index.d.ts
└── webpack.config.js

初始化项目

pnpm init
git init # husky自动安装需要git

安装依赖

依赖有很多,这里拆开来记录

.env配置

使用.env文件配置环境变量需要安装dotenv-cli,在package.jsonscripts中的命令中使用

// 比如
scripts: {
    start: 'dotenv -e .env 其他的项目启动命令'
}

以将.env文件中的变量赋值到process.env

pnpm i -D dotenv-cli

webpack

除了基本的webpakck,还想使用其server服务以在开发环境热更新项目,所以还需要webpack-dev-server

pnpm i -D webpack webpack-dev-server webpack-cli

解析sass

解析sass的时候需要三种依赖,分别是style-loadercss-loadersass-loader

  • sass-loader用来编译.scss.sass文件为css
  • css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样。且可配置CSS Module
  • style-loadercss插入到dom
  • sass 解析sass语法
pnpm i -D sass style-loader css-loader sass-loader

解析ts、tsx

使用babel-loader解析tstsx。那就需要安装

  • @babel/core
  • babel-loader
  • @babel/preset-typescript
pnpm i -D @babel/core babel-loader @babel/preset-typescript

解析react

因为要使用react框架进行项目开发,所以react的依赖包必不可少。还有需要让reactjsx可以被编译,所以解析react总共需要的依赖有

  • react
  • react-dom
  • @babel/preset-react 编译jsx
  • @types/react
  • @types/react-dom
pnpm i -D react react-dom @babel/preset-react @types/react @types/react-dom

代码规范检查

一般使用eslint进行代码规范检查。可以去官网查看自动下载安装并配置.eslintrc.js文件的命令,这里举出npm的命令npm init @eslint/config。但是本次测试环境使用的是pnpm,不妨使用pnpm init @eslint/config命令看看是否可行。

image.png
啊哦,不行的。不过有给出另一个命令,可以执行试试看。

pnpm create @eslint/config

image.png

根据图片可以看到,根据需要选完对应的选项后,并选择pnpm立即安装,就会自动去下载

  • @typescript-eslint/eslint-plugin
  • @typescript-eslint/parser
  • eslint
  • eslint-plugin-react

且会在项目根目录中生成.eslintrc.js文件。

另外,考虑到平时的代码开发,在编译的时候就会有检查,所以还需要安装eslint-webpack-plugin搭配webpack使用

pnpm i -D eslint-webpack-plugin

git commit提交规范检查

使用husky控制git hooks在对应生命周期需要执行的脚本,commitlint进行规范检查。
其中@commitlint/config-conventionalcommitlint官方给的一个常用配置

pnpm i -D husky @commitlint/cli @commitlint/config-conventional

文件配置

配置过程中需要注意的事项都在文件中有注释,可以关注下。

package.json

.env文件中的变量赋值给process.env,然后使用webpack-dev-server启动项目

"scripts": {
    "start": "dotenv -e .env webpack-dev-server"
 },

完整的package.json文件内容如下。可以直接拿过去用,但是huskycommit-msg需要自己手动或使用命令添加

{

  "name": "test-dev",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "dotenv -e .env webpack-dev-server",
    "prepare": "husky install"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.22.5",
    "@babel/preset-react": "^7.22.5",
    "@babel/preset-typescript": "^7.22.5",
    "@commitlint/cli": "^17.6.5",
    "@commitlint/config-conventional": "^17.6.5",
    "@types/react": "^18.2.11",
    "@types/react-dom": "^18.2.4",
    "@typescript-eslint/eslint-plugin": "^5.59.9",
    "@typescript-eslint/parser": "^5.59.9",
    "babel-loader": "^9.1.2",
    "css-loader": "^6.8.1",
    "dotenv-cli": "^7.2.1",
    "eslint": "^8.42.0",
    "eslint-plugin-react": "^7.32.2",
    "eslint-webpack-plugin": "^4.0.1",
    "husky": "^8.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "sass": "^1.63.3",
    "sass-loader": "^13.3.2",
    "style-loader": "^3.3.3",
    "webpack": "^5.86.0",
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^4.15.1"
  }
}

.env

# 给webpack-dev-server用
PORT=9000
# 给webpack的mode属性用
MODE=development

.eslintrc.js

这里先配置下.eslintrc.js,避免配置下面的文件时,文件爆红,还以为发生了什么可怕的事情?

module.exports = {

  env: {
    browser: true,
    es2021: true,
  },
  extends: [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended",
    // react17之后使用jsx函数实现jsx到dom的转换
    "plugin:react/jsx-runtime",
  ],
  parser: "@typescript-eslint/parser",
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
  },
  plugins: ["@typescript-eslint", "react"],
  // 忽略根目录下的所有以.js为后缀的文件。即不对其进行检查
  ignorePatterns: ["/*.js"],
  rules: {},
};

webpack.config.js

const path = require("path");
const extensions = [".tsx", ".ts", ".js", ".jsx"];
const ESLintWebpackPlugin = require("eslint-webpack-plugin");

module.exports = {
  mode: process.env.MODE, // .env文件里来的
  entry: "./src/index.tsx",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              modules: {
                localIdentName: "[name]__[local]--[hash:base64:5]",
              },
            },
          },
          "sass-loader",
        ],
      },
      {
        test: /\.(ts|tsx)$/,
        exclude: /node_modules/,
        use: "babel-loader",
      },
    ],
  },
  resolve: {
    extensions,
  },
  devServer: {
    open: true,
    port: process.env.PORT,
    client: {
      overlay: {
        // 当有警告信息时不显示到页面上。可以制造令eslint发出警告的代码测试效果
        warnings: false,
      },
    },
  },
  plugins: [
    /* 
      下面的options配置与.eslintrc.js文件的关系可以理解为
      - .eslintrc.js是给eslint用的。eslint会在整个项目上使用该配置,前提是使用eslint命令
      - options配置是给eslint-webpack-plugin用的。
        - eslint-webpack-plugin插件内部会在options配置的基础上使用.eslintrc.js文件
        - 假如要检查.ts文件,eslint-webpack-plugin的options没有配置.ts文件的检查,
          则.eslintrc.js配置就不会在.ts文件上起效。所以如果想要在编译时检查除了.js之外的其他文件,
          需要手动配置options选项
    */
    new ESLintWebpackPlugin({
      // 编译时要检查的根目录
      context: path.resolve(__dirname, "src"),
      // 编译时要检查的文件后缀
      extensions,
    }),
  ],
};

这里eslint-webpack-pluginoptions配置与.eslintrc.js文件之间的关系理解如下

options配置与.eslintrc.js文件的关系可以理解为
  - .eslintrc.js是给eslint用的。eslint会在整个项目上使用该配置,前提是使用eslint命令
  - options配置是给eslint-webpack-plugin用的。
    - eslint-webpack-plugin插件内部会在options配置的基础上使用.eslintrc.js文件
    - 假如要检查.ts文件,eslint-webpack-plugin的options没有配置.ts文件的检查,
          则.eslintrc.js配置就不会在.ts文件上起效。所以如果想要在编译时检查除了.js之外的其他文件,
          需要手动配置options选项

.babelrc.js

module.exports = {

  presets: [
    [
      "@babel/preset-react",
      {
        // react17之后,使用jsx函数进行jsx到dom的转换。可以不用在.tsx文件中使用`import React from 'react',也可以运行代码`
        runtime: "automatic", 
      },
    ],
    "@babel/preset-typescript",
  ],
};

tsconfig.json

配置的时候,如果文件爆红,可以先注释掉include属性。因为代码文件还没有创建,typescript识别不到。

{

    "compilerOptions": {
        "jsx": "react-jsx" // react17之后,使用jsx函数进行jsx到dom的转换。可以不用在.tsx文件中使用`import React from 'react',也可以运行代码`
    },
    // 哪些文件可被ts识别。
    "include": ["src", "typings"]
}

commilint.config.js

module.exports = { extends: ["@commitlint/config-conventional"] };

husky

husky这边没有配置文件,但是需要安装脚本。操作如下

image.png

根据图片执行命令pnpm dlx husky-init && pnpm install,会在根目录生成

.husky
├── _
│   ├── .gitignore 
│   └── husky.sh
└── commit-msg

其中

  • .gitignore文件需要被删除,否则无法上传到远端
  • commit-msg的位置原本是pre-commit,被删除了,因为我暂时不用?。然后使用下面的命令添加了commit-msg
pnpx husky add .husky/commit-msg 'pnpm commitlint --edit "$1"'

各种git hooks的执行及生命周期可以去git官网查看了解。

注意:huskycommitlint配置完,可以通过下面的命令进行测试

git add .
git commit -m "fdfasdf" # 会在终端报错
git commit -m "feat: fasdfas" # pass

大致结果如下。具体的提交规范,可以去这里查看

image.png

测试文件

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>Document</title>
</head>
<body>
    <div id="app"></div>
    <!-- webpack中配置的名称 -->
    <script src="bundle.js"></script>
</body>
</html>

typings/index.d.ts

// 将scss文件的import声明为module,避免import对应的.scss文件时爆红
declare module "*.scss"

src/test.module.scss

.color {
    color: red;
    font-weight: 900;
}

src/test.tsx

import styles from './test.module.scss'
export default function Test() {
  return (
    <div className={styles.color}>test</div>
  )
}

src/index.tsx

import { createRoot } from 'react-dom/client'
import App from './test'

createRoot(document.getElementById('app')).render(<App/>)

测试运行

pnpm start

命令执行完成后,可以在浏览器看到下面的内容

image.png

项目的基础配置到此完成,感谢记录的我自己☕️

参考链接

sass-loader

css-loader

style-loader

eslint

husky

react-in-jsx-scope原因

tsconfig.json中的jsx

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYpsR7YV' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片