Monorepo
Monorepo工程管理方案
mutirepo vs monorepo
- mutirepo : 一个包对应一个仓库
- monorepo : 多个包对应一个仓库
常见monorepo管理工具: pnpm- npm
- yarn
- Lerna
- Nx
- Rush
- ……
pnpm monorepo
1 | |
1 | |
在工程根目录下执行初始化
1 | |
环境版本锁定
1 | |
1 | |
TypeScript
1 | |
1 | |
1 | |
代码风格与质量检查
prettier
1 | |
1 | |
prettier忽略项
1 | |
1 | |
prettier脚本命令
1 | |
ESLint
1 | |
| 类别 | 库名 |
|---|---|
| 核心引擎 | eslint |
| 官方规则集 | @eslint/js |
| 全局变量支持 | globals |
| TypeScript支持 | typescript-eslint |
| 类型定义(辅助) | @types/node |
| Prettier集成 | eslint-plugin-prettier, eslint-config-prettier |
| Vue支持 | eslint-plugin-vue |
1 | |
拼写检查
VsCode插件:Code Spell Checker
1 | |
1 | |
git提交规范
1 | |
commitizen
用于检查提交
1 | |
- @commitlint/cli 是 commitlint 工具的核心
- @commitlint/config-conventional 是基于 conventional commits 规范的配置文件
- commitizen 提供一个交互式撰写commit信息的插件
- cz-git 是国产工具
1 | |
配置 cz-git
1 | |
husky
连接 git hook 自定义 提交前后事件
1 | |
配置
1 | |
lint-staged
检查暂存区文件
1 | |
配置命令
1 | |
1 | |
公共库打包
安装rollup
1 | |
@rollup/plugin-node-resolve: 解析 node_modules 中的依赖@rollup/plugin-commonjs: 将 CommonJS 模块转为 ESMrollup-plugin-typescript2: 让 Rollup 支持 TS 编译@rollup/plugin-terser: 压缩和混淆@vitejs/plugin-vue: 支持SFC编译rollup-plugin-postcss: 处理css代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111// scropts/buildBase.js
import path from "node:path";
import URL from "node:url";
import fs from "node:fs";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "rollup-plugin-typescript2";
import vue from "@vitejs/plugin-vue";
import postcss from "rollup-plugin-postcss";
const __filename = URL.fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const packages = ["utils", "components"];
function getPackageRoots() {
return packages.map(pkg => path.resolve(__dirname, "../packages", pkg));
}
async function packageJson(root) {
const jsonPath = path.resolve(root, "package.json");
const content = await fs.promises.readFile(jsonPath, "utf-8");
return JSON.parse(content);
}
async function getRollupConfig(root) {
const config = await packageJson(root);
const tsconfig = path.resolve(root, "tsconfig.json");
const { name, formats } = config.buildOptions || {};
const dist = path.resolve(root, "./dist");
const entry = path.resolve(root, "./src/index.ts");
const rollupOptions = {
input: entry,
sourcemap: true,
external: ["vue"],
plugins: [
nodeResolve(),
commonjs(),
typescript({
tsconfig,
compilerOptions: {
outDir: dist
}
}),
vue({
template: {
compilerOptions: {
// 自定义转换函数,在生成 AST 时移除特定属性
nodeTransforms: [
node => {
if (node.type === 1 /* NodeTypes.ELEMENT */) {
// 过滤掉所有 data-testid 属性
node.props = node.props.filter(prop => {
if (prop.type === 6 /* NodeTypes.ATTRIBUTE */) {
return prop.name !== "data-testid";
}
return true;
});
}
}
]
}
}
}),
postcss()
],
dir: dist
};
const output = [];
for (const format of formats) {
const outputItem = {
format,
file: path.resolve(dist, `index.${format}.js`),
sourcemap: true,
globals: {
vue: "Vue"
}
};
if (format === "iife") {
outputItem.name = name;
}
output.push(outputItem);
}
rollupOptions.output = output;
// watch options
rollupOptions.watch = {
include: path.resolve(root, "src/**"),
exclude: path.resolve(root, "node_modules/**"),
clearScreen: false
};
return rollupOptions;
}
export async function getRollupConfigs() {
const roots = getPackageRoots();
const configs = await Promise.all(roots.map(getRollupConfig));
const result = {};
for (let i = 0; i < packages.length; i++) {
result[packages[i]] = configs[i];
}
return result;
}
export function clearDist(name) {
const dist = path.resolve(__dirname, "../packages", name, "dist");
if (fs.existsSync(dist)) {
fs.rmSync(dist, { recursive: true, force: true });
}
}
1 | |
1 | |
统一测试
1 | |
Monorepo
https://jhyjhy.cn/posts/前端/Monorepo工程管理方案/41960/