【实战】umi3.x+qiankun+模块联邦 搭建微前端应用(三)— 项目部署

·  阅读 1007

前言

这是 umi3.x+qiankun+模块联邦 搭建微前端应用系列的最后一章,先来回顾一下:上一章节我们主要是集成了webpack5 中的 module-federation 实现了各应用间公共组件和公共方法的实时共享,并解决了模块联邦与umi3.x框架的兼容问题。那么这一章节主要讲讲如何把一个微前端项目部署上线。

主要用到了gitlab CI/CDdocker等技术,在此之前需要各位看官了解相关的基础知识,这里有我之前写的一篇关于搭建gitlab私库的文章,传送门在这里

系列文章传送门:

【实战】umi3.x+qiankun+模块联邦 搭建微前端应用(一)— 项目初始化

【实战】umi3.x+qiankun+模块联邦 搭建微前端应用(二)— 集成qiankun

部署阶段

在项目根目录下新建 .gitlab-ci.yml 文件

image: node:latest

stages:
  - deploy

job_deploy:
  image: docker
  stage: deploy
  tags:
    - vitepro3
  script:
    - docker build -t citestimages1 .
    - if [ $(docker ps -aq --filter name=citest-container1) ]; then docker rm -f citest-container1;fi
    - docker run -d -p 80:80 --name citest-container1 citestimages1

复制代码

在项目根目录下新建 Dockerfile 文件

# 注意这里的node镜像版本 最新的17.x在安装依赖的时候会有问题
FROM node:14.15.0-alpine as builder

WORKDIR /app

COPY package.json pnpm-lock.yaml /app/

RUN npm config set registry --registry=http://registry.npm.taobao.org

RUN npm install -g pnpm@7.8.0

RUN pnpm install

COPY . .

RUN pnpm run deploy

FROM nginx:latest

COPY --from=builder /app/dist /usr/share/nginx/html

复制代码

修改主、子应用配置

主要涉及两个地方:打包输出的路径、静态资源请求路径

打包输出的路径

我们期望打包后主、子应用的包结构是这样的:

dist
├── index.html
├── sub_projects
│ ├── app1
│ └── app2
├── umi.css
└── umi.js
复制代码

配置子应用打包输出的路径

app1 项目

// vite.config.ts文件
build: {
  outDir: '../../dist/sub_projects/app1',
},
复制代码

app2 项目

// config/config.ts
outputPath: '../../dist/sub_projects/app2',
复制代码

配置 publicPath

app1 项目

// vite.config.ts文件
base: process.env.NODE_ENV === 'development' ? './' : `//yourhost/sub_projects/app1/`,
复制代码

app2 项目

// config/config.ts
base: process.env.NODE_ENV === 'development' ? './' : `//yourhost/sub_projects/app2/`,
复制代码

部署脚本

在主应用根目录新建:

scripts
├── build.js
├── utils.js
复制代码
// scripts/build.js

const { resolve } = require('path');
const { run, subProjectDirs, subProjectDir, projRoot } = require('./utils');

const buildSubProjects = async (index = 0) => {
  const projects = subProjectDirs();
  const projectsPath = resolve(projRoot, subProjectDir, projects[index]);
  await run('pnpm install', projectsPath);
  await run('pnpm run build', projectsPath);
  if (projects.length - 1 > index) {
    buildSubProjects((index += 1));
  }
};

const main = async () => {
  await run('pnpm run build');
  buildSubProjects();
};

main();
复制代码
// utils.js
const { spawn } = require("child_process");
const { resolve } = require("path");
const fs = require("fs");

// 项目根目录
const projRoot = resolve(__dirname, "..");

// 子应用目录
const subProjectDir = resolve(__dirname, "../sub-projects");

const subProjectDirs = () => fs.readdirSync(subProjectDir);

const run = async (command, cwd = projRoot) =>
  new Promise((resolve, reject) => {
    const [cmd, ...args] = command.split(" ");
    const app = spawn(cmd, args, {
      cwd,
      stdio: "inherit",
      shell: process.platform === "win32",
    });

    const onProcessExit = () => app.kill("SIGHUP");

    app.on("close", (code) => {
      process.removeListener("exit", onProcessExit);

      if (code === 0) resolve();
      else
        reject(
          new Error(`Command failed. \n Command: ${command} \n Code: ${code}`)
        );
    });
    process.on("exit", onProcessExit);
  });

module.exports = {
  projRoot,
  run,
  subProjectDir,
  subProjectDirs,
};
复制代码

ok! 最后将我们的代码提交至远程,自动触发 ci/cd,构建成功如图:

image.png

最后访问下吧:

20220818174306.gif

总结

这一章讲了整个应用的部署,主要涉及到打包的目录结构划分、publicPath路径的配置、以及打包脚本的编写,这些可以根据各位看官的实际情况而定,欢迎讨论。当然过程中还有很多不足,比如每次上线都是一次全量打包部署的过程,其实这个地方可以集成 jenkins,在每次上线时勾选需要打包部署的应用,真正做到微前端提出的子应用可独立发布。最后,这个系列也算告一段落了,过程中的不足,欢迎各位指出,菜鸟作者一定虚心接受。

分类:
前端
收藏成功!
已添加到「」, 点击更改