通过 Lerna 创建自己的 eslint 配置包

  最近在写一个eslint config的整合包,因为有不同语言,会发多个 npm 包,通过 Lerna 来管理多包发布,它优化了使用 git 和 npm 管理多包存储库的工作流,Vue、Babel、React 都有使用 Lerna。这里记录下使用过程中的一些点。

一、两种工作模式

1.1、固定模式

  Fixed/Locked mode,Vue,Babel 都是用这种,在 publish 的时候,会依据lerna.json文件里面的"version": "0.0.1"进行增加,只选择一次,其他有改动的包自动更新版本号。

1.2、独立模式

  Independent mode,执行lerna init --independent命令初始化项目,lerna.json文件里面会设置"version": "independent"。每次 publish 时,会得到一个提示符,提示每个已更改的包,以指定是补丁、次要更改、主要更改还是自定义更改(x.y.z)。

二、初始化

  新建一个文件夹eslint-config-liuxy0551,并进入该文件夹;为了方便 github action,安装 lerna 到开发环境:

1
2
npm init -y
yarn add lerna -D

  因为 lerna 经常需要用到,我们全局安装下:

1
yarn global add lerna

  安装完成后输入lerna -v查看版本号:

1
lerna init

  我们使用固定模式,然后进入packages文件夹初始化几个不同语言对应的 eslint config 包:

1
2
3
4
5
6
7
8
9
10
11
cd packages
mkdir basic prettier typescript

cd basic
npm init -y
cd ../prettier
npm init -y
cd ../react
npm init -y
cd ../typescript
npm init -y

  项目结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
eslint-config-liuxy0551
├─lerna.json
├─package.json
├─result.txt
├─yarn.lock
├─packages
| ├─typescript
| | └package.json
| ├─react
| | └package.json
| ├─prettier
| | └package.json
| ├─basic
| | └package.json

  按照约定 Shareable Configs,包名应该以eslint-config-开头,例如:eslint-config-liuxy0551-basic。依次将 packages 下的几个 package.json 中的 name 改成如:@liuxy0551/eslint-config-liuxy0551-basic,version 改成 0.0.0。

  每个子 package 都有自己的 node_modules,通过如下设置,就可以只在根目录创建 node_modules,只有开启了 private 的项目才能使用 workspaces。依次修改根目录的 package.json 和 lerna.json,添加以下配置项:

1
2
3
4
"private": true,
"workspaces": [
"packages/*"
]
1
2
"useWorkspaces": true,
"npmClient": "yarn"

三、绑定 git 和 npm

  接下来与远程仓库绑定,并登录 npm:

1
git remote add origin git@github.com:liuxy0551/eslint-config-liuxy0551.git
1
npm whoami

注意
如果上述命令报错,排查 npm 源: npm config ls
设置 npm 官方源: npm config set registry https://registry.npmjs.org/
如果未登录则执行npm login登录

四、配置内容

  在 packages/basic 文件夹下新建 index.js,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
module.exports = {
extends: [
'airbnb',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:eslint-comments/recommended',
'plugin:yml/recommended',
'prettier',
],
plugins: ['html'],
rules: {

},
}

  rules对象就是我们可以自己改动的配置项,在Airbnb/JavaScript仓库中的 https://github.com/airbnb/javascript/issues/1089,告诉了我们有哪些规则可以被修改。

五、lerna 命令

5.1、创建一个包

lerna create <包名> [存放的目录]

1
lerna create packageName

5.2、查看当前列表

1
lerna list

5.3、增加本地或者远程 package 作为当前项目 packages 里面的依赖

lerna add [@version] [--scope=localPackageName] [-D] [--exact]

  • -D 表示安装到 devDependencies
  • –exact 表示安装准确版本,不带 ^

注意
以下基于node 12版本安装插件,需要兼容低版本的可以在插件后加上版本号

1
lerna add eslint
1
2
3
4
5
6
7
8
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-basic eslint-loader
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-basic eslint-config-airbnb
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-basic eslint-plugin-eslint-comments
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-basic eslint-plugin-html
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-basic eslint-plugin-import
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-basic eslint-plugin-node
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-basic eslint-plugin-promise
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-basic eslint-plugin-sort-requires

  加上--scope=表示给本地指定的包安装依赖,也可以 cd 到这个包的文件夹下安装,就不用加--scope=了;不加则是给所有子包都安装该依赖。

1
2
3
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-typescript @liuxy0551/eslint-config-liuxy0551-basic
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-typescript @typescript-eslint/eslint-plugin
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-typescript @typescript-eslint/parser
1
2
3
4
5
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-react @liuxy0551/eslint-config-liuxy0551-typescript
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-react eslint-plugin-jest
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-react eslint-plugin-jsx-a11y
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-react eslint-plugin-react
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-react eslint-plugin-react-hooks
1
2
3
4
5
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-prettier @liuxy0551/eslint-config-liuxy0551-react
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-prettier prettier
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-prettier prettier-plugin-jsdoc
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-prettier eslint-config-prettier
lerna add --scope=@liuxy0551/eslint-config-liuxy0551-prettier eslint-plugin-prettier

5.4、安装依赖

  因为我们指定过使用 yarn,直接执行yarn install就会把所有包的依赖安装到根目录的 node_modules。

1
lerna bootstrap

5.5、删除依赖

1
lerna clean --scope=特定的某个包

  和rm -rf node_modules功能一致,--scope=表示指定包,不会移除根目录的 node_modules。

5.6、建立软链接

lerna link [--force-local]

1
lerna link --force-local

  类似npm link的使用,–force-local 表示不论本地的版本是否符合,都使用本地的版本。

5.7、列出更新的包

1
lerna changed

  列出改动过的包,发布时只更新改动过的包。

5.8、指定版本号

1
lerna version 0.0.2 -y

  需要本地分支和远程分支无差别。

5.9、发布

lerna publish [--conventional-commits -y]

1
lerna publish

  需要先执行 git commit,会打 tag,--conventional-commits表示生成 changelog。如果包名是带 scope 的格式,如:@liuxy0551/eslint-config-liuxy0551,则需要在 package.json 中添加配置项,packages 下的每个包都需要加:

1
2
3
"publishConfig": {
"access": "public"
}

六、发布整合包

lerna publish 只会发布 packages 下的包,当前文件夹并不会作为一个包发布

  在 packages 文件夹下新建一个main,作为入口:

1
2
3
4
5
cd packages
mkdir main

cd main
npm init -y

  将 main 下 package.json 中的 name 改成如:@liuxy0551/eslint-config-liuxy0551,version 改成 0.0.0。添加依赖:

1
2
lerna add --scope=@liuxy0551/eslint-config-liuxy0551 eslint@^7.0.0
lerna add --scope=@liuxy0551/eslint-config-liuxy0551 @liuxy0551/eslint-config-liuxy0551-react

  在 packages/main 文件夹下新建 index.js,内容如下:

1
2
3
4
5
6
/** Export all */
module.exports = {
extends: [
'@liuxy0551/eslint-config-liuxy0551-react',
]
}

  lerna 不会发布标记私有的项目,需要修改根目录 package.json 中的配置"private": false

1
npm whoami
1
lerna publish

  访问https://www.npmjs.com/search?q=@liuxy0551/eslint-config-liuxy0551 可以看到发布的包。

常见错误
第一次发布失败后出现 Current HEAD is already released
执行lerna publish from-package

  可选步骤删除测试发布的 npm 包:

1
2
3
4
5
npm unpublish @liuxy0551/eslint-config-liuxy0551-react --force
npm unpublish @liuxy0551/eslint-config-liuxy0551-typescript --force
npm unpublish @liuxy0551/eslint-config-liuxy0551-prettier --force
npm unpublish @liuxy0551/eslint-config-liuxy0551-basic --force
npm unpublish @liuxy0551/eslint-config-liuxy0551 --force

参考资料

1、Lerna 中文教程详解
2、如何创建自己的ESLint配置包
3、Lerna --多包存储管理工具(一)

以上

随笔标题:通过 Lerna 创建自己的 eslint 配置包

随笔作者:刘先玉

发布时间:2022年03月23日 - 17:24:04

最后更新:2022年03月23日 - 17:24:04

原文链接:https://liuxianyu.cn/article/my-eslint-config-by-lerna.html