返回
随着“”的文章发布,收到了很多建设性的反馈,特地把大家好的提议在这里做下实践和补充!
以下操作是在第三方库https://github.com/Heyff12/reuseParent执行的操作
git submodule add https://github.com/Heyff12/reuseSon.git
此时,push 代码,在第三库中,reuseSon 只是一个外链,并不包含真实代码。
备注:
git clone https://github.com/Heyff12/reuseParent
git submodule init
git submodule update
# 合并上面两行命令 git submodule update --init
替代命令
git clone --recurse-submodules https://github.com/Heyff12/reuseParent
拉取子库最新代码
git submodule update --remote
需要在 reuseSon 目录下,单独 commit /push
git push origin HEAD:master
在子库可以通过 pull 获取最新改动
在 app.module.ts 中引入
import { TheButtonComponent } from "reuseSon/src/app/components/the-button/the-button.component";
在文件 tsconfig.app.json 中增加编译配置
"include": [
"reuseSon/src/app/components/**/*.ts",
],
"exclude": [
"reuseSon/src/app/components/**/*.spec.ts"
]
跟使用 subtree 比较起来,效果一样。
优点:
缺点:
如果使用 subtree 或者 dubmodule 的方式,最佳操作:
建议(个人观点):
subtree 和 submodule 的目的都是用于 git 子仓库管理,二者的主要区别在于,subtree 属于拷贝子仓库,而 submodule 属于引用子仓库。
维度 | subtree | submodule | 优劣对比 |
---|---|---|---|
空间占用 | subtree 在初始化 add 时,会将子仓库 copy 到父仓库中,并产生至少一次 merge 记录。所以会占用大量父仓库空间 | submodule 在初始化 add 时,会在父仓库新建一个 .gitmodules 文件,用于保存子仓库的 commit hash 引用。所以不会占用父仓库空间 | submodule 更优 |
clone | subtree add 至父仓库之后,后续的 clone 操作与单一仓库操作相同 | 后续 clone 时 submodule 还需要 init/update 操作,且 submodule 子仓库有自己的分支 | subtree 更优 |
update | 子仓库更新后,父仓库需要 subtree pull 操作,且命令行略长,需要指定 --prefix 参数。由于无法感知子仓库的存在,可能会产生 merge 冲突需要处理 | 子仓库更新后,父仓库需要 submodule update 操作。父仓库只需变动子仓库 hash 引用,不会出现冲突 | submodule 更优 |
commit | 父仓库直接提交父子仓库目录里的变动。若修改了子仓库的文件,则需要执行 subtree push | 父子仓库的变动需要单独分别提交。且注意先提交子仓库再提交父仓库 | subtree 更优 |
学习参考链接:
Linux ln(英文全拼:link files)命令是一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接。
当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在 其它的目录下用 ln 命令链接(link)它就可以,不必重复的占用磁盘空间。
ln [参数][源文件或目录][目标文件或目录]
我们基于一、实现跨 Git 项目复用组的探测之旅中的第四种方式,设置软链
在 reuseParent 项目根目录
ls -s ../reuseBtn ./node_modules/btnUrl
bug: 暂时无效
在第三种的基础之上,改用 npm link
# 创建link
cd reuseBtn
npm link
## /Users/yaya/.nvm/versions/node/v12.10.0/lib/node_modules/@hey_ff/testbutton -> /Users/yaya/Documents/learn/angular-study/component-repeat/reuseBtn
# 关联link
cd reuseParent
npm link @hey_ff/testbutton
## /Users/yaya/Documents/learn/angular-study/component-repeat/reuseParent/node_modules/@hey_ff/testbutton -> /Users/yaya/.nvm/versions/node/v12.10.0/lib/node_modules/@hey_ff/testbutton -> /Users/yaya/Documents/learn/angular-study/component-repeat/reuseBtn
# 解除link
npm unlink @hey_ff/testbutton
## 解除时,会导致同时删除安装包
备注(来自建议信息,尚没有实践到这类情况):
使用 npm link 做 Angular library 与业务代码集成测试时需要在业务库的 angular.json( project > architect > build > options) 中配置 "preserveSymlinks": true。否则会报告很诡异的错误。
在探索的过程中,都是基于位于不同库的方式。有同事给出了 monorepo 的解决方案,特此一试。
# 创建workspace
ng new my-workspace --createApplication="false"
# 进入工作区 创建应用和库
cd my-workspace
ng generate application my-first-app
ng generate library my-lib
ng generate application my-second-app
在 package.json 增加配置
"scripts": {
"ng": "ng",
"start": "ng serve",
"start:second": "ng serve my-second-app",
"build": "ng build",
"build:lib": "ng build my-lib --prod",
"build:second": "ng build my-second-app --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
在 my-lib 新建组件并执行打包
npm run build:lib
核心配置 tsconfig.base.json:
"paths": {
"my-lib": [
"dist/my-lib/my-lib",
"dist/my-lib"
]
}
引入 app.module.ts:
import { MyLibModule } from "my-lib";
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AppRoutingModule, MyLibModule],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
使用 app.component.html:
<lib-the-button text="lib-componeent"></lib-the-button>
每次修改组件后,执行打包
npm run build:lib
在 my-first-app 中就会得到最新的效果
这个实践跟 一、实现跨 Git 项目复用组的探测之旅 第五种方式的实现原理相同:通过 tsconfig 文件配置实现对组件库的调用
mkdir monorepo
cd monorepo
git init
npm init -y
mkdir first-app # 配置一个Angular的可运行app
mkdir libs # 放置纯组件源代码
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"module": "es2020",
"lib": ["es2018", "dom"],
"paths": {
"my-libs": ["projects/libs"]
}
},
"include": ["projects/libs/**/*.ts"]
}
npm install -D @angular/core rxjs