bit-react-tutorial 体验

2019 年的第一篇,也可能是 2019 的最后一篇

上半年在做用研业务群的组件跨业务共享方案的时候,曾经看过 bit.dev ,不过当时只是被他的在线预览组件的特性吸引,并没太深入研究这个站点。

但随着下半年越来越多的进行跨业务代码共享,发现传统的 NPM 方式会过于臃肿,组件孵化速度过慢,所以又回过头再研究下 bit.dev 是怎么解决这方面的问题的。

了解 Bit

bit.dev 的文档非常丰富(复杂),挑一些适合大家快速了解和学习的两篇,本文也是从这两篇进行学习的。

Bit 的一些亮点

  • 从已有的组件或项目工程中,直接提取子组件
  • 每一个子组件,都可以独立的进行构建、测试
  • 每个子组件,都会被包裹成独立的 NPM 包

Bit 如何实现的直接提取呢?

Bit 有一个工作空间的概念,通过 bit init 来初始化工作空间。

初始化后,原工程项目的 package.json 会出现一段 bit 的配置。同时,项目目录中也会生成一个 .bitmap 的隐藏文件,该文件就是用来记录哪些子组件需要被提取成独立 NPM 包的一个关键信息点。

对着教程演示一遍

教程和 demo 的 git repo

1、在原有项目工程中,初始化 bit 的工作空间。

执行 bit init 命令,可以看到 package.json 中多了一些 bit 相关的配置

bit init

2、添加已有的组件

执行 bit add src/components/* 命令,扫描 src/components 下面的所有文件夹,并挨个提取独立的子组件。

demo 中只有两个互不依赖的子组件(product-list 和 top-bar)。

bit add src/comopnents/*

可以看到,每个子组件,都有一个 files 字段来收集依赖项目,demo 里面包含了 css,也就是说子组件默认有处理 css 的行为。

3、添加 React 子组件的编译环境

由于我们的子组件都是 React 组件,React 组件由于用到了 JSX,是需要预编译成 JS 的。

执行 bit import bit.envs/compilers/react --compiler 命令,添加 React 的编译。

bit import bit.envs/compilers/react –compiler

4、对子组件进行编译

执行 bit build 命令就会对子组件进行编译了,默认会输出在工程的 dist 目录中。

bit build

从红框中可以看出,构建产物并非一个原生的 esm 模块,而是一个经过 babel 处理后的 cjs 模块。

由于是 cjs 不是 esm,所以构建产物中会有 require('./product-list.css') 这种非 js 的依赖存在。

5、把子组件打包成 0.1.0 版本并发布

这部分内容比较简单,两个命令一起来。

执行 bit tag --all 0.1.0 ,把子组件打包。

bit tag

执行 bit export --all libo1106.react-tutorial 将子组件发布到集合

bit export

可以看到,打包和发布的工作,仅仅是对 bit 的工作空间进行操作,没有动到任何源工程的源码,也没有平时 npm 发包会需要的各种 package.json 定义,但这两个包,却是实实在在的发布到 bit 的私有 npm 仓库中。

6、验证下我们发的包

npm show @bit/libo1106.react-tutorial.product-list

由于 bit 使用的是他们自己的 scope,所以默认 npm 会搜索不到,需要手动添加一下。

npm config set '@bit:registry' https://node.bit.dev
对 @bit 这个 scope,采用 https://node.bit.dev 这个源

深挖一下,看看 Bit 的组件都做了些啥

挑了两个组件下载回来解压看内容,package.json 都挺干净,没有额外的依赖引入,只有 bit 字段,是用来给 bit.dev 渲染时候的实时编译用的。

同时,NPM 包里面还存放有组件的源代码,来给 bit.dev 进行在线查看源码使用。

Bit 小结

在 Bit 的这套方案中,有一些挺有意思的东西。

1、大范围使用 Scope

全部的 Bit 组件,都托管在 https://node.bit.dev 的源上面。

现在才知道 NPM 是支持对不同的 Scope 采取不同的 Registry 策略。@bit:registry = "https://node.bit.dev"

2、UI 组件采用 cjs,而不是更激进的 esm 模块

之前我们团队做的跨项目方案,想用更纯粹的 ESM 方案,结果非 JS 的内容处理比较麻烦。

要么编译时候 inline 到 JS 里面,要么业务使用的时候,需要额外的 babel 插件来实现非 JS 内容的注入。

而保守点用 cjs 的方案的话,则不存在这个问题,只是没有验证过业务还能否进行 tree-shaking。

3、由工具生成 package.json

由于 packge.json 是工具生成的,所以也能通过 packgae.json 来实现在线预览,甚至是一定能力的编辑。

同时,也能利用 name 字段的 . 符,来实现 scope 下面的多级划分(@bit/用户名.集合.组件)。

这个多级能力,在原生的 NPM 下面,可是只有 scope 这一级的组织能力。

4、通过额外的 .bitmap 来隔离业务和子组件

一份额外的关系树文件,就能避免对原有工程的污染和大改,挺好的。

5、私有化部署一套 bit ?

他们现在有企业版的洽谈,估计能做私有化部署了。

他们的 Github 也开源了非常多的能力,但暂时没深入进去看那些可以用来。