1. 特性

ucf-web 微前端工程主要是通过 [ucf-scripts](https://github.com/iuap-design/ucf-web/tree/master/packages/ucf-scripts) 工具去执行项目的运行和构建,它支持 ES 最新语法,包括注解、async、await等,并将less、babel7、webpack4、autoprefixer、postcss、代理、静态服务等最新的主流前端技术栈集合来实现项目的工程化能力。

2. 配置文件

UCF微前端工程核心配置文件只有一个 ucf.config.js ,下面对配置文件具体说明。

文件中部分不使用的配置属性可以将其删除。

**

  1. module.exports = () => {
  2. return {
  3. context:"", // 上下文对象
  4. // 启动所有模块,默认这个配置,速度慢的时候使用另外的配置
  5. // bootList: true,
  6. // 启动这两个模块,不启动调试,关闭构建
  7. bootList: [
  8. "demo-app-org",
  9. "demo-app-staff"
  10. ],
  11. templateType: 'ejs', // ejs 文件;默认为 html 文件,则可无需配置该参数
  12. // babel presets
  13. babel_presets: [
  14. //require.resolve('@babel/preset-react')
  15. ],
  16. // babel plugins
  17. babel_plugins: [
  18. [require.resolve("babel-plugin-import-bee"),
  19. {
  20. "libraryName": "tinper-bee"
  21. }]
  22. ],
  23. // 代理的配置
  24. proxy: [
  25. {
  26. enable: true,
  27. headers: {
  28. // 与下方url一致
  29. "Referer": "http://iuap-meger-demo.test.app.yyuap.com"
  30. },
  31. //要代理访问的对方路由
  32. router: [
  33. '/iuap'
  34. ],
  35. // pathRewrite: {
  36. // '^/api/old-path': '/api/new-path', // rewrite path
  37. // '^/api/remove/path': '/path' // remove base path
  38. // },
  39. url: 'http://iuap-meger-demo.test.app.yyuap.com'
  40. }
  41. ],
  42. // 静态托管服务
  43. static: 'ucf-common/src/static',
  44. // 是否展开静态引用资源
  45. res_extra: true,
  46. // 构建资源是否产出SourceMap,默认开启
  47. open_source_map: true,
  48. // CSS loader 控制选项
  49. css: {
  50. modules: false
  51. },
  52. // 全局环境变量
  53. global_env: {
  54. GROBAL_HTTP_CTX: JSON.stringify("/iuap_demo"),
  55. },
  56. // 别名配置
  57. alias: {
  58. //'ucf-apps': path.resolve(__dirname, 'ucf-apps/')
  59. },
  60. // 构建排除指定包
  61. externals: {
  62. //'tinper-bee': 'TinperBee'
  63. },
  64. // 加载器Loader
  65. loader: [],
  66. // 调试服务需要运行的插件
  67. devPlugins: [],
  68. // 构建服务需要运行的插件
  69. buildPlugins: []
  70. }
  71. }

3. API

配置项 说明 默认值 可选值 备注
bootList 启动、构建入口配置,true表示所有模块全部启用,数组参数按需模块使用 true true,['app-name','app-demo'] 一般默认开启所有模块的调试和构建,低配置机器或者只需要开发一块模块的话可以选择性的去配置单独启动
templateType 模版类型配置 ‘html’ ‘ejs’ 其他模版文件
proxy 开发调试阶段的代理服务配置 [] enable:true是否有效代理,false表示关闭. headers:{}设置代理请求的消息头. router:['/iuap','wbalone']. url:'proxy.example.com'. 本地请求代理对方服务器地址. pathRewrite:{}URL重写服务. opts:{}如内置配置无法满足需求,需要单独设置原生配置 http-proxy-middleware. 数组节点可以配置多条代理服务,通过enable来控制启用哪个,针对一些服务器校验头信息例如:Referer等就需要设置,其他常规的设置工具已经内置,代理路由router表示设置的几个路由访问后会代理到对方服务器上,url就是对方服务器地址
global_env 程序内公共变量 null 同webpack4 { key : value } 接收K、V格式如:{GROBAL_HTTP_CTX: JSON.stringify(“/iuap_demo”)}
alias 别名 null 同webpack4 {key : value} 接收K、V格式如:{‘ucf-apps’: path.resolve(__dirname, ‘ucf-apps/‘)}
externals 排除指定的包用外部变量代理提升打包性能 null 同webpack4 { key : value } 接收K、V格式如:{‘tinper-bee’: ‘TinperBee’}
loader 内置加载器无法处理需要单独去设置处理 [] 同webpack4 loader
devPlugins 开发环境加载的插件 [] 同webpack4 plugin 开发阶段使用的插件
buildPlugins 生产环境加载的插件 [] 同webpack4 plugin 生产阶段使用的插件
open_source_map 构建资源生产环境的时候产出sourceMap true true,false 只是在build的时候才会生效
css css loader的options - - 具体参考https://www.npmjs.com/package/css-loader
context 上下文对象 - - 在项目后添加此路径
static 静态托管服务 - - 加载本地http服务
res_extra 展开静态打包资源 false true,false 优化vendor、提取images、fonts等
babel_presets babel presets - babel-presets相关
babel_plugins babel plugin - babel 使用的插件
scan_root 自定义文件夹作为扫描微应用入口 - 原则上是按照./自定义目录/*/src/app.js扫描
dist_root 输出自定义文件夹 - -
postcss_plugins PostCss Plugin - -

4. 详细说明

context

脚手架输出的上下文字段

  1. /ucf-publish/context/demo1/index.js

bootList

启动控制器,用于设置启动哪些微应用,可以单独启动某一处,也可以启动所有

  1. // 启动所有的微应用
  2. bootList: true
  1. // 单独启动demo1、demo2
  2. bootList: [
  3. "demo1",
  4. "demo2"
  5. ]

proxy

用于设置开发阶段的代理服务(生产构建发布无效),基于 http-proxy-middleware 二次开发,可以使用默认参数快速使用,也可以使用原生options参数传入给中间件

  1. // 基础使用代理
  2. proxy: [
  3. {
  4. // 启用、禁用该条规则
  5. enable: true,
  6. // 请求代理服务的消息头
  7. headers: {
  8. "Referer": "https://mock.yonyoucloud.com"
  9. },
  10. //本地路由代理到远端
  11. router: [
  12. '/mock'
  13. ],
  14. url: 'https://mock.yonyoucloud.com'
  15. }
  16. ]

启动调试服务后,本机开启:http://127.0.0.1:3000/mock 代理服务。例如访问:http://127.0.0.1:3000/mock/843/basic 服务,代理会访问对方的主机服务为:https://mock.yonyoucloud.com/mock/843/basic

实际上开发过程中,我们使用的代理服务并不是那么顺利,有的时候后端的接口会随时改变,那么前端就要对接着改变,这样无疑是增大了前端工作量,针对这类问题,代理服务也有对应的对策,继续往下看

  1. // 使用pathRewrite来改写我们请求的代理路由
  2. proxy: [
  3. {
  4. // 启用、禁用该条规则
  5. enable: true,
  6. // 请求代理服务的消息头
  7. headers: {
  8. "Referer": "https://mock.yonyoucloud.com"
  9. },
  10. pathRewrite: {
  11. '^/mock/api' : '/new/api'
  12. },
  13. //本地路由代理到远端
  14. router: [
  15. '/mock'
  16. ],
  17. url: 'https://mock.yonyoucloud.com'
  18. }
  19. ]

可以看出,增加pathRewrite字段,key代表是我们本地要访问的代理路由,value是远端服务器被解析转换的路由,这样当我们访问了http://127.0.0.1:3000/mock/api/842/action后,会被解析为https://mock.yonyoucloud.com/new/api/842/action
当访问正确后控制台会显示如下信息:

  1. [HPM] Rewriting path from "/mock/api" to "/new/api"
  2. [HPM] GET /mock/api ~> https://mock.yonyoucloud.com
  3. [HPM] Rewriting path from "/mock/api" to "/new/api"
  4. [HPM] GET /mock/api ~> https://mock.yonyoucloud.com
  5. [HPM] Rewriting path from "/mock/api" to "/new/api"
  6. [HPM] GET /mock/api ~> https://mock.yonyoucloud.com
  7. [HPM] Rewriting path from "/mock/api" to "/new/api"
  8. [HPM] GET /mock/api ~> https://mock.yonyoucloud.com

除了上面快速使用外,如达不到你的开发要求,可以使用原生中间件参数来传递,具体如下:

  1. // 使用opts字段来转换原生参数
  2. proxy: [
  3. {
  4. // 启用、禁用该条规则
  5. enable: true,
  6. // 开启 http-proxy-middleware 中间件参数设置
  7. opts : {
  8. // 这里按照 https://www.npmjs.com/package/http-proxy-middleware#http-proxy-options 中options编写
  9. }
  10. }
  11. ]

babel_presets

自定义传入让UCF加载babel presets

  1. // 让babel使用@babel/preset-typescript
  2. babel_presets: [
  3. require.resolve('@babel/preset-typescript')
  4. ]

babel_plugins

自定义传入让UCF加载babel plugin

  1. // 启用组件库按需加载插件
  2. babel_plugins: [
  3. [require.resolve("babel-plugin-import-bee"),
  4. {
  5. "libraryName": "tinper-bee"
  6. }]
  7. ]

static

静态http服务,用作本地不参与import加载的资源使用,类似webpack-dev-server里的contentBase,仅仅用于开发调试,请使用正确导入资源使用

  1. {
  2. static: 'ucf-common/src/static'
  3. }

res_extra

释放静态资源并且优化js、css

  1. // true 优化、false 不优化单独构建在独立文件
  2. res_extra: false

开启该选项后,构建资源对比:

  1. ucf-publish
  2. └── demo-app-org
  3. ├── index.css
  4. ├── index.html
  5. └── index.js
  6. 1 directory, 3 files

当开启参数后:

  1. ucf-publish
  2. ├── assets
  3. └── fonts
  4. ├── iconfont.2b12aa52.eot
  5. ├── iconfont.454e95d8.svg
  6. ├── iconfont.bed8b35e.ttf
  7. └── iconfont.ee989690.woff
  8. └── demo-app-org
  9. ├── index.css
  10. ├── index.html
  11. └── index.js
  12. 3 directories, 7 files

可以看出区别,产出了assets静态提取文件夹,如果是两个以上的微应用的话,效果如下:

  1. ucf-publish
  2. ├── assets
  3. └── fonts
  4. ├── iconfont.2b12aa52.eot
  5. ├── iconfont.454e95d8.svg
  6. ├── iconfont.bed8b35e.ttf
  7. └── iconfont.ee989690.woff
  8. ├── demo-app-org
  9. ├── index.css
  10. ├── index.html
  11. └── index.js
  12. ├── demo-app-org2
  13. ├── index.css
  14. ├── index.html
  15. └── index.js
  16. ├── vendor.css
  17. └── vendor.js
  18. 4 directories, 12 files

当微应用大于两个以上,会发现做了splitChunk优化,提取了vendor.cssvendor.jsassets文件夹

open_source_map

开启构建后的SourceMap功能,只针对生产构建环境有效

  1. open_source_map: true
  1. ucf-publish
  2. └── demo-app-org
  3. ├── index.css
  4. ├── index.html
  5. ├── index.js
  6. └── index.js.map
  7. 1 directory, 4 files

css

传递css-loader的options

  1. // 开启css modules
  2. // 更多options查询https://www.npmjs.com/package/css-loader#options
  3. css: {
  4. modules: true
  5. }

global_env

项目内全局环境变量

  1. // 注入一个GROBAL_HTTP_CTX值为/iuap_demo
  2. GROBAL_HTTP_CTX: JSON.stringify("/iuap_demo")
  3. ...
  4. // 程序内使用
  5. const url = `${GROBAL_HTTP_CTX}/repo`

alias

项目依赖别名,可以把一个路径设置为别名包的形式

  1. alias: {
  2. 'ucf-apps': path.resolve(__dirname, 'ucf-apps/')
  3. }

在代码中可以这样使用:

  1. // 使用alias
  2. import { Apps } from 'ucf-apps';
  3. ...
  4. // 没有使用alias
  5. import { Apps } from '../../ucf-apps';

脚手架中内置了一些常用的别名,如下:

  1. alias: {
  2. 'ucf-apps': path.resolve('.', 'ucf-apps/'),
  3. 'ucf-common': path.resolve('.', 'ucf-common/src/'),
  4. components: path.resolve('.', 'ucf-common/src/components/'),
  5. static: path.resolve('.', 'ucf-common/src/static/'),
  6. utils: path.resolve('.', 'ucf-common/src/utils/')
  7. }

externals

优化构建速度、体积,可以把我们指定的包进行排除,不参与打包构建,使用外部全局变量代替

  1. // 不使用npm下的node_modules/tinper-bee组件打包
  2. // key字段代表项目内from 'tinper-bee',value代表外部的变量
  3. externals: {
  4. 'tinper-bee': 'TinperBee',
  5. 'jQuery': 'window.jQuery'
  6. }

打包构建的时候会发现UCF不会把这俩包打包到我们的js里,而是使用外部的变量

loader

传入webpack4的loader参数

  1. // 添加TypeScript支持
  2. loader: [{
  3. test: /\.tsx?$/,
  4. use: [
  5. {
  6. loader: 'ts-loader',
  7. options: {
  8. transpileOnly: true
  9. }
  10. }
  11. ]
  12. }]

devPlugins

调试模式的插件传入

  1. // 调试模式添加进度条加载插件
  2. const webpack = require('webpack');
  3. ...
  4. devPlugins: [
  5. new webpack.ProgressBar()
  6. ]

buildPlugins

生产模式的插件传入

  1. const webpackBundleReport = require('webpack-bundle-report')
  2. buildPlugins: [
  3. new webpackBundleReport()
  4. ]

scan_root

自定义扫描微应用的文件夹,默认使用ucf-apps,如果你想设置自己的目录使用该参数

  1. // 使用自己项目内apps作为主要扫描
  2. scan_root: 'apps';

扫描规则是./${scan_root}/*/src/app.js为有效的微应用,其他不匹配规则视为普通目录

注:规则匹配使用glob

dist_root

自定义输出目录,默认使用ucf-publish,可以设置任意系统位置

  1. // 设置当前根目录 dist 为输出目录
  2. dist_root: 'dist'

还可以输出到指定不同级别的目录下:

  1. // 输出到Java开发环境下指定位置
  2. dist_root: '../../../JavaWeb/Maven/webapp/src/static'

host

启动UCF服务的时候绑定的IP或域名,支持IPV4、IPV6

  1. // 绑定自定义域名
  2. host: 'game.imyy.org'
  3. // 绑定自定义IP
  4. host: '10.1.26.87'

postcss_plugins

设置PostCss Loader的插件传入配置

  1. // 传入自定义postcss插件,支持参数
  2. postcss_plugins: [
  3. [require.resolve("postcss-pxtorem"),
  4. {
  5. "options": "tinper-bee"
  6. }]
  7. ]

5. 常见问题

组件库的按需加载

当你的项目只用到了部分组件,你想要更小的打包体积的时候,我们提供了按需加载的能力

  1. import { Button } from 'tinper-bee'; // 这样会把整个组件库全部打包加载进来
  2. // 转换为:
  3. import Button from 'tinper-bee/lib/Button'; // 单独使用组件,按需使用

如何在UCF中使用:

  1. # 安装babel插件
  2. # 查看插件 https://www.npmjs.com/package/babel-plugin-import-bee
  3. npm install babel-plugin-import-bee -D

配置

  1. babel_plugins: [
  2. [require.resolve("babel-plugin-import-bee"),
  3. {
  4. "libraryName": "tinper-bee",
  5. "libraryDirectory": "lib"
  6. }]
  7. ]

启动时默认打开指定页面

通过配置npm启动命令来实现调试运行后自动开启浏览器
packages.json scripts 命令行传入--homepage

  1. "scripts": {
  2. "start": "ucf-scripts start --homepage=demo-app-org",
  3. "build": "ucf-scripts build"
  4. }

修改自定义端口

通过配置npm启动命令来实现调试运行后自动开启浏览器
packages.json scripts 命令行传入--port

  1. "scripts": {
  2. "start": "ucf-scripts start --port=9000",
  3. "build": "ucf-scripts build"
  4. }

proxy 代理

一般使用按照下面配置就可以使用代理服务:

  1. proxy: [
  2. {
  3. enable: true,
  4. headers: {
  5. "Referer": "http://iuap-meger-demo.test.app.yyuap.com"
  6. },
  7. pathRewrite:{},
  8. //要代理访问的对方路由
  9. router: [
  10. '/iuap'
  11. ],
  12. url: 'http://iuap-meger-demo.test.app.yyuap.com'
  13. }
  14. ]

也可以直接传入原始参数,基于 http-proxy-middleware 封装,参数一致,通过下面配置 opts 开启原始参数:

  1. proxy: [
  2. {
  3. opts: {
  4. target: 'http://www.example.org', // target host
  5. changeOrigin: true, // needed for virtual hosted sites
  6. ws: true, // proxy websockets
  7. pathRewrite: {
  8. '^/api/old-path': '/api/new-path', // rewrite path
  9. '^/api/remove/path': '/path' // remove base path
  10. },
  11. router: {
  12. // when request.headers.host == 'dev.localhost:3000',
  13. // override target 'http://www.example.org' to 'http://localhost:8000'
  14. 'dev.localhost:3000': 'http://localhost:8000'
  15. }
  16. }
  17. }
  18. ]

按需启动

默认可以使用 bootList:true 来加载所有微服务应用,如果仅仅加载一个或多个模块设置如下:

  1. // 单独启动模块
  2. bootList: [
  3. "demo-app-org",
  4. "demo1",
  5. "demo2"
  6. ]

这样设置后的话,ucf-web 就会查找 ucf-apps 下的 demo-app-org 单独去运行或构建,设置该项可以大大提高启动和构建速度。

运行出错找不到包

这类问题应该是在npm 安装、卸载的时候删除了需要的包,卸载后再安装即可

  1. // 卸载完全版本
  2. npm un ucf-scripts -D
  3. // 安装全新版本
  4. npm i ucf-scripts@latest -D

自定义传入Cookies

一般登录信息的Cookies都是服务器端登录自动跳转写入到我们代理本地的,但是有特殊情况,如后端给了固定有效的Cookies信息,需要我们前端在代理服务写入,如下:

  1. // 自定义Cookies
  2. proxy: [
  3. {
  4. // 启用
  5. enable: true,
  6. // Header
  7. headers: {
  8. "Referer": "https://mock.yonyoucloud.com",
  9. // 传入自己有效的Cookies
  10. "cookie": "yht_username=test;yht_usertoken=token"
  11. },
  12. // 要代理访问的对方路由
  13. router: [
  14. '/mock'
  15. ],
  16. // 对方代理主机
  17. url: 'https://mock.yonyoucloud.com'
  18. }
  19. ]