本文首发于 https://mp.weixin.qq.com/s/nuSmPllrXQQC30YjTduk2g
更多资讯欢迎关注公众号:
前端架构师笔记
什么是 monorepo?以及和 multirepo 的区别是什么
关于这些问题,在之前的一篇介绍 lerna 的文章中已经详细介绍过,感兴趣的同学可以再回顾下。
简而言之,monorepo
就是把多个工程放到一个 git
仓库中进行管理,因此他们可以共享同一套构建流程、代码规范也可以做到统一,特别是如果存在模块间的相互引用的情况,查看代码、修改bug、调试等会更加方便。
pnpm
是新一代的包管理工具,号称是最先进的包管理器。按照官网说法,可以实现节约磁盘空间并提升安装速度和创建非扁平化的 node_modules 文件夹两大目标,具体原理可以参考 pnpm 官网。
pnpm
提出了 workspace
的概念,内置了对 monorepo
的支持,那么为什么要用 pnpm
取代之前的 lerna
呢?
这里我总结了以下几点原因:
$ npm install -g pnpm
v7版本的pnpm安装使用需要node版本至少大于v14.19.0,所以在安装之前首先需要检查下node版本。
为了便于后续的演示,先在工程根目录下新建 packages
目录,并且在 packages
目录下创建 pkg1
和 pkg2
两个工程,分别进到 pkg1
和 pkg2
两个目录下,执行 npm init
命令,初始化两个工程,package.json
中的 name
字段分别叫做 @qftjs/menorepo1
和 @qftjs/monorepo2
(PS:@qftjs是提前在npm上创建好的组织,没有的话需要提前创建)。
为了防止根目录被发布出去,需要设置工程工程个目录下 package.json
配置文件的 private
字段为 true
。
为了实现一个完整的例子,这里我使用了 father-build
对模块进行打包,father-build
是基于 rollup
进行的一层封装,使用起来更加便捷。
在 pkg1 和 pkg2 的 src 目录下个创建一个 index.ts
文件:
// pkg1/src/index.ts
import pkg2 from '@qftjs/monorepo2';
function fun2() {
pkg2();
console.log('I am package 1');
}
export default fun2;
// pkg2/src/index.ts
function fun2() {
console.log('I am package 2');
}
export default fun2;
分别在 pkg1 和 pkg2 下新增 .fatherrc.ts
和 tsconfig.ts
配置文件。
// .fatherrc.ts
export default {
target: 'node',
cjs: { type: 'babel', lazy: true },
disableTypeCheck: false,
};
// tsconfig.ts
{
"include": ["src", "types", "test"],
"compilerOptions": {
"target": "es5",
"module": "esnext",
"lib": ["dom", "esnext"],
"importHelpers": true,
"declaration": true,
"sourceMap": true,
"rootDir": "./",
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"baseUrl": "./",
"paths": {
"*": ["src/*", "node_modules/*"]
},
"jsx": "react",
"esModuleInterop": true
}
}
全局安装 father-build
:
$ pnpm i -Dw father-build
<