webapp项目架构畅想(vue3).md
我司现在使用vue3
做为新项目的框架,设计了如下的目录:
|--src
|-- assets/
|-- boot/
|-- components/
|-- config/
|-- lib/
|-- projects/
|-- flight/
|-- promotion/
|-- member/
|-- login/
|-- router/
|-- store
|-- App.vue
|-- main.js
简要说明:projects 下的每个目录,都是一个独立的项目,它们共同依赖外部的模块。
现阶段困境
生产环境刚开始使用 vite 默认的打包逻辑,它有一些问题:
- 公共包太大
- 修改一个模块,会使所有文件缓存失效
- 无法使用 webpackChunkName
所以我动手改造了下打包过程,具体思路如下:
- 从入口文件引入的三方包,打包成 vendor
- 路由带有 webpackChunkName 的,分别按名称打包
- 文件多次引用
- 被同一个 project 引用,打包成 [projectName]-share
- 被多个 project 引用,打包成 common
- src 文件夹下的内容打包成 common
这解决开头提到的几个问题,顺便还提了一个 rollup 的 bug issue。
但随着对项目的深入理解,我看到了一些有意思的情况。
首先,projects 下的项目彼此间并无太多交集,甚至可以看着是一个个独立的项目,但它们组成了一个大型单页应用(SPA)。所以,每次打包的时候,都得全量构建一次。可以预见的是,随着代码量的增加,生产环境的打包时间会越拉越长。
其次,虽然我们多数时候只会访问几个页面,但却不得不加载一堆不相关的依赖。这减缓了首屏的渲染时间,影响用户体验。
新架构设想
第一步:生成公共服务包
公共服务包应具有哪些内容?一个原则——内容公用、接口稳定。
具体到我们项目,应包含 vue、vuex、vue-router 源码及相关配置,请求(request)、登录注册(auth)、支付(payment)、全局组件等。将它们打包成一个文件,假设叫 common-service-[hash].js,此文件导出公共接口,通过外链(<script src="common-service-[hash].js">)
的方式,供他项目使用。
第二步:每个项目单独构建
每个子项目独立开发、构建,最终发布到同一个静态服务器中。
第三步:路由跳转中加载依赖文件
虽然每个子项目相对独立,但我们依然想要获得单页应用的使用体验。那么就需要在路由跳转前,把对应的项目依赖加载完毕后,再使用 vue-router 进行跳转。
新架构优点
- 减少子项目之间的耦合
- 减少生产环境编译时间
- 加快首页渲染速度
- SPA 般的使用体验
新架构的问题
软件开发没有银弹。新架构至少存在以下问题。
公共服务包中数据变更,如何全量通知子应用,且不影响子应用的缓存
我们通过 script 标签在 .html 中引入公共服务包。所以当公共服务包发生变更,只需替换所有 .html 文件中的内容,然后上传到服务器对应的目录。
子项目内容存在冗余
冗余是肯定有的,但可以根据具体场景优化
子项目如何通信
vuex
如何丝滑的加载子应用依赖
可以通过应用的 manifest.json 获取初始依赖,但这至少会增加一次网络请求。
构建过程变得非常复杂
软件复杂度不会消失,只会转移。
问题是,这值得么?