Monorepo開發

一、什麼是Monorepo

Monorepo是指在一個代碼倉庫中管理多個項目,每個項目可以拆分成不同的模塊,統一的依賴管理,共享代碼和配置等。相比於多個獨立的倉庫,在monorepo中可以更容易地實現代碼復用和協同開發。

在實際應用中,常見的使用Monorepo的場景有:

  • 多個相關的項目有共享代碼的需求,例如同一公司或同一部門的多個項目。
  • 前端應用拆分成多個模塊或組件,共享依賴。
  • 微服務架構中,多個服務共享公共的代碼和配置。

而在monorepo中,一個典型的項目結構通常如下:

root/
├── package.json
├── packages/
│   ├── app/
│   ├── lib/
│   └── common/
└── scripts/

其中,根目錄下的package.json包含所有項目的相關信息和依賴,packages/目錄下存放不同的項目或模塊,scripts/目錄下存放一些腳本和配置文件。

二、Monorepo的優缺點

1. 優點

(1)統一的依賴管理

在Monorepo中,所有的項目和模塊共享同一個package.json,可以大大簡化依賴管理。例如,對於共同依賴的庫,只需要在package.json中進行一次安裝即可,而不需要每個項目單獨安裝。

(2)共享代碼

在Monorepo中,多個項目之間可以共享代碼和模塊,避免重複編寫和維護代碼,提高了代碼的復用性和可維護性。此外,共享的代碼也可以更容易地進行版本控制和更新。

(3)容易進行協同開發

由於所有的代碼都在一個倉庫中,可以更容易地進行代碼協同開發,例如可以使用git子模塊、git subtree等技術來讓開發者只克隆需要關注的部分,方便團隊協同開發。

2. 缺點

(1)構建速度慢

由於Monorepo中會有多個項目和模塊的代碼,每次構建都需要對每個模塊進行編譯和構建,如果項目非常龐大,構建速度會明顯變慢。

(2)發布部署複雜

在Monorepo中,不同項目和模塊之間存在依賴關係,如果需要對某個模塊進行修改或升級,需要考慮依賴關係對其他模塊的影響,因此發布和部署可能會更加複雜。

三、使用Monorepo管理項目

在本節中,我們將通過一個簡單的示例來演示如何使用Monorepo管理項目。

1. 初始化項目

首先,我們需要在本地創建一個新的文件夾,例如monorepo-test,並執行以下命令初始化項目:

mkdir monorepo-test
cd monorepo-test
npm init

在創建package.json時,可以將Monorepo相關的配置設置成項目的初始化信息:

{
  "name": "monorepo-test",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

private: true表示這是一個私有庫,workspaces: ["packages/*"]表示我們的工作區設置在packages/目錄下。

2. 創建項目

現在我們來創建一個新的項目,可以使用lerna命令來快捷地創建:

npx lerna create app --dependencies=react

你會看到一個新的packages/app目錄創建出來。

現在,我們需要在app目錄下添加一個React組件,例如:

// packages/app/src/Hello.js
import React from 'react';

export default function Hello({ name }) {
  return 

Hello, {name}!

; }

然後,我們需要在packages/app目錄下創建package.json,並在其中添加依賴和構建指令:

npm init -y
npm install --save react
// packages/app/package.json
{
  "name": "app",
  "version": "0.0.1",
  "scripts": {
    "build": "npm run build:lib",
    "build:lib": "rollup -c",
    "start": "react-scripts start"
  },
  "devDependencies": {
    "@babel/core": "^7.12.3",
    "@babel/plugin-proposal-class-properties": "^7.12.1",
    "@babel/preset-env": "^7.12.1",
    "@rollup/plugin-commonjs": "^16.0.0",
    "@rollup/plugin-node-resolve": "^10.0.0",
    "rollup": "^2.32.1",
    "rollup-plugin-babel": "^4.4.0",
    "rollup-plugin-css-only": "^3.1.0",
    "rollup-plugin-terser": "^7.0.2"
  },
  "dependencies": {
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  }
}

在這裡,我們使用了rollup進行打包和構建,同時添加了一些常見的依賴和插件。

3. 創建依賴模塊

現在,我們需要創建一個獨立的依賴模塊,用於在不同的項目中共享代碼和邏輯。

我們可以使用lerna來快速創建一個空的模塊:

npx lerna create common

然後,在packages/common目錄下,創建一個空的JavaScript文件index.js,它將作為我們的共享代碼的入口點。

// packages/common/index.js

由於common模塊是一個純JavaScript模塊,因此我們只需要在common/package.json中添加必要的依賴和構建腳本即可:

// packages/common/package.json
{
  "name": "common",
  "version": "0.0.1",
  "main": "index.js",
  "scripts": {
    "build": "npm run build:lib",
    "build:lib": "babel src --out-dir lib",
    "test": "echo \"No tests yet...\""
  },
  "devDependencies": {
    "@babel/core": "^7.12.3",
    "@babel/preset-env": "^7.12.1",
    "babel-jest": "^26.6.3",
    "jest": "^26.6.3"
  },
  "dependencies": {}
}

在這裡,我們使用了babel來進行編譯和構建,同時添加了一些常見的依賴和插件。

4. 在app中使用common模塊

現在,我們可以在app模塊中引入common模塊,並使用common模塊中的函數。

首先,我們需要在app/package.json中添加對common模塊的依賴:

"dependencies": {
  "react": "^17.0.1",
  "react-dom": "^17.0.1",
  "common": "^0.0.1"
}

然後,在app目錄下的任意JavaScript文件中,可以輕鬆地引入和使用common模塊中的函數:

// packages/app/src/Hello.js
import React from 'react';
import common from 'common';

export default function Hello({ name }) {
  return 

{common.sayHello(name)}

; }

在這裡,我們使用common.sayHello來獲取在common模塊中定義的函數,並將結果渲染到頁面中。

5. 構建和測試

現在,我們可以使用lerna來進行對我們的項目的構建和測試了:

npx lerna run build

這將會使用rollupbabel來構建我們的app和common模塊。

npx lerna run test

這將會使用jest來運行我們的測試用例。

四、總結

Monorepo雖然在一些場景下使用起來會有些複雜,但是其優點同樣非常明顯,特別是在多個項目和模塊之間有共享代碼和統一依賴管理的需求時,使用Monorepo可以顯著提高開發效率和可維護性。

在實際應用中,使用Monorepo需要清晰的項目結構和依賴關係管理,動態調整不同項目和模塊的關係需要仔細考慮,同時需要合理地使用各種工具和技術實現代碼隔離和部署。

原創文章,作者:ZPFBH,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/371976.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
ZPFBH的頭像ZPFBH
上一篇 2025-04-23 18:08
下一篇 2025-04-23 18:08

發表回復

登錄後才能評論