mip-project / mip

MIT License
11 stars 1 forks source link

MIP 2.0 的静态资源加载方案 #9

Open PengXing opened 6 years ago

clark-t commented 6 years ago

MIP 2.0 静态资源加载方案

背景

用户在开发组件的时候会引用第三方开源项目,项目公用资源(如utils、图片、字体等)、组件相互依赖等问题,在发布组件的时候如果将每个组件依赖到的资源全部 bundle 成一个 js,会造成严重的代码冗余问题,也破坏掉组件间依赖某些单实例(如 eventbus)进行数据传递的机制,因此需要更改组件打包方案,并且设计新的静态资源加载机制去解决这些问题。

组件打包方案设计

组件的打包流程为:

  1. 将所有的 .vue 文件编译成 .js 文件,不会将依赖的资源给 bundle 进来;
  2. 将所有的 .js 文件进行 babel 转码处理;
  3. 将所有的 .js 文件以 amd 模块的形式进行封装;

至此,所有的静态资源将以 amd 模块的方式使用,组件上线时,静态资源全部上传 cdn。

静态资源加载

MIP core 通过当前页面使用哪些组件,动态请求组件资源,模块载入框架考虑使用 esl。在 amd 模式下会造成前端大量请求 js 资源的问题,因此考虑引入 jet 来实现请求 combo。

jet 服务接入

  1. 前端采用 esl2.1.7 + jet-loader 的方式进行请求 combo;
  2. 组件打包增加 jet-dev-tool 编译静态资源流程,将编译产物上传至 jet 服务器;

需要考虑的问题:

  1. 静态资源是否需要经过 jet 服务器压缩、加 hash;
  2. 如果不加 hash,如何解决请求相同 url 时的缓存问题;
  3. 如果需要加 hash,那么加过 hash 之后生成的配置文件(map)由 jet 服务器还是开发者维护;
PengXing commented 6 years ago

静态资源加载分为下面几步:

  1. mip core 分析支出的 HTML 里所有的 mip 标签
  2. 请求 jet 的时候带上引用的每个 mip 标签名
  3. jet 根据 mip 标签拼合依赖的所有 JS 文件

但是,这样的步骤里有一个问题,传统的网站上,直出的 HTML 里引用 JS 的时候会带上版本号或者 hash,而 MIP HTML 并没有这个东西,那么,怎么保证每次获取到的 JS 都是最新版,如果开发者通过 mip2 publish 发布了一个对已有组件的更新呢。

MIP1 的解决方法大概是这样:

  1. 限制 MIP1 的 JS 的 max-age=600,也就是 10min
  2. MIP1 的组件每天固定两个上线时间点,没天更新两次 MIP 组件

MIP2 和 MIP1 不一样,MIP2 面向的是复杂站点,如电商,如果线上的 MIP2 的组件有 bug,往往是不能等的,需要立刻上线修复问题,否则影响会比较大,因此,我们需要一种方法能让站长能够在发布组件之后,立刻更新 JS 版本。

PengXing commented 6 years ago

我们可以提供两种机制

  1. 默认 10min 更新一次缓存
  2. 开放一个 mip-version 的标签或者变量,让开发者能够强制更新缓存
PengXing commented 6 years ago

MIP2.0 初期先不考虑这个问题,还是延用 MIP1.0 的静态资源管理方式

在页面里面插入多个 js 文件

<script src="//mipcdn.cn/some/path/mip-a.js"></script>
<script src="//mipcdn.cn/some/path/mip-b.js"></script>

这个 script 也可以不用站长来写,通过 js 扫描当前 HTML 中有哪些 MIP 标签动态插入

MIP2.0 后期才考虑优化 JS 的加载问题。

OVER.

tayqassqan commented 6 years ago

这个优化前期基于MIP Cache来做是不是好一点? 前端的动态合并要考虑的东西挺多的,我们可以再多讨论一下可行性。