vue cli异步路由加载原理
webpack会解析路由文件的引入,就算你是一个setTimeout输出的路由配置文件,或者if else
判断的路由配置文件,他都会将你明文书写的路由vue文件打包。为什么?其原理未知,估计并不是解析代码,而且代码关键字的抓取。
如果你是一个api返回的路由配置,webpack的无法准确感知到路由文件的是否被引入,所以它的办法是全部都打包,src目录下的所有vue文件全部会被打包成chunk-2d0b30b7.3576daad.js
这种格式的文件。
其中包裹components目录下的组件,哪怕你的这个组件已经被某个路由页明确引入了,这个路由除了会被打包到这个路由页,还会生成单独的chunk-xx.xx.js
文件
为了解决这个问题,应该是用到了@vue/cli-plugin-babel/preset
这个vue cli的依赖去解析路由配置component
中的import()
方法。
如果我们这么写:
component: () => import(`@/views/${component}`)
@/views
会被明确的解析到,那么只有这个目录下的文件是不可预见的,那么,这个目录下所有文件都会被打包成chunk-xx.xx.js
文件
如果这么写:
component: () => import(`@/${component}`)
@/
成了明确的路径,该路径又等于/src
,所以会出现上述问题,vue文件全部被打包了。
而且vue cli会将所有的文件做成预加载资源设置到index.html文件的head下,格式如下:
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="/favicon.ico">
<title>hello-world</title>
<link href="/js/chunk-2d0ab09a.9f23883a.js" rel="prefetch">
<link href="/js/chunk-2d0c4244.d539bdf1.js" rel="prefetch">
<link href="/js/chunk-2d0cfa15.60c1fbaf.js" rel="prefetch">
<link href="/js/chunk-2d0d6f02.a0069259.js" rel="prefetch">
<link href="/js/chunk-2d0e4e98.ea1b3b36.js" rel="prefetch">
<link href="/js/chunk-2d0e6875.605d60f3.js" rel="prefetch">
<link href="/js/chunk-680d03d6.dcb41723.js" rel="prefetch">
<link href="/js/app.48e2bbc6.js" rel="preload" as="script">
<link href="/js/chunk-vendors.d3ebd8e9.js" rel="preload" as="script">
</head>
为了解决这个问题,我们可以关闭这个功能
vue.config.js
module.exports = {
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
}
}
这样就可以解决这个问题。
那么webpack怎么知道这个路由加载这个js文件呢?
推测:
webpack会根据当前文件的路径生成hash值,且会有一个路径与哈希的查询表,而路由里面的import()
方法会被特殊处理,拿到路径之后,会去查询查询表,得到一个hash值,然后通过固定的打包文件名格式,拼接成正确的src地址,然后通过创建script元素的方式,下载这个js文件。
var map = {
"./Home": [
"bb51",
"Home"
],
"./Home.vue": [
"bb51",
"Home"
]
};
bb51就是hash值,后面的home取决于用户的配置,默认chunk-xx.xx.js
格式的文件,用户可以通过webpack魔术语法改变js的文件名:
import(/* webpackChunkName: "[request]" */`@/views/${component}`);
/* webpackChunkName: "[request]" */
中[request]
为webpack预设的一个关键词,表示引入的文件名,所以这里的chunk
就变成了Home
。
除了这个名字还有hash值,这个hash是用于防止js文件缓存用的,hash也是可以用户配置的,一般只有生产模式打包才有。
最终所有的参数都会在打包生成的app.js
中以这种形式出现:
function jsonpScriptSrc(chunkId) {
return __webpack_require__.p + "js/" + ({
"Home": "Home"
}[chunkId] || chunkId) + "." + {
"Home": "f2ac4836"
}[chunkId] + ".js"
}
这个函数就是拼接文件src的方法,最终通过script元素引入。
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据