自己动手写 React——【1】项目框架搭建

深入理解 React 源码,带你从零实现 React v18 的核心功能,构建自己的 React 库。

电子书地址:2xiao.github.io/leetcode-js...

源代码地址:github.com/2xiao/my-re...

1. 选择项目结构

选择 Multi-repo 还是 Mono-repo?

  • Multi-repo 每个库都有独立的仓库,逻辑清晰,但协同管理会更繁琐;
  • Mono-repo 可以方便的协同管理不同独立的库的生命周期,但是会有更高的操作复杂度。

很多大型项目都使用 Mono-repo 结构管理,比如 Vue,Bable,我们也选择 Mono-repo。

2. 选择 Mono-repo 工具

简单工具:

  • npm workspace
  • Yarn workspace
  • pnpm workspace

专业工具:

  • nx
  • bit
  • turborepo
  • rush
  • nx
  • lerna

我们选择 pnpm,因为它相比其它打包工具,依赖安装更快,更规范(处理幽灵依赖问题)。

安装 pnpm

npm install -g pnpm

初始化pnpm

csharp 复制代码
pnpm init

在根目录新增 pnpm-workspace.yaml文件,并初始化,写入下面的代码:

yaml 复制代码
// pnpm-workspace.yaml

packages:
  - 'packages/*'

pnpm-workspace.yaml文件定义了工作空间的根目录,也就是说,packages 目录下的文件就是 Mono-repo 的子项目。

3. 配置代码规范

代码规范检查与修复,使用 eslint

安装:

css 复制代码
pnpm i eslint -D -w

新增.gitignore文件,忽略node_modules目录下的文件:

node_modules/*

初始化 eslint:

csharp 复制代码
npx eslint --init

选项选择如下:

vbnet 复制代码
√ How would you like to use ESLint?
· To check syntax and find problems

√ What type of modules does your project use?
· JavaScript modules (import/export)

√ Which framework does your project use?
· none

√ Does your project use TypeScript?
· Yes

√ Where does your code run?
· node

√ What format do you want your config file to be in?
· JSON

√ Would you like to install them now?
· Yes

√ Which package manager do you want to use?
· pnpm

如果报错,再执行下面的代码,手动安装这两个包和 typescript:

bash 复制代码
pnpm i -D -w @typescript-eslint/eslint-plugin, @typescript-eslint/parser, typescript

此时,自动生成了一个.eslintrc.json文件,它是对 eslint 的一些配置,将.eslintrc.json文件配置如下:

json 复制代码
// .eslintrc.json

{
	"env": {
		"browser": true,
		"es2021": true,
		"node": true,
		"jest": true
	},
	"extends": [
		"eslint:recommended",
		"plugin:@typescript-eslint/recommended",
		"prettier",
		"plugin:prettier/recommended"
	],
	"parser": "@typescript-eslint/parser",
	"parserOptions": {
		"ecmaVersion": "latest",
		"sourceType": "module"
	},
	"plugins": ["@typescript-eslint", "prettier"],
	"rules": {
		"prettier/prettier": "error",
		"no-case-declarations": "off",
		"no-constant-condition": "off",
		"@typescript-eslint/ban-ts-comment": "off",
		"@typescript-eslint/no-unused-vars": "off",
		"@typescript-eslint/no-var-requires": "off",
		"no-unused-vars": "off"
	}
}

安装 ts 的eslint插件:

css 复制代码
pnpm i @typescript-eslint/eslint-plugin -D -w

安装代码风格检查 prettier

css 复制代码
pnpm i prettier -D -w

新建.prettierrc.json配置文件,添加配置:

json 复制代码
// .prettierrc.json

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

prettier集成到eslint中,避免它和eslint冲突,其中:

  • eslint-config-prettier:覆盖eslint本身的规则配置
  • eslint-plugin-prettier:用prettier来接管修复代码,即eslint --fix
arduino 复制代码
pnpm i eslint-config-prettier eslint-plugin-prettier -D -w

package.json"scripts" 中增加 lint 对应的执行脚本:

json 复制代码
"lint": "eslint --ext .ts,.jsx,.tsx --fix --quiet ./packages"

4. 配置 commit 规范检查

安装husky,用于拦截 commit 命令:

css 复制代码
pnpm i husky -D -w

初始化huaky

npx husky install

将刚才实现的格式化命令pnpm lint纳入 commit 时husky将执行的脚本:

sql 复制代码
npx husky add .husky/pre-commit "pnpm lint"

使用commitlint堆 git 提交信息进行检查:

bash 复制代码
pnpm i commitlint @commitlint/cli @commitlint/config-conventional -D -w

新建配置文件.commitlintrc.js,指定规范集:

js 复制代码
// .commitlintrc.js

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

commitlint集成到husky中:

bash 复制代码
npx husky add .husky/commit-msg "npx --no-install commitlint -e $HUSKY_GIT_PARAMS"

这样之后所有的 commit 都必须符合规范集的格式:提交的类型: 摘要信息,即<type>: <subject>,例如:git commit -m "feat: project init"

常见的 type 值如下:

  • feat: 新功能
  • fix: 修复
  • docs: 文档变更
  • style: 代码格式
  • refactor: 重构
  • perf: 性能优化
  • test: 增加测试
  • revert: 回退
  • build: 打包
  • chore: 构建过程或辅助工具的变动

5. 配置 typescript

新建配置文件tsconfig.json,并添加以下配置:

json 复制代码
// tsconfig.json

{
	"compileOnSave": true,
	"include": ["./packages/**/*"],
	"compilerOptions": {
		"target": "ESNext",
		"useDefineForClassFields": true,
		"module": "ESNext",
		"lib": ["ESNext", "DOM"],
		"moduleResolution": "Node",
		"strict": true,
		"sourceMap": true,
		"resolveJsonModule": true,
		"isolatedModules": true,
		"esModuleInterop": true,
		"noEmit": true,
		"noUnusedLocals": false,
		"noUnusedParameters": false,
		"noImplicitReturns": false,
		"skipLibCheck": true,
		"baseUrl": "./packages",
		"paths": {
			"hostConfig": ["./react-reconciler/src/hostConfig.ts"]
		}
	}
}

6. 选择打包工具

有一个比较权威的网站bundlers.tooling.report/,比较了不同的打包工具的区别。

可以看到webpack是比较大而全的,但是我们要开发的是一个库,而不是业务代码,希望工具尽可能简洁,打包产物可读性高,所以选择rollup

安装rollup:

css 复制代码
pnpm i rollup -D -w

新建文件夹scripts/rollup,用于放所有的打包脚本。


至此,我们的项目框架就搭建完成了。

相关代码可在 git tag v1.1 查看,地址:github.com/2xiao/my-re...

相关推荐
undefined&&懒洋洋11 分钟前
Web和UE5像素流送、通信教程
前端·ue5
大前端爱好者2 小时前
React 19 新特性详解
前端
随云6322 小时前
WebGL编程指南之着色器语言GLSL ES(入门GLSL ES这篇就够了)
前端·webgl
随云6322 小时前
WebGL编程指南之进入三维世界
前端·webgl
无知的小菜鸡2 小时前
路由:ReactRouter
react.js
寻找09之夏3 小时前
【Vue3实战】:用导航守卫拦截未保存的编辑,提升用户体验
前端·vue.js
多多米10054 小时前
初学Vue(2)
前端·javascript·vue.js
柏箱4 小时前
PHP基本语法总结
开发语言·前端·html·php
新缸中之脑4 小时前
Llama 3.2 安卓手机安装教程
前端·人工智能·算法
hmz8564 小时前
最新网课搜题答案查询小程序源码/题库多接口微信小程序源码+自带流量主
前端·微信小程序·小程序