UNPKG

utquidem

Version:

The meta-framework suite designed from scratch for frontend-focused modern web development.

402 lines (292 loc) 10.5 kB
--- sidebar_position: 9 --- # 开发工具库 本章将介绍如何使用 Modern.js,进行工具库项目的开发。本章对应的代码仓库地址:[独立项目场景](https://github.com/modern-js-dev/modern-js-examples/tree/main/quick-start/library-project) 、[Monorepo 场景](https://github.com/modern-js-dev/modern-js-examples/tree/main/quick-start/monorepo-library)。 :::info 注 工具库项目是指开发类似 [Lodash](https://lodash.com/)、JavaScript SDK 等可复用模块的项目。 ::: 通过本章你可以了解到: - 如何创建一个工具库项目。 - 如何在工具库项目中进行测试。 - 如何为工具库项目开启 Storybook 功能并使用它进行调试。 - 如何发布工具库项目。 - 如何将工具库项目迁移到 Monorepo 中。 ## 环境准备 import EnvPrepare from '@site/docs/components/env-prepare.md'; <EnvPrepare /> ## 创建项目 使用 `@modern-js/create` 创建新项目,运行命令如下: ```bash npx @modern-js/create library-project ``` :::info 注 library-project 为创建的项目名。 ::: 按照如下选择,生成项目: ```bash ? 请选择你想创建的工程类型 模块 ? 请填写项目名称 library ? 请选择开发语言 TS ? 请选择包管理工具 pnpm ? 是否需要调整默认配置? 否 ``` :::info 注 项目名称为 package.json 中的 `name` 字段值。 ::: ### 编写工具函数逻辑 修改 `src/index.ts` 文件,增加工具库函数(以将字符串字母都转为大写为例): ```ts export const upperCase = (s: string) => s.toUpperCase(); ``` ## 测试 修改默认测试文件 `tests/index.test.ts````ts import { upperCase } from '@/index'; describe('upperCase cases', () => { test('upperCase', () => { expect(upperCase('abc')).toBe('ABC'); }); }); ``` 执行 `test` 命令对工具函数进行测试,命令如下: ```bash pnpm run test ``` ## IDE 支持 import DevIDE from '@site/docs/components/dev-ide.md' <DevIDE/> ## 启用 Storybook 调试 在项目根目录下,执行 `pnpm run new`,可以开启 Storybook 功能。 ```bash ? 请选择你想要的操作 启用可选功能 ? 启用可选功能 启用「Storybook」 ``` 启用成功后,会自动创建 `stories/` 目录,修改 `stories/index.stories.tsx` 文件内容: ```ts import { useState } from 'react'; import { upperCase } from '@/index'; const Component = () => { const [value, setValue] = useState(''); return ( <div> <input value={value} onChange={e => setValue(e.target.value)} /> <div>result: {upperCase(value)}</div> </div> ); }; export const YourStory = () => <Component />; export default { title: 'Your Stories', }; ``` 执行 `pnpm run dev` 调试运行结果,如下图所示: ![调试 storybook](https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/start/storybook.png) ## 产物模式 工具库项目支持配置不同的产物模式来满足不同的开发需求,产物模式通过 `output.packageMode` 配置进行。 该配置支持如下值: - universal-js - universal-js-lite - browser-js - browser-js-lite - node-js 具体每个值对应的产物结构详见 [`output.packageMode`](/docs/apis/config/output/package-mode)。 对于当前场景,如果开发的工具库只支持 Node.js 环境,可以在项目 `modern.config.js` 中增加如下配置: ```js title="modern.config.js" export default defineConfig({ output: { packageMode: 'node-js', }, }); ``` 执行 `pnpm run build` 之后,查看 `dist/` 目录产物,可以看到只生成 `node``modern` 两种类型的产物。 ## 发布 开发完成后,可以对工具库进行发布。 发布分以下四个步骤: 1. 添加 changeset 执行 `pnpm run change`,根据提示选择升级的版本,并填写变更信息。 ![填写变更信息](https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/start/changeset.png) 2. 升级对应版本号,并生成 changelog 执行 `pnpm run bump`,该命令会根据上述生成的 changeset 自动更新版本号和 CHANGELOG 信息,检查信息无误后提交。 3. 发布 执行 `pnpm run release`, 发布该工具包。 4. 推送 tags 发布完成之后执行 `git push --follow-tags`,推送当前发布对应生成的 git tag。 ## 迁移到 Monorepo 在团队协作开发中,也会存在使用 Monorepo 进行项目开发的情况。接下来介绍如何将工具库项目迁移到 Monorepo 中。 ### 创建 Monorepo 使用 `@modern-js/create` 创建 Monorepo 项目,运行命令如下: ```bash npx @modern-js/create library-monorepo ``` :::info 注 library-monorepo 既是创建的 Monorepo 目录名称,又是项目的名称。 ::: 按照如下选择,生成项目: ```bash ? 请选择你想创建的工程类型 Monorepo ? 请选择包管理工具 pnpm ``` 生成的项目目录结构如下: ```bash . ├── .changeset │ └── config.json ├── .editorconfig ├── .gitignore ├── .npmrc ├── .nvmrc ├── .pnpmfile.cjs ├── .vscode │ ├── extensions.json │ └── settings.json ├── README.md ├── apps │ └── .gitkeep ├── features │ └── .gitkeep ├── monorepo.code-workspace ├── package.json ├── packages │ └── .gitkeep ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── tsconfig.json ``` ### 迁移工具库项目 这里只需要将之前创建的工具库项目复制到 `packages/` 目录下面,并删除 `.change``.vscode``.git` 目录及 `.editorconfig``.gitignore``.nvmrc``.npmrc` 文件。 ```md . ├── packages/ │ └── library-project ├── CHANGELOG.md ├── README.md ├── modern.config.js ├── package.json ├── src │ ├── index.ts │ └── modern-app-env.d.ts ├── stories │ ├── index.stories.tsx │ └── tsconfig.json ├── tests │ ├── index.test.ts │ ├── modern-app-env.d.ts │ └── tsconfig.json └── tsconfig.json | ... ``` ### 创建子项目 Modern.js 支持 Monorepo 工程方案的管理,我们可以在 Monorepo 项目下通过 `new` 命令创建不同类型的子项目。例如在刚刚创建的 Monorepo 项目根目录下执行 `pnpm run new`: 然后分别选择创建**应用**,**模块(内部)**项目。 ```bash ? 请选择你想创建的工程类型 应用 ? 请填写子项目名称 app ? 请填写子项目目录名称 app ? 请选择开发语言 TS ? 是否需要支持以下类型应用 不需要 ? 是否需要调整默认配置? 否 ``` ```bash ? 请选择你想创建的工程类型 模块(内部) ? 请填写子项目名称 internal-lib ? 请填写子项目目录名称 internal-lib ? 请选择开发语言 TS ? 是否需要调整默认配置? 否 ``` ### 在应用项目中使用组件以及内部模块 接下来在 app 项目中通过以下方式把工具库项目加到依赖中: ```bash cd ./apps/app pnpm add library ``` 此时可以观察到 app 项目的 `package.json` 内容更新如下: ```json { "dependencies": { "@modern-js/runtime": "^1", ++ "library": "workspace:^0.1.1", "react": "^17.0.1", "react-dom": "^17.0.1" } } ``` 接下来导入内部模块 `internal-lib`,由于内部模块并不需要进行发布,因此通过如下方式添加到项目中: :::info 注 内部模块是指不需要发布到 npm 上的 package,它们只提供源码给应用项目使用,应用项目会将它们打包到构建产物中。 ::: ```bash cd ./apps/app pnpm add internal-lib -D ``` 此时可以观察到 app 项目的 `package.json` 内容更新如下: ```json { "devDependencies": { "@modern-js/app-tools": "^1", "@modern-js/plugin-jarvis": "^1", "@types/jest": "^26.0.9", "@types/node": "^14", "@types/react": "^17", "@types/react-dom": "^17", ++ "internal-lib": "workspace:^0.1.0", "typescript": "^4" }, } ``` 此时在 app 项目下的 `src/App.tsx` 文件引用 `library``upperCase` 函数以及 `internal-lib` 模块,并使用它们: ```tsx title="App.tsx" import { Switch, Route } from '@modern-js/runtime/router'; import { upperCase } from 'library'; import sayHelloWorld from 'internal-lib'; import './App.css'; const App = () => ( <Switch> <Route exact={true} path="/"> <div className="container"> <main>{/* //... */}</main> <div>{upperCase('abc')}</div> <div>{sayHelloWorld()}</div> <footer className="footer"> <a href="#" target="_blank" rel="noopener noreferrer"> Powered by Modern.JS </a> </footer> </div> </Route> <Route path="*"> <div>404</div> </Route> </Switch> ); export default App; ``` 然后我们在 `apps/app` 目录下执行 `pnpm run dev` 命令,可以看到页面渲染效果如下: ![app-tools](https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/start/app-tools.png) ### 批量发布 我们可以在 Monorepo 中再创建一个工具库项目(以将字符串字母都转为小写为例): 在 Monorepo 项目根目录下执行: ```bash pnpm run new ``` ```bash ? 请选择你想创建的工程类型 模块 ? 请填写子项目名称 library2 ? 请填写子项目目录名称 library2 ? 请选择开发语言 TS ? 是否需要调整默认配置? 否 ``` 修改 `packages/library2/src/index.ts` 文件,增加工具库函数: ```ts export const lowerCase = (s: string) => s.toLowerCase(); ``` 开发完成后可以在 Monorepo 的场景下对所有工具库做批量发布: 1. 添加 changeset 在 Monorepo 根目录执行 pnpm run change,根据提示选择发布的包(注意这里只选择工具库包名)和升级的版本,并填写变更信息。 ![monorepo 添加 changeset](https://lf3-static.bytednsdoc.com/obj/eden-cn/aphqeh7uhohpquloj/modern-js/start/monorepo-changeset.png) 2. 升级发布包对应版本号,并生成 changelog 执行 `pnpm run bump`,该命令会根据上述生成的 changeset 自动更新版本号和 CHANGELOG 信息,检查信息无误后提交。 3. 发布 执行 `pnpm run release`, 发布对应的多个工具包。 4. 推送 tags 发布完成之后执行 `git push --follow-tags`,推送当前发布对应生成的 git tag。