{"id":16347009,"url":"https://github.com/ospoon/simple-micro-app","last_synced_at":"2025-11-09T02:30:25.722Z","repository":{"id":235341601,"uuid":"790095210","full_name":"OSpoon/simple-micro-app","owner":"OSpoon","description":null,"archived":false,"fork":false,"pushed_at":"2024-04-23T02:51:27.000Z","size":1003,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-12-28T06:09:28.423Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OSpoon.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-04-22T08:56:04.000Z","updated_at":"2024-05-14T08:14:33.000Z","dependencies_parsed_at":"2024-04-23T05:43:30.588Z","dependency_job_id":"3329fe01-0b4e-44c0-9869-9eb851a84f2b","html_url":"https://github.com/OSpoon/simple-micro-app","commit_stats":null,"previous_names":["ospoon/simple-micro-app"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OSpoon%2Fsimple-micro-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OSpoon%2Fsimple-micro-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OSpoon%2Fsimple-micro-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OSpoon%2Fsimple-micro-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OSpoon","download_url":"https://codeload.github.com/OSpoon/simple-micro-app/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239565664,"owners_count":19660158,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T00:39:08.782Z","updated_at":"2025-11-09T02:30:25.688Z","avatar_url":"https://github.com/OSpoon.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lerna-lite 轻量化 monorepo 管理利器\n## 写作背景\n微前端是一个新旧项结合挺常见的一种技术，我司也成功借助京东前端团队推出的 `micro-app` 完成了一主两从 **3** 个独立项目的完美结合。但随着项目整体 **sass** 化逐步转型开始，迭代差异化增加就，相对应的造成了项目依赖安装、启动、编译等一系列事项的频率变高，解决这个拖慢研发节奏的问题我想到的方案就是引入 **Monorepo** 单仓库的管理。\n\n## **lerna-lite 介绍**\n**lerna-lite** 是用来管理和发布同一仓库多 `JavaScript`/`TypeScript` 包的一款工具，与 **lerna** 相比 **lerna-lite** 具有更轻量化和模块化的特点，同时 **lerna-lite** 也是 **lerna** 的一个有限子集。我们在实际项目中可以采用渐进式的方式按需安装使用。需要注意的一点是 **lerna-lite** 是不包括 `bootstrap`、`add`、`create` 和 `link` 命令的，所以需要正式使用 **lerna-lite** 之前配置好项目的包管理器（`npm`、`pnpm`、`yarn`）。\n\n### 快速开始：\n首先要将`@lerna-lite/cli`作为开发依赖安装到项目中：\n```bash\n# 创建一个空项目\nmkdir lerna-repo\ncd lerna-repo\nnpm init -y\n\n# 安装 cli 依赖并执行 init 命令\nnpm install -D @lerna-lite/cli\nnode_modules/.bin/lerna init\n```\n\n执行 `init` 命令初始化工作空间，得到一个 `lerna.json` 配置文件和一个 `packages` 文件夹；\n```bash\nlerna-repo            \n├─ packages       \n├─ lerna.json\n└─ package.json\n```\n如果你不打算使用 `npm` 作为项目的包管理器的话需要更新 `lerna.json` 配置文件中的 `npmClient`；\n\n1. 使用 `yarn` 配置：`\"npmClient\": \"yarn\"`\n2. 使用 `pnpm` 配置：`\"npmClient\": \"pnpm\"`\n### 命令列表：\n| 命令 | 安装 | 介绍 |\n| --- | --- | --- |\n| ☁️ publish | `npm i -D @lerna-lite/publish` | 发布软件包 |\n| 📑 version | `npm i -D @lerna-lite/version` | 为软件包创建新版本 |\n| 🕜 changed | `npm i -D @lerna-lite/changed` | 查看上一个版本发布以来更改的软件包 |\n| 🌓 diff | `npm i -D @lerna-lite/diff` | 查看上一个版本发布以来软件包发生的变化 |\n| 👷 exec | `npm i -D @lerna-lite/exec` | 运行 shell 命令 |\n| 📖 list | `npm i -D @lerna-lite/list` | 列出工作区中的所有本地软件包 |\n| 🏃 run | `npm i -D @lerna-lite/run` | 运行script 脚本 |\n| 👓 watch | `npm i -D @lerna-lite/watch` | 监听所有软件包的变更并执行自定义命令 |\n\n**PS**： 由于 `publish` 命令依赖于 `version` 命令，所以在安装 `@lerna-lite/publish`后即可获得这两个命令。\n\n## 一起操练起来：\n![image (1)](https://github.com/OSpoon/simple-micro-app/assets/10126623/6270f045-f752-455c-8dd8-ed1ca7d563e2)\n\n首先会创建三个独立的前端应用，接着会使用 `micro-app` 将 **Angualr16** 的项目改造为微前端的主应用，**Vue3** + **Vite** 和 **React** + **Vite** 两个项目当做子应用接入，最后在升级为 **Monorepo** 。\n**lerna-lite** 将会以渐进式的方式在整个过程中逐步引入。\n\n### 独立前端应用（Multirepo风格）：\n#### Angualr16 应用：\n\n- 创建应用：\n```bash\n# 创建命令\n$ npx @angular/cli@16 new angular-app\n? Would you like to add Angular routing? Yes\n? Which stylesheet format would you like to use? CSS\n```\n\n- 分配启动端口： 修改 `start` 脚本 ，增加 `--port` 选项，指明端口号；\n```json\n{\n  \"start\": \"ng serve --port 10010\"\n}\n```\n\n- 通过路由组织页面：\n```typescript\napp                                \n├─ pages                           \n│  ├─ sub-react                    \t添加 react 子应用页面\n│  │  ├─ sub-react.component.css   \n│  │  ├─ sub-react.component.html  \n│  │  └─ sub-react.component.ts    \n│  └─ sub-vue                       添加 vue 子应用页面\n│     ├─ sub-vue.component.css     \n│     ├─ sub-vue.component.html    \n│     └─ sub-vue.component.ts      \n├─ app-routing.module.ts  \t\t\t\t\t添加页面对应的路由         \n├─ app.component.css                \n├─ app.component.html               左右布局（aside + article）\n└─ app.module.ts           \t\t\t\t\t添加新页面的组件声明        \n```\n\u003cimg width=\"987\" alt=\"image\" src=\"https://github.com/OSpoon/simple-micro-app/assets/10126623/42180591-612b-4d1b-830a-b6df93e85652\"\u003e\nPS：文末通过访问 Github 查看项目中的变更文件，已用注释说明；\n\n#### Vue3 应用：\n\n- 创建应用\n```bash\n# 创建命令\n$ npm create vite@latest\n✔ Project name: vue-app\n✔ Select a framework: › Vue\n✔ Select a variant: › TypeScript\n```\n\n- 分配启动端口：修改 `vite.config.ts` 配置文件，增加 `server.port` 选项，指明端口号；\n```javascript\n{\n  server: {\n    port: 10011,\n  }\n}\n```\n\n#### React 应用：\n\n- 创建应用\n```bash\n# 创建命令\n$ npm create vite@latest\n✔ Project name: react-app\n✔ Select a framework: › React\n✔ Select a variant: › TypeScript\n```\n\n- 分配启动端口：同 **Vue3** 应用，指明端口号；\n```javascript\n{\n  server: {\n    port: 10012,\n  }\n}\n```\n\n### 微前端改造（MicroApp）：\n\u003e 以下针对对前端的改造全部在 **Angualr16** 主应用中进行；\n\n#### 安装并初始化：\n安装`npm i @micro-zoe/micro-app --save`；\n```typescript\n// main.ts\nimport microApp from '@micro-zoe/micro-app';\n\nmicroApp.start();\n```\n#### 支持 WebComponent：\n```typescript\n// app/app.module.ts\nimport { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';\n\n@NgModule({\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\n})\n```\n#### 页面嵌入子应用：\n```html\n\u003c!-- vue3 + vite --\u003e\n\u003c!-- pages/sub-vue/sub-vue.component.html --\u003e\n\u003cmicro-app name=\"sub-vue\" url=\"http://localhost:10011\" iframe\u003e\u003c/micro-app\u003e\n\n\u003c!-- react + vite --\u003e\n\u003c!-- pages/sub-react/sub-react.component.html --\u003e\n\u003cmicro-app name=\"sub-react\" url=\"http://localhost:10012\" iframe\u003e\u003c/micro-app\u003e\n```\nPS：子应用使用 `vite` 作为基础框架，需要主动切换到 `iframe` 沙箱；\n![2024-04-22 15 41 58](https://github.com/OSpoon/simple-micro-app/assets/10126623/09dcae4a-e702-4c44-bcf7-9fced81d38dd)\n\n\n### **lerna-lite（Monorepo风格）：**\n按快速开始的的流程创建 `simple-micro-app` 项目且默认使用 `npm` 包管理器，执行 `init` 命令后将独立的三个前端应用移动到对应的目录。\n```\nsimple-micro-app       \n├─ packages            \n│  ├─ main-angular-app  \t\t对应 angular-app\n│  ├─ sub-react-app    \t\t\t对应 react-app\n│  └─ sub-vue-app      \t\t\t对应 vue-app\n├─ lerna.json           \n└─ package.json        \n```\nPS：`pnpm`包管理器需要依据团队使用熟练度来进行落地。\n\n#### 查看本地应用：\n\n- 安装：`npm i -D @lerna-lite/list`；\n- 添加脚本：\n```json\n{\n  \"scripts\": {\n    \"list\": \"lerna ls -la\"\n  }\n}\n```\nPS：查看包括私有的所有 `JavaScript`/`TypeScript` 包；\n\n#### 删除 node_module：\n\n- 安装：`npm i -D @lerna-lite/exec`；\n- 添加脚本：\n```json\n{\n  \"scripts\": {\n    \"clear\": \"lerna exec -- rm -rf ./node_modules\"\n  }\n}\n```\nPS：一次性删除 `packages` 中每个应用的 `node_module` 文件夹；\n\n#### 安装应用依赖：\n\n- 添加脚本：\n```json\n{\n  \"scripts\": {\n    \"install\": \"lerna exec -- npm install\"\n  }\n}\n```\nPS：一次性安装 `packages` 中每个应用的依赖；\n\n#### 启动所有应用：\n\n- 安装：`npm i -D @lerna-lite/run`；\n- 添加脚本：\n```json\n{\n  \"scripts\": {\n    \"dev\": \"lerna run dev --parallel\"\n  }\n}\n```\nPS：需要将 `angular16` 项目中的 `start` 脚本名修改为 `dev`，与其他两个应用保持一致的启动命令；\n#### \n#### 创建新版本：\n\n- 安装：`npm i -D @lerna-lite/version`；\n- 添加脚本：\n```json\n{\n  \"scripts\": {\n    \"version\": \"lerna version\"\n  }\n}\n```\nPS：执行 version 脚本前需要保证所有的变更都已经提交；\n\n- 操作过程：\n```bash\n$ npm run version\n\n\u003e simple-micro-app@1.0.0 version\n\u003e lerna version\n\nlerna-lite notice cli v3.3.3\nlerna-lite info current project version 0.0.0\nlerna-lite info Assuming all packages changed\n? Select a new version (currently 0.0.0) Prepatch (0.0.1-alpha.0)\n\nChanges (3 packages):\n - angular-app: 0.0.0 =\u003e 0.0.1-alpha.0 (private)\n - react-app: 0.0.0 =\u003e 0.0.1-alpha.0 (private)\n - vue-app: 0.0.0 =\u003e 0.0.1-alpha.0 (private)\n\n? Are you sure you want to create these versions? Yes\nlerna-lite info git Pushing tags...\nlerna-lite info execute Skipping releases\nlerna-lite success version finished\n```\n#### 生成 CHANGELOG：\n\n- 修改 version 脚本：\n```json\n{\n  \"scripts\": {\n    \"version\": \"lerna version --conventional-commits --changelog-preset angular\"\n  }\n}\n```\nPS：使用 angular 预设在创建新版本时生成 **CHANGELOG.md** 文件；\n#### 查看变更的应用：\n\n- 安装：`npm i -D @lerna-lite/changed`；\n- 添加脚本：\n```json\n{\n  \"scripts\": {\n    \"changed\": \"lerna changed --all\"\n  }\n}\n```\nPS：执行 `changed` 查看距离上次发布版本所有包；\n\n- 操作过程：\n```bash\n$ npm run changed\n\n\u003e simple-micro-app@1.0.0 changed\n\u003e lerna changed --all\n\nlerna-lite notice cli v3.3.3\nlerna-lite info Looking for changed packages since v0.0.2\nangular-app (PRIVATE)\nlerna-lite success found 1 package ready to publish\n```\n\n#### 查看变更的内容：\n\n- 安装：`npm i -D @lerna-lite/diff`；\n- 添加脚本：\n```json\n{\n  \"scripts\": {\n    \"diff\": \"lerna diff\"\n  }\n}\n```\nPS：执行 `diff` 查看距离上次发布版本所有变化的内容；\n\n- 操作过程：\n```bash\n$ npm run diff\n\ndiff --git a/packages/main-angular-app/src/app/app.component.html b/packages/main-angular-app/src/app/app.component.html\n \u003cmain\u003e\n   \u003caside\u003e\n-    \u003ca [routerLink]=\"['/sub-vue']\" routerLinkActive=\"active\"\u003esub-vue\u003c/a\u003e\n-    \u003ca [routerLink]=\"['/sub-react']\" routerLinkActive=\"active\"\u003esub-react\u003c/a\u003e\n+    \u003ca [routerLink]=\"['/sub-vue']\" routerLinkActive=\"active\"\u003evue3\u003c/a\u003e\n+    \u003ca [routerLink]=\"['/sub-react']\" routerLinkActive=\"active\"\u003ereact\u003c/a\u003e\n   \u003c/aside\u003e\n   \u003carticle\u003e\n     \u003crouter-outlet\u003e\u003c/router-outlet\u003e\n~\n```\n## 总结：\n从一开始的三个独立的前端应用通过 `micro-app` 将代码从业务的层面整合到了一起，但由于此时还是 Multirepo 风格，所以对于开发维护和管理上还是存在一定的负担，每一次的迭代、BUG 修复或提交代码都需要多次 `cd` 到项目路径，逐个执行不同的命令，通过 **lerna-lite** 将它们从代码仓库的层面继续整合将大大优化拖慢研发节奏的问题。\n\n- **micro-app** 在不同的技术栈和不同的基础框架会有不一样的要求，更多内容可以访问 [https://github.com/micro-zoe/micro-app](https://github.com/micro-zoe/micro-app) 查看学习。\n- **lerna-lite** 的 `publish` 和 `watch` 两个命名以及其他命令的更多选项可以到 [https://github.com/lerna-lite/lerna-lite](https://github.com/lerna-lite/lerna-lite) 查看学习。\n\nPS：源码访问 [simple-micro-app](https://github.com/OSpoon/simple-micro-app) 获取；\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fospoon%2Fsimple-micro-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fospoon%2Fsimple-micro-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fospoon%2Fsimple-micro-app/lists"}