木灵鱼儿

木灵鱼儿

阅读:334

最后更新:2022/03/23/ 15:04:16

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元素引入。

版权申明

本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。

关于作者

站点职位 博主
获得点赞 0
文章被阅读 334

相关文章