基于 git submodule + lerna 的多项目工程

目录

第一篇:基于 lerna 的多项目工程

本文概要

本文主要是为了说明如何使用lerna在工程里管理多个依赖包及多个终端项目。并梳理一个基本的项目结构

额外知识点

lerna

lerna github
本文就不扩展了,有兴趣的同学可以看下

demo

https://github.com/ignous/project-demo

前言:为什么要建立单工程多项目

我们同时有 web + h5 + 后台的前端系统,3个项目分别部署,但是又有通用的部分。比如

  1. 登陆,3个系统是同样的登陆系统
  2. 直播。视频播放
  3. 文件上传系统,因为使用了第三方直穿的方式,需要前端和第三方api有紧密的操作。

有各种各样相同的逻辑,但是又需要在三端呈现不同的ui。

重复书写多套肯定不可取,这样会带来大量的更新和维护难度。

当然方案还有npm,把公用模块发布成npm包的形式也是我们尝试过的方案,但是业务永远是多变的,npm包发布和更新版本带来的复杂度,会导致我们在联调和测试时发布多个beta版本,比如测试发现了个bug,你要修是不是又要升一个版本,交互视觉做一些细节调整又是一个版本。最后发现可能有30%甚至50%的时间用于版本的发布和更新。

基于这些原因我们就考虑是不是有更好的办法解决问题~

基于lerna的单工程多项目文件结构

这是我们思考的一个方案,单个工程,单个仓库,天生就解决的发布的问题,但是如何同时让多个客户端项目并存,我们采用了lerna

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root/
├── packages/ // 这里放公共模块
│ ├── account/ // 帐号模块
│ │ ├── src
│ │ │ └── ... // 功能代码
│ │ ├── index.js
│ │ └── package.json
│ └── 其他模块/ // 其他模块
│ └── package.json
├── clients/ // 这里放各个客户端,如web,h5,admin
│ ├── web/
│ │ ├── src/
│ │ │ └── ... // 这里就和平时的一样了
│ │ ├── babel.config.js // babel
│ │ ├── package.json
│ │ └── webpack.config.js // webpack 配置
│ ├── h5/
│ │ └── package.json
│ └── 其他项目/
│ └── package.json
├── .eslintrc.js // 所有项目统一的eslint配置,不用担心每个项目规则不一样了~
├── lerna.json // lerna 配置
└── package.json //

lerna配置

1
2
3
4
5
6
{
"packages": [
"packages/*",
"clients/*"
]
}

设置lerna中的包含 packagesclients文件夹下的项目

根目录下package.json的配置

1
2
3
4
5
6
{
scripts: {
"setup": "lerna link && lerna bootstrap", // 执行link关联项目及bootstrap安装项目中所有的依赖
"dev": "lerna run dev --stream"
}
}

这样我们就可以在根目录运行 npm run setup 完成所有包的安装和关联啦

npm run dev的命令后面会讲到,我们先来看下具体子项目的配置

packages中公共模块的配置

公共项目的package.json

account 模块为例

1
2
3
4
5
6
7
8
9
10
11
{
"name": "@packages/account",
"main": "index.js",
"files": [
"src",
"index.js",
"package.json"
],
"scripts": {
}
}

其实只是配置了namemain,都是npm的基本配置

如何在clients项目中使用公共模块(以web为例)

  1. clients/web/package.json 中添加基本配置

    1
    2
    3
    4
    5
    6
    {
    "name": "@clients/web",
    "script": {
    "dev": "webpack-dev-server --host 0.0.0.0"
    }
    }
  2. 添加依赖 继续编辑clients/web/package.json

    1
    2
    3
    4
    5
    {
    "dependencies": {
    "@packages/account": "^1.0.0",
    }
    }
  3. 根目录运行 npm run setup 或者 lerna link 进行关联的安装

  4. clients/web/src/main.js 添加代码

    1
    2
    3
    import account from '@packages/account';
    account.getName();
  5. 运行 npm run dev -- --scope @clients/web 启动服务查看效果

和使用普通的npm包一样简单方便

ok,这样包共用就很简单了,web和h5就可以同时用一个帐号逻辑啦。

webpack.config.js配置

但是这里还有一个小问题~

在web项目里我们用 webpack 编译,但是 @packages/* 在node_modules里,会默认被babel-loader 忽略,所以需要加个配置

babel-loader添加配置

1
2
3
4
5
6
7
8
9
10
{
loader: 'babel-loader',
"include": [
"src",
path.resolve(__dirname, '../../packages/')
],
"exclude": [
"dist"
],
}

include 里的地址必须是包的实际地址, node_modules里的是link,直接使用会导致匹配不正确的

配置完成

可以直接在根目录运行npm run dev -- --scope @clients/web启动web项目的开发服务啦

也可以运行npm run dev 同时启动web+h5项目的开发服务啦