因为公司要做的项目比较多,项目之间又会相互依赖。目前分为pc后台,pc商城,uniapp项目等等。所以为了代码的复用和代码的规范提交,决定引入pnpm来创建Monorepo项目。
Monorepo 简单的说,是指将公司的所有代码放到一个 Git / Mercurial / Subversion 的代码仓库中。对于很多没听说过这个概念的人而言,无异于天方夜谭。Git 仓库不应该是每个项目一个吗?对于很多用 monorepo 的公司,他们的 Git 仓库中不止有自己的代码,还包括了很多的依赖。基本上,只要把 monorepo 用 Git 拖下来,跑一下 ./scripts/install,就可以直接用 Buck / Bazel (在安装脚本中就装到了本地)编译仓库中的所有项目,并且提交修改(安装脚本配置好了代码提交环境,如果用的 Phabricator 的话,Gerrit 不用)
npm/yarn 采用了直接平铺的方式,而 pnpm 则是采用 .pnpm 隐藏目录隐藏真实的平铺结构,在使用链接(symbollink)的方式将真实安装的目录映射到 node_modules 下
因为我们把项目剥离为业务组件层,通用api层,项目三层。项目引入通用api和业务组件相互依赖,所以我们搭建了内网npm。内网npm牵扯到了发包和版本号的问题,所以引入workspace 让项目内部进行引用类似这样
"devDependencies":{
"**":"workspace:*"
}
第一步
我们在 packages 中新建以下几个目录。
├── packages
│ ├── ui-uniapp
│ ├── common-api
第二步
在根目录新建 pnpm-workspace.yaml,内容如下
packages:
- 'packages/*'
第三步
npm init
生成package.json后
第四步
强制pnpm安装依赖
执行工程自身 preinstall
当前 npm 工程如果定义了 preinstall 钩子此时会被执行。
"scripts": {
"preinstall": "node preinstall.js",
},
preinstall.js 中
if (!/pnpm/.test(process.env.npm_execpath || '')) {
console.warn(
`\u001b[33mThis repository requires using pnpm as the package manager ` +
` for scripts to work properly.\u001b[39m\n`
)
process.exit(1)
}
第五步
新增eslint stylelint prettier检测
"scripts": {
"preinstall": "node ./scripts/preinstall.js",
"lint-staged": "lint-staged",
"lint:eslint": "eslint --cache --max-warnings 0 \"packages/**/*.{vue,ts,tsx}\" --fix",
"lint:prettier": "prettier --write \"packages/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"",
"lint:stylelint": "stylelint --cache --fix \"**/*.{vue,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
},
"dependencies": {
"stylelint": "^14.0.1",
"stylelint-config-html": "^1.0.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-standard": "^23.0.0",
"stylelint-order": "^5.0.0",
"eslint": "^8.1.0",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"eslint-config-prettier": "^8.3.0",
"eslint-define-config": "^1.1.2",
"eslint-plugin-jest": "^25.2.2",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-vue": "^8.0.3",
"vue-eslint-parser": "^8.0.1",
"prettier": "^2.5.1",
"lint-staged": "^12.3.4",
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"prettier --write"
],
"{!(package)*.json,*.code-snippets,.!(browserslist)*rc}": [
"prettier --write--parser json"
],
"package.json": [
"prettier --write"
],
"*.vue": [
"prettier --write",
"stylelint --fix"
],
"*.{scss,less,styl,html}": [
"stylelint --fix",
"prettier --write"
],
"*.md": [
"prettier --write"
]
}
第六步
增加git钩子
我的钩子命令是 pnpm run lint-staged
husky
npm install husky --save-dev
npm set-script postinstall "husky install"
npm run postinstall
npx husky add .husky/pre-commit " pnpm run lint-staged"
git add .husky/pre-commit
第七步
引入提交方式
安装依赖 commitizen和cz-conventional-changelog
"scripts": {
"commit": "cz"
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},