前端微服务化解决方案6 - 构建与部署

微前端打包构建

微前端项目的打包,是有一些需要注意的点 以webpack为例:

amd模块

在之前的文章,我们有提到我们的加载器,是基于System.js来做的. 所以我们微前端的模块最终打包,是要符合模块规范的. 我们使用的是amd模块规范来构建我们的模块.

指定基础路径

因为模块打包后,调用模块出口文件的,是模块加载器. 为了清晰的管理每个模块,并且正确的加载到我们每一个模块的资源, 我们给模块的资源都指定一个publicPath.

下面给出一个简单的 webpack 配置,这些配置我只是列出一些必要选项. 并不是一个完整的webpack配置,后续我会提供完整的微前端的Demo,提供大家参考 这些配置都是基于 create-react-app 的配置做的修改. 只要明白了配置的意图,明白我们打包出来的最终是一个什么样的包, 不管打包工具以后怎么变,技术栈怎么变,最后都是可以对接到微前端中来.

这里给出 project.json 的内容,便于后面的配置文件的阅读

// project.json
{
    "name": "name", //模块名称
    "path": "/project", //模块url前缀
    "prefix": "/module-prefix/", //模块文件路径前缀
    "main": "/module-prefix/main.js", //模块渲染出口文件
    "store": "/module-prefix/store.js",//模块对外接口
    "base": true // 是否为baseapp
  }

// 引入项目配置文件,也是前面说的 模块加载器必要文件之一
const projectConfig = require('./project.json')

let config = {
  entry: {
    main: paths.appIndexJs, //出口文件,模块加载器必要文件之一
    store: paths.store // 对外api的reducer文件,模块加载器必要文件之一
  },
  output: {
    path: paths.appBuild,
    filename: '[name].js?n=[chunkhash:8]',
    chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
    publicPath: projectConfig.prefix, //在output中指定模块配置好的 publicPath
    libraryTarget: 'amd', //对外输出 amd模块,便于 system.js加载
    library: projectConfig.name, //模块的名称
  },
  },
  module: {
    rules: [
      {
        oneOf: [
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            // loader: 'happypack/loader?id=url',
            loaders: [{
              loader: require.resolve('url-loader'),
              options: {
                limit: 5000,
                name: 'static/media/[name].[hash:8].[ext]',
                publicPath: projectConfig.prefix, //我们需要在静态文件的loader加上publicPath
              },
            }]
          },
          {
            test: /\.(js|jsx|mjs)$/,
            include: paths.appSrc,
            loader: 'happypack/loader?id=babel',
            options: {
                name: 'static/js/[name].[hash:8].[ext]',
                publicPath: projectConfig.prefix, //在静态文件的loader加上publicPath
              },
          },
          {
            loader: require.resolve('file-loader'),
            exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
            options: {
              name: 'static/media/[name].[hash:8].[ext]',
              publicPath: projectConfig.prefix, //在静态文件的loader加上publicPath
            },
          },
        ],
      },
    ],
  },
}

部署

前端单页面的部署,不管怎么自动化,工具怎么变. 都是把打包好的静态文件,放到服务器的正确位置下. 微前端的部署,是一个应用聚合的过程,我们如何把一个个模块最后接入到一个完整的项目中的呢?

微前端应用完整目录

一般会放在一个nginx配置好的静态目录里,或者是其他web容器的一个静态目录. 看到这个目录结构,你应该能理解为什么要额外的配置 publicPath 了吧.

├── index.html              // 首先浏览器会加载这个index.html,html里面会引入一个bootstrap.js的文件
├── bootstrap.js            // 这个bootstrap.js是之前说的模块加载器打包过后的代码,
│                           // 模块加载器会先加载 `project.config.js`,得到所有模块的配置.
│                           // 然后才开始加载每个项目中的main.js文件,注册应用,注入store.js
│
├── project.config.js       // 这个文件存到是该项目的所有模块的配置,是代码自动生成的
│                           // 之前有提到过项目配置自动化,是这个项目中唯一动态的文件.
│                           // 目的是让模块的配置文件更新,或者新增新模块的时候,模块会自动挂载到项目中来
│                           // 他会遍历每一个模块的project.json文件,取出内容,合并到一起
│
├── projectA                // 模块A目录
│   ├── asset-manifest.json
│   ├── favicon.ico
│   ├── main.js             // 渲染用的出口文件
│   ├── manifest.json
│   ├── project.json        // 模块的配置文件
│   ├── static
│   │   ├── js
│   │   │   ├── 0.86ae3ec3.chunk.js
│   │   └── media
│   │       └── logo.db0697c1.png
│   └── store.js            //对外输出的store.js 文件
└── projectB                // 模块B (重要文件的位置,与模块A是一致的)
    ├── asset-manifest.json
    ├── main.js
    ├── manifest.json
    ├── project.json
    ├── static
    │   ├── js
    │   │   ├── 0.86ae3ec3.chunk.js
    │   └── media
    │       └── logo.db0697c1.png
    └── store.js

配置自动化

我们每个模块都有上面所描述的配置文件,当我们的项目多个模块的时候,我们需要把所有模块的配置文件聚合起来. 我这里也有写一个脚本.

micro-auto-config

使用方法:

npm install micro-auto-config -g

# 在项目根目录,用pm2启动该脚本,便可启动这个项目的配置自动化
pm2 start micro-auto-config --name 你的项目名称-auto-config

这样之后 project.config.js 就会自动生成,以及模块变动之后也会重新生成.

未完待续 …

相关文章

前端微服务化解决方案1 - 思考

前端微服务化解决方案2 - Single-SPA

前端微服务化解决方案3 - 模块加载器

前端微服务化解决方案4 - 消息总线

前端微服务化解决方案5 - 路由分发

前端微服务化解决方案6 - 构建与部署

前端微服务化解决方案7 - 静态数据共享

前端微服务化解决方案8 - 二次构建

Demo

前端微服务化 Micro Frontend Demo

微前端模块加载器

微前端Base App示例源码

微前端子项目示例源码

本文链接:

https://alili.tech/archive/ffb0c5ab/