源组件
设想我们的若干源组件【souce components】满足这样的目录结构关系,所有组件都仅仅通过一个 index.ts 向外暴露接口,相互之间仅通过 index.ts 引用依赖——这个是一个很重要的原则,isolate:
而这些源组件存在如下的依赖关系:
- Zoo.tsx 通过 ../Camel 引用 Camel 组件,【Legacy Mode Relative Paths】
- Zoo.tsx 通过 @source/Elephant 别名引用了 Elephant 组件
依赖解析
通过 bit add src/source/zoo --id demo/zoo 对 Zoo 组件进行追踪,bit 会把组件目录、文件等相关信息会被写入到 .bitmap。
bit 会在执行 tag 时候才会解析组件的依赖,所以当 bit tag demo/zoo 时,会抛错,并同时打印两个告警信息:
- missing packages dependencies …… Elephant
- untracked file dependencies …… Camel
对于告警 1,我们需要在 bit.json 里配置别名,告诉 bit 如何去查找 @source 依赖:
{
"resolveModules": {
"aliases": {
"@source": "src/source"
}
}
}
而告警 2 则需要 bit add、bit tag Camel & Elephant 两个组件:
bit add src/source/camel --id=demo/camel
bit add src/source/elephant --id=demo/elephant
bit tag demo/camel
bit tag demo/elephant
然后就可以再次 bit tag demo/zoo,并且成功—— bit 会把对 Camel、Elephant 组件的依赖映射为对 demo/camel 、demo/elephant 的依赖【Relative Source】——接下来就可以通过 bit export scopeName 导出组件。
依赖安装
更直观的体验一下,可以配置 bit.json:
{
"env": {},
"componentsDefaultDirectory": "components/{name}",
"packageManager": "npm"
}
然后:
bit init;
bit remote add ssh://bit@你的私服:/data/bit/my-test;
bit import my-test/demo/zoo;
最终的 bit 创建目录树是这样的:
其中,components 目录下:
- demo/zoo 保留了跟源组件相同目录结构:
- Zoo 跟源组件内容一模一样的目录结构、源文件;
- 创建 Camel 目录, 通过 index.ts 导出 camel,让 Zoo 可以找到相对路径依赖 Camel
- 将 node_modules/@bit/* 软链至 .dependencies 下对应依赖的特定版本
- 为让 Zoo 可以找到通过 @source 别名引入的依赖 Elephant,十分机智的创建了 node_modules/@source/Elephant 目录,并通过 index.js 和 index.d.ts 导出逻辑和类型——这就带来一个问题:
如果:
import Elephant from '@source/Elephant/Elephant';
但是在对应的 node_modules/@source/Elephant 并没有 Elephant.tsx,必然会是错误的——这就是为什么组件之间要 isolate,因为 bit 就这么限制了——奇怪的是这里为什么不把 Elephant 直接软链到 node_modules/@bit/my-test.demo.elephant?
- .dependencies 下是 demo/zoo 各依赖组件的不同版本的源文件。
然后,node_modules/@bit 目录下会有软链到 components/demo/zoo 的 my-test.demo.zoo,这样在业务代码里就可以通过 @bit/my-test.demo.zoo 引入 Zoo 组件。
经验总结
组件之间 isolate——组件所有的成员,包括逻辑、类型都只能通过唯一的出口,比如 index.ts 导出;对其他组件依赖的引用,也必须通过该组件唯一的出口,进行引用。如此就可以避免踩到 bit 依赖处理这块的坑。