vue-router 配合 webpack 进行路由懒加载
一、描述
vue & webpack 的开发模式如果网站内容特别多,会导致 SPA 打出来的包的大小非常的大,经常超过 1M,因此一般会使用 webpack 的 code spliting 把代码分割成不同的 chunk。
按需加载 vue 支持异步组件的方式,因此 vue-router 提供了路由懒加载,可以在路由切换之后再去请求相关路由组件的资源,从而在某种程度上减少 bundle 的大小。
开发的脚手架是之前自己用 webpack4.x 配置的,可以在 https://github.com/postbird/webpack4.x-vue-develop 直接 clone 项目,然后:
yarn install
yarn start
即可,不对 webpack 配置 vue 基本的开发环境做过多的阐述,不过目前的脚手架没有配置 router,需要自己配置。文章结束之后我会发一个本篇文章的 demo 到 github,可以直接运行
二、传统的 router 配置
直接上配置文件,通过 import
的方式引入组件,然后在 routes 中配置相关的路由信息,很基本的配置了:
import VueRouter from 'vue-router';
import Index from '../components/Index.vue';
import Hello from '../components/Hello.vue';
import List from '../components/List.vue';
const routes = [
{ path: '/', alias:'/index', component: Index },
{ path: '/hello', component: Hello },
{ path: '/list', component: List }
];
const router = new VueRouter({ routes });
export default router;
在模板中使用的时候也是如此,正常使用:
<ul>
<li><router-link to="/index">Index</router-link></li>
<li><router-link to="/hello">Hello</router-link></li>
<li><router-link to="/list">List</router-link></li>
</ul>
<router-view></router-view>
最终的结果:
进入首页,将 main.bundle.js 完整的请求下来
切换其他路由后不会进行新的资源请求
二、路由懒加载 router 配置及作用
路由懒加载其实依赖于 webpack 的 code-spliting 以及 vue 的异步组件,关于 vue 的异步组件可以看:
而异步组依赖动态 import,react 也有这个思想:https://reactjs.org/docs/code-splitting.html#import
vue-router 结合动态 import 及 异步组件的支持,通过将之前配置的 import Index from '../components/Index.vue';
这种直接 import 的方式改变成 const Index = () => import('../components/Index.vue');
这种能够被 webpack 识别并自动分割代码的组件。
因此 router 的配置变化如下:
import VueRouter from 'vue-router';
const Index = () => import('../components/Index.vue');
const Hello = () => import( '../components/Hello.vue');
const List = () => import( '../components/List.vue');
const routes = [
{ path: '/', alias:'/index', component: Index },
{ path: '/hello', component: Hello },
{ path: '/list', component: List }
];
const router = new VueRouter({ routes });
export default router;
除了 router 的配置会发生变化之外,如果使用了 babel,则 webpack 进行代码分割的时候需要依赖 babel 的一个插件 @babel/babel-plugin-syntax-dynamic-import
,文档地址:https://babeljs.io/docs/en/babel-plugin-syntax-dynamic-import/
因此需要更改 webpack 中 babel 的配置,因为我是直接写在了 webpack.dev.config.js
,所以还是直接更新 webpack.dev.config.js:(prod.config.js 没更改,因为只是 demo)
{
test: /\.(js)$/,
exclude: /(node_modules)/,
use:{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/transform-runtime', "@babel/plugin-syntax-dynamic-import"]
}
}
},
首次进入,可以发现除了加载了一个 bundle.js 之外,还加载了一个 2.bundle.js
:
当切换路由的时候,会发现每次切换的路由都多请求了一个 x.bundle.js
,而里面的内容则是路由组件的内容
四、问题
两次对比其实有一个很明显的问题可以发现,路由懒加载之前,main.bundle.js
的大小是 183kb
,而路由懒加载之后,main.bundle.js
还是 183kb
,根本没有减少。
第二个问题是,在 main.bundle.js
都相同的情况下,使用路由懒加载后,每次都会多请求 1.4kb
的 x.bundle.js
,这个特别尴尬。路由懒加载之后 bundle 不但没减少,反而多请求了好几 kb 的资源 好几个网络请求。
因为我的每个组件内容都很少,基本都是下面特别简单的内容:
<template>
<div>
<h1>Hello</h1>
</div>
</template>
所以分离出去懒加载后,对整体的 main.bundle.js
没有什么大的影响,大小未发生变化,每个 bundle 单独打包,webpack 又会注入自己的规范代码,导致多注入了很多代码(见上面截图)。
所以
五、demo 代码
请注意,文章的 demo 在 dev/router-lzay-loading
分支:
文章版权:Postbird-There I am , in the world more exciting!
本文链接:http://www.ptbird.cn/vue-router-lazy-loading-with-webpack.html
转载请注明文章原始出处 !