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

背景

公司从 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。

总结

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

相关推荐
云枫晖2 小时前
JS核心知识-数据转换
前端·javascript
RaidenLiu2 小时前
Riverpod 3:重建控制的实践与性能优化指南
前端·flutter
学习中的小胖子2 小时前
React的闭包陷阱
前端
不卷的攻城狮2 小时前
【精通react】(五)react 函数时组件为什么需要 hooks?
前端
十八朵郁金香3 小时前
深入解析:ES6 中 class 与普通构造器的区别
前端·ecmascript·es6
索迪迈科技3 小时前
CommonJS与ES6模块的区别
前端·ecmascript·es6
前端Hardy3 小时前
12个被低估的 CSS 特性,让前端开发效率翻倍!
前端·javascript·css
前端Hardy3 小时前
HTML&CSS:精美的3D折叠卡片悬停效果
前端·javascript·css
nightunderblackcat3 小时前
新手向:中文语言识别的进化之路
前端·javascript·easyui