Monorepo单仓多包&独立部署

仓就是仓库(repository,简称 repo),通常我们使用多个仓库(简称多仓,multi-repo)来管理项目代码,也就是每个仓库负责一个模块或包的编码、构建、测试和发布,代码规模相对较小,所以也称为小型规模仓库(简称小仓)。而单一(mono)仓库(简称单仓,mono-repo)是指在一个仓库中管理多个模块或包,当代码规模达到一定程度后可称为大型规模仓库(简称大仓)。

1. 目录结构「monorepo」

bash 复制代码
project-root/
├── packages/                      # 公共模块目录(跨子项目共享)
│   └── shared/                   # 公共模块(可跨子项目复用)
│       ├── api/                  # 公共接口封装
│       ├── utils/                # 工具函数、通用方法
│       ├── components/           # 公共 Vue/React 组件
│       └── styles/               # 公共样式文件,例如变量、mixin等
│
├── apps/                          # 子项目目录,每个子项目独立打包部署
│   ├── mobile/                    # mobile 子项目
│   │   ├── assets/               # 页面专属静态资源(图片、图标等)
│   │   ├── router/               # 页面专属路由配置
│   │   ├── store/                # 页面专属状态管理(vuex、pinia 等)
│   │   ├── views/                # 页面视图组件
│   │   ├── App.vue               # 根组件
│   │   └── main.js               # 入口文件,挂载 App.vue 并初始化子项目        
│   │
│   └── ...                       # 其他子项目,结构同 home/about
│
├── build/                         # webpack 配置、打包脚本、构建工具等
├── package.json                   # 项目依赖、npm scripts、monorepo 配置
└── README.md                      # 项目说明文档

2. 入口、出口以及别名

js 复制代码
const path = require("path");
const fs = require("fs");

// 根目录 apps 路径
const appsPath = path.resolve(__dirname, "../apps");

// 获取所有子包目录
const appDirs = fs
  .readdirSync(appsPath, { withFileTypes: true })
  .filter(dirent => dirent.isDirectory())
  .map(dirent => dirent.name);

// 构建别名
const alias = {
  // 每个 app,比如 @mobile @test
  ...Object.fromEntries(appDirs.map(name => [`@${name}`, path.resolve(appsPath, name)]))
};

module.exports = { apps: appDirs, alias };

// webpack 入口、出口以及别名
const APP_NAME = process.env.APP_NAME || "mobile";
if (!apps.includes(APP_NAME)) {
  throw new Error(`未找到${APP_NAME}应用,请检查apps目录`);
} else {
  console.log(`🚀 开始编译${APP_NAME}应用`);
}
entry: {
  base: ["core-js/stable", "regenerator-runtime/runtime"],
  main: [resolve(`apps/${APP_NAME}/main.js`)]
},
output: {
  filename: "js/[name].[chunkhash:8].js",
  path: resolve(`${process.env.OUTPUT_DIR || "dist"}/${APP_NAME}`)
},
alias: {
  "@": resolve("packages/shared"),
  "~": resolve(""),
  ...alias
}

3. 子包单独编译

1. 根目录统一管控

js 复制代码
"build:test": "pnpm run -r build:test",
"build:prod": "pnpm run -r build:prod",
"dev:mobile": "pnpm --filter mobile dev",
"dev:wxmp": "pnpm --filter wxmp dev",

2. 子包打包配置

js 复制代码
{
  "name": "mobile",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "build:prod": "cross-env NODE_ENV=production BUILD_ENV=prod APP_NAME=mobile webpack --progress --config ../../build/webpack.prod.js",
    "build:test": "cross-env NODE_ENV=production BUILD_ENV=test APP_NAME=mobile webpack --progress --config ../../build/webpack.prod.js",
    "dev": "cross-env NODE_ENV=development BUILD_ENV=dev APP_NAME=mobile webpack serve --progress --config ../../build/webpack.dev.js"
  }
}
相关推荐
IT_陈寒19 分钟前
Vite热更新失效?你可能漏了这个配置项
前端·人工智能·后端
10年前端老司机1 小时前
Next.js+LangGraph.js+ 简历工具AI Agent完整落地
前端·langchain·agent
IT_陈寒6 小时前
Java中equals方法比了个寂寞?原来这才是正确的重写姿势
前端·人工智能·后端
默_笙6 小时前
🚓 分诊台与拆题术:让 RAG 学会判断和规划
前端·javascript
CopyCode6 小时前
用 AI 迁项目有多爽?我把 Webpack 迁 Vite 的全过程记下来了
前端·架构
去伪存真6 小时前
Electron 自动化发布指南:GitHub Actions 跨平台打包全纪录
前端·electron
计算机魔术师6 小时前
OpenAI智能体失控闯进美国政府网站,53张用户图片外泄背后
前端
颜进强6 小时前
14 · NestJS ExecutionContext 执行上下文:守卫、拦截器、过滤器拿到的"同一个 context",为什么能力不一样?
前端·后端·ai编程
程序员Flycan6 小时前
🚀 跨域终结者:前端代理服务器(Proxy)原理解析与配置总结
前端
怕浪猫6 小时前
顶级模型一句话,AI 写出了能玩的 QQ飞车
前端·面试·github