# 现代模式打包
# 介绍
打包应用的过程中通常会使用babel对代码进行转译,使得一些js的新特性也能在低版本浏览器中正常运行,但是如果一些用户使用的浏览器版本很高,足以支持这些特性,那么下载的js文件如果也被转译了就会带来浪费,而现代模式打包应用就是解决这个问题的,对支持新特性的用户分发es6代码,对不支持分发转移后的代码。
# 原理
<script type="module" src="..."></script>
当script标签碰到type="module"
时,就会将对应文件作为一个module运行,如果浏览器不支持type="module"
就会忽略这个脚本的执行,此时就需要用到nomodule
来进行降级处理:
<script nomodule src="..."></script>
在浏览器不识别type="module"
的时候,执行nomodule中的代码。
# 使用
Vue CLI中直接提供了现代模式构建的方法:
vue-cli-service build --modern
从打包过程和打包结果可以看出,其实就是执行了两次webpack打包过程,以此用了babel进行转移,称为legacy build,一次没有进行转移,称为modern build。
# 实现方法
每一次打包,都会将打包的资源通过htmlWebpackPlugin内联进html模板中,两次打包后就会有两者的资源,legacy build时内联的标签会有nomodule=""
的属性,在modern build时,就会将该属性替换成nomodule
,然后modern build的标签会添加type="module"
属性。其还针对Safari 10.1不识别nomodule导致执行两套资源的bug进行了fix。详细可见:node_modules/@vue/cli-service/lib/webpack/ModernModePlugin.js
。
# 最后
**注意:现代模式分发的代码受跨域限制,例如你的html中引用了第三方资源,并且script有type="module"的属性,第三方服务器头部需要设置Access-Controll-Allow-Origin: ***