前端工程化之submodule

268 阅读2分钟

最近接触了一个前端项目, 多个项目组件 link 开发, 经常遇到 link 出错的问题,

导致项目 run 不起来。

于是尝试 接入submodule,实现开箱即用, 做此笔记:

文件结构如下:

创建父级项目目录 LOWCODE, scripts下为工程使用的脚本。 src下为 5个相互依赖link 关系的 子项目。

package.json 如下:

{
  "name": "lowcode",
  "version": "1.0.0",
  "license": "MIT",
  "scripts": {
    "ck": "node ./scripts/ck.js",
    "install:all": "node ./scripts/inst.js",
    "link:all": "node ./scripts/link.js",
    "run:all": "node ./scripts/run.js"
  },
  "dependencies": {},
  "repository": "git@git.***/lowcode.git",
  "devDependencies": {
    "chalk": "^4.0.0",
    "child_process": "^1.0.2",
    "shelljs": "^0.8.4"
  }
}

scripts 为使用的4个脚本命令:

  • ck 为切换分支命令: yarn ck ${分支名}   如不提供分支,默认到 master

  • install:all 为安装所有项目依赖

  • link:all 为处理link 关系

  • run:all 为启动 mac 终端 Terminal 

因使用 mac 终端 Terminal,且使用 yarn 为脚本,所以需要使用 mac 电脑安装 yarn 使用。

ck.js

const path = require("path");

const dirsrc = path.resolve(__dirname, "../src");

const execSync = require("child_process").execSync;

const branch = process.argv[2];
log(branch ? `提供分支:${branch}` : '未提供分支,切换默认 master 主分支');

const runBranch = branch || 'master';
log(`ant-seed-ui -> ${runBranch}`);
run(`cd ${dirsrc}/ant-seed-ui && git checkout ${runBranch}`);

log(`enginejs-default-ui -> ${runBranch}`);
run(`cd ${dirsrc}/enginejs-default-ui && git checkout ${runBranch}`);

log(`enginejs-logic -> ${runBranch}`);
run(`cd ${dirsrc}/enginejs-logic && git checkout ${runBranch}`);

log(`app-saas -> ${runBranch}`);
run(`cd ${dirsrc}/app-saas && git checkout ${runBranch}`);

log(`kcp -> ${runBranch}`);
run(`cd ${dirsrc}/kcp && git checkout ${runBranch}`);

log(`执行结束`);

function run(sh) {
  let res;
  try {
    res = execSync(sh);
    console.log(res.toString());
  } catch (error) {
    process.exit(-1);
  }
}

function log(msg) {
  console.log();
  console.log("\x1B[36m%s\x1B[0m", `-------- ${msg}`);
  console.log();
}

inst.js

const path = require("path");
const shell = require('shelljs');
const chalk = require("chalk");

const dirsrc = path.resolve(__dirname, "../src");

const addNpmInstall = {
  "ant-seed-ui": {
    path: `${dirsrc}/ant-seed-ui`,
    color: "redBright",
  },
  "enginejs-default-ui": {
    path: `${dirsrc}/enginejs-default-ui`,
    color: "greenBright",
  },
  "enginejs-logic": {
    path: `${dirsrc}/enginejs-logic`,
    color: "yellowBright",
  },
  "app-saas": {
    path: `${dirsrc}/app-saas`,
    color: "blueBright",
  },
  "kcp": {
    path: `${dirsrc}/kcp`,
    color: "magentaBright",
  },
};

function runInstallAll() {
  console.log("==== 开始安装所有项目的 依赖 ====");
  for (const projectCode in addNpmInstall) {
    const { path: _path, color } = addNpmInstall[projectCode];
    shell.cd(_path);
    console.log(
      chalk[color](
        `【-----------------${projectCode} start---------------------】`
      )
    );

    console.log();
    shell.exec("pwd");

    console.log();
    shell.exec(`yarn`);

    console.log();
    console.log(
      chalk[color](
        `【-----------------${projectCode}   end---------------------】`
      )
    );
    console.log();
  }
  console.log("==== 所有依赖安装完成 ====");
}

runInstallAll();

link.js

const path = require("path");
const shell = require("shelljs");
const dirsrc = path.resolve(__dirname, "../src");

const addNpmInstall = {
  "ant-bud-ui": `${dirsrc}/ant-seed-ui`,
  "bud-bridge": `${dirsrc}/enginejs-default-ui`,
  "ui-logic-engine": `${dirsrc}/enginejs-logic`,
  "app-saas": `${dirsrc}/app-saas`,
  kcp: `${dirsrc}/kcp`,
};

log(` 开始执行 link 关系 `);

log(` 首先暴露 ant-bud-ui、bud-bridge、ui-logic-engine `);

for (const item of ["ant-bud-ui", "bud-bridge", "ui-logic-engine"]) {
  shell.cd(addNpmInstall[item]);
  shell.exec(`yarn link`);
  log(`${item} link 完成`);
}

log(` enginejs-default-ui 包含 (ant-bud-ui、ui-logic-engine)`);
shell.cd(addNpmInstall["bud-bridge"]);
for (const item of ["ant-bud-ui", "ui-logic-engine"]) {
  shell.exec(`yarn link ${item}`);
  log(`enginejs-default-ui link ${item} 完成`);
}

log(` app-saas 包含 (ant-bud-ui、bud-bridge、ui-logic-engine)`);
shell.cd(addNpmInstall["app-saas"]);
for (const item of ["ant-bud-ui", "bud-bridge", "ui-logic-engine"]) {
  shell.exec(`yarn link ${item}`);
  log(`app-saas link ${item} 完成`);
}

log(` kcp 包含 (ant-bud-ui)`);
shell.cd(addNpmInstall["kcp"]);
for (const item of ["ant-bud-ui"]) {
  shell.exec(`yarn link ${item}`);
  log(`kcp link ${item} 完成`);
}

log(` 最后都依赖 app-saas 的 react 版本 `);
for (const item of ["ant-bud-ui", "bud-bridge", "ui-logic-engine", "kcp"]) {
  shell.cd(addNpmInstall[item]);
  shell.exec(`npm link ../app-saas/node_modules/react`);
  log(`${item} link react 完成`);
}

log(` 执行结束 `);

function log(msg) {
  console.log();
  console.log("\x1B[36m%s\x1B[0m", `-------- ${msg}`);
  console.log();
}

run.js

const path = require("path");
const shell = require("shelljs");
const chalk = require("chalk");

const dirsrc = path.resolve(__dirname, "../src");

const addNpmInstall = {
  "ant-seed-ui": {
    path: `${dirsrc}/ant-seed-ui`,
    shellScript: "npm run start",
  },
  "enginejs-default-ui": {
    path: `${dirsrc}/enginejs-default-ui`,
    shellScript: "npm run start",
  },
  "enginejs-logic": {
    path: `${dirsrc}/enginejs-logic`,
    shellScript: "npm run start",
  },
  "app-saas": {
    path: `${dirsrc}/app-saas`,
    shellScript: "npm run local",
  },
  kcp: {
    path: `${dirsrc}/kcp`,
    shellScript: "npm run dev",
  },
};

function runInstallAll() {
  console.log("==== 开始 run 所有项目 ====");
  for (const projectCode in addNpmInstall) {
    const { path: _path, shellScript } = addNpmInstall[projectCode];

    // shell.exec(`open -a Terminal ${_path} && pwd`);

    shell.exec(`osascript -e 'tell app "Terminal"
                    do script "cd ${_path} && ${shellScript}"
                end tell'`);

    console.log();
  }
  console.log("==== run 所有项目 完成 ====");
}

runInstallAll();

最后 README.md 为使用步骤

lowcode 低代码平台

必备工具: mac电脑、yarn、 gitlab配置ssh key 参考下面链接

使用步骤

# [0]克隆lowcode 以及子包 (相当于下面两步 1 + 2)
$ git clone --recursive git@git.***/lowcode.git

# [1]克隆lowcode
$ git clone git@git.***/lowcode.git

# [2]克隆 子包
$ git submodule update --init --recursive

# [3]安装 lowcode 外壳的依赖(脚本所需依赖)
$ cd lowcode && yarn

# [4]切换子包到指定分支(如不提供分支,默认到 master 和 online 主分支)
$ yarn ck ${分支名}

# [5]安装所有子项目的依赖
$ yarn install:all

# [6] link依赖包
$ yarn link:all

# [7] 最后 开启5个终端 run各自项目(5个项目)(可能需要电脑授权)
$ yarn run:all

# 单独开启
$ cd src/ant-seed-ui && npm run start
$ cd src/enginejs-default-ui && npm run start
$ cd src/enginejs-logic && npm run start
$ cd src/app-saas && npm run local
$ cd src/kcp && npm run dev

# 更新所有子模块代码
$ git submodule update --remote

注意

每次安装完新依赖后, 需要重新在lowcode根目录执行 yarn link:all

提供删除所有 node_modules 小工具

### 删除当前目录下所有的node_modules,包含子目录
```shell
$ find ./ -name node_modules -exec rm -rf {} ;
```