Monorepo
ICE PKG 提供了对 Monorepo 方案的支持。目前支持:
- 子项目之间依赖链接,方便进行本地调试
- 结合类似 Changesets、Rush等方案完成子项目版本管理和发布
开发环境准备
ICE PKG 的 Monorepo 方案是基于 pnpm workspace + 包构建器 @ice/pkg,因此我们需要确保我们的开发环境满足:
创建项目
通过以下命令,可以快速初始化一个 Monorepo 项目:
$ pnpm create @ice/pkg my-monorepo
选择 React 组件项目类型:
? 请选择项目类型 (Use arrow keys)
  React 组件
  Node 模块
  前端类库  
  Rax 组件
❯ Monorepo React 组件
  Monorepo Node 模块  
目录介绍
以一个多 React 组件默认脚手架项目为例子:
├── build.config.mts       # 文档预览配置文件
├── package.json
├── packages               # 存放子项目的目录
|  ├── component-a
|  ├── component-b
|  └── component-c
├── pages                  # 文档首页
|  ├── index.module.css
|  └── index.tsx
├── pnpm-workspace.yaml    # 定义工作空间的子项目
├── tsconfig.base.json
└── tsconfig.json
创建子项目
在项目根目录下,执行以下命令创建一个子项目:
# 假设 packages 目录是用于存放子项目
$ pnpm create @ice/pkg packages/your-lib --workspace
执行成功后,你将会看到以下内容:
? 请选择项目类型 (Use arrow keys)
❯ React 组件
  Node 模块
  前端类库  
  Rax 组件
根据实际的需求选择对应的项目类型,然后填写子项目的 npm 包名后,完成子项目的创建。
然后,我们还需要在根目录的 package.json 中 devDependencies 里添加依赖,以能正常启动文档预览服务(详细原因在后面文档预览小节中会讲到):
# package.json
{
  "devDependencies": {
+   "@ali/your-lib": "workspace:*"
  }
}
本地调试
在项目根目录下执行以下命令进行安装并构建工作区(workspace)的每个子项目:
$ pnpm install && pnpm packages:build
这个时候,所有的依赖都安装完成,并且有依赖的子项目之间也自动 link 好了。
我们在项目根目录下执行以下命令启动调试:
$ pnpm start
这时会监听每个子项目的代码变更,并启动文档预览服务:
 
 
这时我们可以修改源码,进行本地调试了。
文档预览
文档预览服务基于 @ice/pkg-plugin-docusaurus ICE PKG 插件。推荐一个 Monorepo 项目存在一个文档站点服务,并支持预览所有的子项目的文档。
添加依赖到根目录的 package.json
由于启动文档本地预览调试是在项目的根目录进行,但在子项目的文档中通常直接依赖了子包,在文档进行打包构建的时候会找不到对应的子包,因此需要在项目根目录的 package.json 中添加对应的子项目依赖:
# package.json
{
  "devDependencies": {
+   "@ali/your-lib": "workspace:*"
  }
}
子项目文档预览
packages 目录下每个子项目都会有一个 docs 目录,用来存放该子项目的文档。比如:
./packages/component-a
├── README.md
├── build.config.mts
├── docs
|  ├── index.md
|  ├── usage.md
|  └── usage.md
├── package.json
├── src
└── tsconfig.json
在项目根目录下执行以下命令,会起一个 docusaurus 的文档预览:
$ pnpm docs:start
访问控制台中打印的文档地址就能查看文档了:
 
 
以  packages 目录为根目录,页面的路由默认根据下每个子项目的文件路径自动生成的。比如上面的 ./packages/component-a/docs/index.md,路由会自动为 /component-a/docs/(没有 packages 前缀)。
所有的文档选项配置,都在根目录的 build.config.mts 文件中配置,下面是推荐的配置:
import { defineConfig } from '@ice/pkg';
export default defineConfig({
  plugins: [
    [
      '@ice/pkg-plugin-docusaurus',
      {
        path: 'packages',
        sidebarItemsGenerator: (args: any) => {
          // The index.md doc should not be the category, so we rewrite the default isCategoryIndex function.
          function isCategoryIndex({ fileName, directories }: any) {
            const eligibleDocIndexNames: string[] = [
              'readme',
              directories[0].toLowerCase(),
            ];
            return eligibleDocIndexNames.includes(fileName.toLowerCase());
          }
          const defaultSidebarItems = args.defaultSidebarItemsGenerator({
            ...args,
            isCategoryIndex,
          });
          // 1. Remove the `docs` category.
          // 2. Remove category link.
          const newSidebarItems = defaultSidebarItems.map(({ link, ...rest }: any) => ({
            ...rest,
            items: rest.items.map((item: any) => item.items).flat(),
          }));
          return newSidebarItems;
        },
        exclude: ['**/node_modules/**'],
        onBrokenLinks: 'warn',
      },
    ],
  ],
});
更多配置说明可参考文档预览。
定制文档首页
默认情况下,当我们访问根路由(/)是返回 404 页面的。如果我们想定制文档首页的内容,我们可以增加 pageRouteBasePath 配置:
首先在 build.config.mts 中新增以下内容:
import { defineConfig } from '@ice/pkg';
export default defineConfig({
  plugins: [
    [
      '@ice/pkg-plugin-docusaurus',
      {
+       pageRouteBasePath: '/',
      },
    ],
  ],
});
然后在根目录下新增 pages 目录,然后新增 index.tsx 或者 index.md 文件,此文件将会被渲染到根路由。
// pages/index.tsx
export default function Home() {
  return (
    <div>我是首页</div>
  )
}
发布
对于 npm 包进行版本管理和发布,ICE PKG 推荐使用社区的版本控制工具: