Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
2xiao opened this issue Mar 14, 2024 · 0 comments
Open

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

2xiao opened this issue Mar 14, 2024 · 0 comments
Assignees

Comments

@2xiao
Copy link
Owner

2xiao commented Mar 14, 2024

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

pnpm init

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

// pnpm-workspace.yaml

packages:
  - 'packages/*'

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

3. 配置代码规范

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

安装:

pnpm i eslint -D -w

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

node_modules/*

初始化 eslint:

npx eslint --init

选项选择如下:

√ 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:

pnpm i -D -w @typescript-eslint/eslint-plugin, @typescript-eslint/parser, typescript

此时,自动生成了一个.eslintrc.json文件,它是对 eslint 的一些配置,将.eslintrc.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插件:

pnpm i @typescript-eslint/eslint-plugin -D -w

安装代码风格检查 prettier

pnpm i prettier -D -w

新建.prettierrc.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
pnpm i eslint-config-prettier eslint-plugin-prettier -D -w

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

"lint": "eslint --ext .ts,.jsx,.tsx --fix --quiet ./packages"

4. 配置 commit 规范检查

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

pnpm i husky -D -w

初始化huaky

npx husky install

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

npx husky add .husky/pre-commit "pnpm lint"

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

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

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

// .commitlintrc.js

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

commitlint集成到husky中:

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,并添加以下配置:

// 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. 选择打包工具

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

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

安装rollup:

pnpm i rollup -D -w

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


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

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

@2xiao 2xiao self-assigned this Mar 14, 2024
@2xiao 2xiao added documentation Improvements or additions to documentation good first issue Good for newcomers and removed documentation Improvements or additions to documentation good first issue Good for newcomers labels Mar 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant