项目框架搭建
info
- 选择项目结构
(Mono-repo)
- 定义开发规范
(eslint、tsc、prettier)
- 选择打包工具
(rollup)
- 相关代码可在 git tag v1.0 查看
选择项目结构
Multi-repo
- 每个服务和项目都有一个单独的存储库
- 团队可以自主工作; 个人的变更不会影响其他团队或项目的变更
- 管理员可以将访问控制限制到开发人员需要访问的项目或服务
- 良好的性能,因为有限的代码和较小的服务单元
- 开发人员可以很容易地实现
CD
和CI
,因为他们可以独立地构建服务 - 对库和其他常见代码的任何更改都应该定期同步,以避免以后出现问题
Mono-repo
- 一个组织的所有项目代码都使用一个中央存储仓库。
- 团队可以一起协作和工作,可以看到彼此的变化。
- 每个人都可以访问整个项目结构
- 如果项目规模不断增长,可能会导致并发大问题。
- 难以实现
持续部署(CD)
和持续集成(CI)
- 开发人员可以轻松地
共享库
、 和其他在中央存储库中更新的公共代码
很多大型项目都是用 Mono-repo
结构管理,比如 Vue
,Bable
,我们也选择 Mono-repo
搭建项目
选择 Mono-repo
工具
安装 yarn
npm install yarn -g
初始化 yarn
yarn init -y
添加 workspace 配置
在根目录的 package.json
中新增 workspace
和 private
属性 如下:
package.json
{
"private": true,
"workspaces": ["packages/*"],
"type": "module",
"scripts": { "test": 'echo "Error: no test specified" && exit 1' },
"author": "",
"license": "MIT",
"packageManager": "yarn@1.22.22",
}
package.json
文件定义了工作空间的根目录。也就是说, packages
目录下的文件就是 Mono-repo
的子项目。
配置 .gitignore
新增 .gitignore
文件,忽略以下的文件:
.gitignore
.idea/
.vscode/
node*modules/
build
*.tgz
my-app\_
template/src/**tests**/**snapshots**/
lerna-debug.log
npm-debug.log*
yarn-debug.log*
yarn-error.log\*
/.changelog
.npm/
.Ds_Store
配置 ESLint
使用 eslint
代码规范检查
安装 eslint
yarn add eslint globals eslint-plugin-import-x typescript-eslint -D -W
新增 eslint 配置
.eslint.config.js
import { builtinModules } from "node:module";
import globals from "globals";
import importX from "eslint-plugin-import-x";
import tseslint from "typescript-eslint";
import eslint from "@eslint/js";
const DOMGlobals = ["window", "document"];
const NodeGlobals = ["module", "require"];
const banConstEnum = {
selector: "TSEnumDeclaration[const=true]",
message:
"Please use non-const enums. This project automatically inlines enums.",
};
export default tseslint.config(
eslint.configs.recommended,
{
files: ["**/*.js", "**/*.ts", "**/*.tsx"],
extends: [tseslint.configs.base],
plugins: {
"import-x": importX,
},
rules: {
"no-debugger": "error",
"no-console": ["error", { allow: ["warn", "error", "info"] }],
// most of the codebase are expected to be env agnostic
"no-restricted-globals": ["error", ...DOMGlobals, ...NodeGlobals],
"no-restricted-syntax": [
"error",
banConstEnum,
{
selector: "ObjectPattern > RestElement",
message:
"Our output target is ES2016, and object rest spread results in " +
"verbose helpers and should be avoided.",
},
{
selector: "ObjectExpression > SpreadElement",
message:
"esbuild transpiles object spread into very verbose inline helpers.\n" +
"Please use the `extend` helper from @vue/shared instead.",
},
{
selector: "AwaitExpression",
message:
"Our output target is ES2016, so async/await syntax should be avoided.",
},
{
selector: "ChainExpression",
message:
"Our output target is ES2016, and optional chaining results in " +
"verbose helpers and should be avoided.",
},
],
"sort-imports": ["error", { ignoreDeclarationSort: true }],
"import-x/no-nodejs-modules": [
"error",
{ allow: builtinModules.map((mod) => `node:${mod}`) },
],
// This rule enforces the preference for using '@ts-expect-error' comments in TypeScript
// code to indicate intentional type errors, improving code clarity and maintainability.
"@typescript-eslint/prefer-ts-expect-error": "error",
// Enforce the use of 'import type' for importing types
"@typescript-eslint/consistent-type-imports": [
"error",
{
fixStyle: "inline-type-imports",
disallowTypeAnnotations: false,
},
],
// Enforce the use of top-level import type qualifier when an import only has specifiers with inline type qualifiers
"@typescript-eslint/no-import-type-side-effects": "error",
"import-x/order": [
"error",
{
groups: [
"builtin",
"external",
"internal",
"sibling",
"parent",
"index",
"unknown",
],
"newlines-between": "always",
},
],
},
},
// Node scripts
{
files: ["eslint.config.js", "scripts/**", "packages/*/npm/*.js"],
languageOptions: {
globals: { ...globals.node },
},
rules: {
"no-restricted-globals": "off",
"no-restricted-syntax": ["error", banConstEnum],
"no-console": "off",
},
}
);
配置 Prettier
安装 代码风格检查 prettier
安装 prettier
yarn add prettier -D -W
新增 .prettierrc
新建 .prettierrc
配置文件,添加配置:
.prettierrc
{
"printWidth": 100,
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"htmlWhitespaceSensitivity": "strict",
"endOfLine": "auto",
"quoteProps": "as-needed",
"jsxSingleQuote": true,
"arrowParens": "avoid"
}
在 package.json
的 "scripts"
中增加 lint
对应的执行脚本:
package.json
"lint": "eslint --ext .ts,.jsx,.tsx --fix --quiet ./packages"
配置 typescript
安装 typescript
yarn add typescript @types/node -D -W
新增 tsconfig.json
tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"rootDir": ".",
"target": "esnext",
"module": "esnext",
"lib": ["dom", "dom.iterable", "esnext"],
"moduleResolution": "node",
"strict": true,
"allowJs": true,
"removeComments": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"types": ["node"],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"paths": {
"react": ["packages/react"],
"shared": ["packages/shared"],
"react-reconciler": ["packages/react-reconciler"]
}
},
"include": ["packages/**/*.ts", "packages/**/*.d.ts"],
"exclude": ["node_modules"]
}
选择打包工具(rollup)
因为我们要开发的是一个库,而不是业务代码。希望工具尽可能简洁,打包产物可读性高,所以选择 rollup
。
安装 rollup
yarn add rollup -D -W
新建文件夹 scripts/rollup
,用于放所有的打包脚本。