bit 官网: docs.bit.dev/docs/quick-…
什么是 bit
Bit is the platform for collaboration on atomic components
组件共享方式对比
当在 A 项目中发现一个组件 B 项目中可以很好的复用,这时候会有以下几种方式来实现:
- 复制粘贴
- 维护一个单独的组件库
- 将代码提取到其自己的存储库中
- 配置构建工具
- 构建发布链 需要单独的人力成本维护,而且不支持在其他项目的定制化开发,如发现有 bug 往往需要通知维护人员进行修改发布,阻塞开发进度
- Monorepo 将所有代码保留在一个 repo 中,可以在项目之间共享代码,而无需维护多个存储库并。Monorepos 强制要求,不仅共享组件驻留在单个存储库中,而且消耗共享组件的项目也应驻留.而且重构成本较高。
为什么选用 bit
- 共享现有项目中已经开发的组件。
- 无需花费很长时间维护 UI 组件库。
- 支持项目中的二次开发。
- 可以保留使用项目中组件的本地修改,并且仍与传入的更新合并。
- 每一个组件就是一个包,无需等到大版本升级,可单独对现有功能就行修复和升级。
新版 bit 使用流程
介绍
Bit is a component-based approach to modern application development. Bit makes the development and composition of modern applications from independent components repeatable and fun.
安装
- 安装 bvm 类似于 nvm 的 bit 版本管理工具
npm i -g bvm
- 安装 bit 使用 bvm 安装 bit
bvm install
安装成功后,运行bit -v看 bit 是否安装成功
参考链接: harmony-docs.bit.dev/getting-sta…
使用
初始化工作区
bit init --harmony
添加远程工作区
bit remote add http://xx.xx.x.x:port
新创建组件
- bit 支持使用 create 命令来创建新的组件
bit create react-component ui/button
上面命令创建了一个 button 的 ui 组件,其中 react-component 为 bit 创建组件模版的一个类型,可以通过bit templates命令来查看现在的模版。同时模版支持自定义,可点击文档查看具体操作。
ui/button 为 scope/name 就是组件当前所在范围以及组件的名称,便于分类。
新创建的组件的目录结构为
my-component
├── index.ts //入口文件,导出组件
├── my-component.compositions.tsx //使用该组件的示例
├── my-component.docs.jsx //文档
└── my-component.ts //组件的实现
- 待开发完成后,可执行
bit tag --all
来给所有新创建或者有修改的组件标记版本,也可以单独给某一个组件标记版本
bit tag <component-id> <new-version-number>
- 导出到远程工作区
bit export
在导出的同时可以同步发布到 npm 上,在项目中使用该组件的时侯用 npm 包的形式引入
在已有项目中导出组件
在已有项目中导出组件,大致流程与上述过程差不多,区别在于不再需要创建组件,直接使用
bit add src/xxx/xxx -n xxx
使用bit add命令可以追踪已存在组件, -n为namespace缩写。
注意: 使用 bit add 添加追踪组件后,如果在该文件夹下添加文件,新添加的文件将不触发本地调试的热更新,需要重新执行 bit add 命令,追踪新添加文件
其余操作与上述一致。
由于 bit 使用的包管理工具为 pnpm/yarn 2, 所以不建议在项目中使用bit import命令,在不同项目中导出组件后,在一个项目里统一存储这些组件,一是统一管理,二是存备份
关于webpack自定义修改
由于antd按需加载以及项目中使用yarn v1存在一些依赖提升的问题,需要在用到 antd 的地方添加 webpack 自定义配置。 代码如下:
import { WebpackConfigTransformer, WebpackConfigMutator, WebpackConfigTransformContext } from '@teambit/webpack';
const path = require('path');
const fs = require('fs');
// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebook/create-react-app/issues/637
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath);
/**
* Transformation to apply for both preview and dev server
* @description It's ugly but useful
* @param config
* @param context
*/
function commonTransformation(config: WebpackConfigMutator, context: WebpackConfigTransformContext) {
// Merge config with the webpack-config.js file - adding handlebars support
config.addResolve({
modules: ['node_modules', resolveApp('node_modules')],
});
// @ts-ignore
const oneOfRules = config.raw.module.rules.find((rule) => !!rule.oneOf);
// @ts-ignore
const lessRule = findLessRule(oneOfRules.oneOf);
// @ts-ignore
const lessLoader = lessRule.use.find((loader) => loader.loader.includes('less'));
// @ts-ignore
lessLoader.options['lessOptions'] = {
javascriptEnabled: true,
math: 'always',
};
return config;
}
/**
* Transformation for the preview only
* @param config
* @param context
* @returns
*/
export const previewConfigTransformer: WebpackConfigTransformer = (config: WebpackConfigMutator, context: WebpackConfigTransformContext) => {
const newConfig = commonTransformation(config, context);
return newConfig;
};
/**
* Transformation for the dev server only
* @param config
* @param context
* @returns
*/
export const devServerConfigTransformer: WebpackConfigTransformer = (config: WebpackConfigMutator, context: WebpackConfigTransformContext) => {
const newConfig = commonTransformation(config, context);
return newConfig;
};
function findLessRule(rules: Array<any>, testMatcher = `/(?<!\\.module)\\.less$/`) {
return rules.find((rule) => {
return rule.test && rule.test.toString() === testMatcher;
});
}
主要是添加 less 按需加载时候,需要开启 lessOptions 的javascriptEnabled,还有因为依赖提升,导致包找不到所以要手动配置寻找路径
config.addResolve({
modules: ['node_modules', resolveApp('node_modules')],
});
统一管理
新开发的组件和从其他已有项目中导出的组件,统一放到一个项目里面管理,这个项目可以使用bit import的方式,从远程拉去所有的 bit 组件。如果后续组件需要修改的话,可以在这个项目中修改,然后重新发布到远程工作区。同时也留一份备份在 git 上,不会对已有组件丢失。这个管理项目可以采用 pnpm 的方式进行依赖安装。