代码共享方案-多仓库合并单仓库

背景

公司从 2019 年立项以来,陆续分别开了若干个工程,这里代称为 apple, peach, banana, 以及 infra 工程,每个工程对应公司的一块业务,大体都是不相似的,其中 infra 的工程用于工程间代码共享,其中也有工程依赖于另外的工程,现需要将以上工程中部分功能挪到另一个新开的工程 dashboard。如何将多个仓库融合在一个仓库中,并保留原有历史记录,并且随着业务的演进,能够实时同步代码,且工程大多开发了5年以上,代码量巨大,如何组织代码,本文就是为这一方案而生。

原有工程结构如下:

每个工程都是一个独立的 git 仓库,每个仓库中都有一个 infra submodule 子工程

.gitsubmodules 文件内容

git 仓库调整

通过引用 naraku 这个 shell 工程, 将所有仓库包揽在 naraku 仓库之下,改造完成后工程结构如下:

单体工程改造

webpack 调整

这里以 vue-cli 为例,chainWebpack 中加入以下代码

js 复制代码
{
    chainWebpack: config => {
    // 配置路径别名
    config.resolve.alias
      .set('@', resolve('src'))
      .set('&', resolve('../infra/src'))
  }
}

tsconfig.json 调整

json 复制代码
{
  "extends": "../../tsconfig.common.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
        "&/*": [
            "../infra/src/*"
        ],
        "@/*": [
            "src/*"
        ]
    }
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx",
    "../frontend-infra/src/**/*.ts",
    "../frontend-infra/src/**/*.tsx",
    "../frontend-infra/src/**/*.vue",
    "../frontend-infra/src/**/*.ts",
    "../frontend-infra/src/**/*.tsx"
  ]
}

多仓库管理 workspaces 改造

naraku 最外层 package.json 指定 workspaces

json 复制代码
{
  "name": "naraku",
  "version": "1.0.0",
  "description": "",
  "private": true, // 一定要指定为私有仓库
  "workspaces": [ // 指定子仓库的 glob 路径
    "apps/*"
  ],
  "main": "index.js",
  "scripts": {
    "alias": "cross-env APP_NAME=${APP_NAME} node script.js run",
    "bundle": "yarn alias bundle",
    "publishBundle": "yarn alias publishBundle"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/node": "^24.3.0",
    "@types/webpack-env": "^1.18.8"
  },
  "dependencies": {
    "commander": "^9.5.0",
    "cross-env": "7.0.3",
    "shelljs": "^0.8.5"
  }
}

启动工程

bash 复制代码
yarn workspace apple run start | build

cicd 改造

通过以上改造之后,单体工程无法单独启动,需要改造通过 naraku 这个 shell 工程启动,构建,我这里是通过在jenkins pipeline 中指定环境变量,来启动不同的工程。

为使用构建需要 ,改造了npm script,所有命令通过 yarn alias 转发, 在根目录新建 script.js

js 复制代码
const { Command } = require('commander');
const shelljs = require('shelljs');
const program = new Command();
const path = require('path');

program
  .name('workspace-alias')
  .description('CLI to turn APP_NAME to package.json name utilities')
  .version('1.0.0');

const workspaceMap = generatedAliasMap()
program.command('run')
  .description('Working with APP_NAME to workspace alias')
  .helpOption('-e, --HELP', 'read more information')
  .argument('<string...>', 'e.g. "build" or "start"')
  .option('-w, --workspace <type>', 'workspace: ' + Object.keys(workspaceMap).join(' | '), process.env.APP_NAME)
  .option('-v, --verbose [type]', 'verbose mode, just ouput the shell going to run', false)
  .action((actions, opts) => {
    // 映射目录 与 workspace
    const workspace = workspaceMap[opts.workspace]
    if (!workspace) {
      console.error(`Workspace alias for "${opts.workspace}" not found!`)
      process.exit(1)
    }

    const script =`yarn workspace ${workspace} ${actions.join(' ')}`
    if (opts.verbose) {
      greenLog(script)
      return
    }

    greenLog(script);
    shelljs.exec(script);
  });

program.parse();

function generatedAliasMap () {
  const apps = shelljs.ls('-d', 'apps/*/')
  const aliasMap = apps.reduce((acc, appPath) => {
    const pkg = require(`./${appPath}/package.json`)
    acc[path.basename(appPath)] = pkg.name
    return acc
  }, {})
  return aliasMap
}

function greenLog (msg) {
  console.log('\x1B[32m%s\x1B[0m', msg)
}

启动工程

bash 复制代码
# yarn alias [action] -w [app_path]
yarn alias start -w infra

优缺点

优点

  1. 通过以上改造实现了保留单体 git 记录。
  2. 随着业务的演进,能够实时同步代码。
  3. 工程改造量较小。
  4. 易于branch 分支管理。

缺点

  1. 单体仓库无法启动。
  2. 单体仓库的改动可能导致 dashboard 无法正常 work。

总结

都看到这里了,如果你有更多好的建议,欢迎在评论区留言。

相关推荐
一 乐5 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
C_心欲无痕5 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫5 小时前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo6 小时前
前端跨页面通信终极指南:方案拆解、对比分析
前端
yinuo7 小时前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
xkxnq7 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
烛阴7 小时前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
xkxnq8 小时前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
anyup9 小时前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos
BBBBBAAAAAi9 小时前
Claude Code安装记录
开发语言·前端·javascript