这是我从开始使用 VueJS 的第一天起就一直在尝试解决的问题。如果客户端JS框架不能解决这个问题,我不会考虑它。
我最近在这方面做了一个 PoC,并且能够在另一个 VueJS 应用程序中使用一个 VueJS 应用程序作为模块。就我而言,我有一套 VueJs 应用程序,其中每个应用程序都在其自己的专用 docker 容器中运行。这些应用程序具有许多在所有应用程序中通用的功能。所以我决定将这个通用代码(页面布局、css 框架等)移动到一个单独的 VueJS 应用程序中,并将所有现有的 VueJS 应用程序作为这个全局应用程序中的模块来使用。我称这种基于微应用的架构是为了将其与基于微前端的架构区分开来,因为它不使用多个客户端 JS 框架,也不需要另一个框架来实现这一点。这就是我的部署架构的样子(如果你不知道,你可以忽略 kubernetes 特定的东西)-
回到实现部分,您需要逐步将 VueJS 应用程序转换为微应用程序。
- 假设您的项目结构如下所示(它仅显示需要更改的少数文件,而不是所有文件)-
app-1
public
index.html
src
main.js
App.vue
router
index.js
store
index.js
- 将您的 vuex 状态和路由文件拆分为全局文件和应用程序特定文件 -
app-1
public
index.html
src
main.js
App.vue
router
app1
index.js
index.js
store
app1
index.js
index.js
- 复制此项目(全局应用程序),从
app-1 中删除global-app 特定文件,并从global-app 中删除特定文件中的app-1。还要从 app-1 项目中删除 index.html 和 App.vue -
- 在
global-app的index.html文件中添加ROUTES和STORE_MODULES变量-
<head>
....
....
<script type="text/javascript">
const ROUTES = []
const STORE_MODULES = {}
</script>
</head>
<body>
....
....
<div id="app"></div>
<script type="text/javascript" src="/app1/micro-app.umd.min.js"></script>
<!-- built files will be auto injected -->
</body>
- 为
ROUTES 变量更新global-app 的router\index.js 文件-
const routes = [
....
....
]
routes.push(...ROUTES)
const router = new VueRouter({
- 为
STORE_MODULES 变量更新global-app 的store\index.js 文件-
export default new Vuex.Store({
....
....
modules: STORE_MODULES
})
- 清除
app-1\src\main.js文件的内容并替换为以下内容-
import routes from '@/router/app1'
import app1 from '@/store/app1'
ROUTES.push(...routes)
STORE_MODULES['app1'] = app1
- 在
package.jsonapp-1 文件的scripts 块下定义build-app 命令-
....
"scripts": {
"build-app": "vue-cli-service build --target lib --formats umd-min --no-clean --name micro-app src/main.js"
},
....
- 现在在它们的专用容器中构建和部署这两个应用程序,并更新代理容器的 nginx conf 文件以将请求转发到这些容器,如下所示 -
location / {
proxy_pass http://global-app:80;
}
location /app1/ {
proxy_pass http://app1:80/;
}
- 您可以使用nginx容器的IP地址和端口访问全局应用程序。
我希望我已经包含了实现基于微应用的架构所需的所有步骤。您可以参考以下作为此 PoC 的一部分创建的 git 存储库 -
https://github.com/mechcloud/large-app-docker
https://github.com/mechcloud/large-app
https://github.com/mechcloud/large-app-plugin1
虽然我不是客户端 JS 框架内部的专家,但我相信这种方法也适用于其他 JS 框架(Angular、React 等)。