The way of Webpack learning (III.) -- codeSplitting & lazyLoding(代码分割和路由懒加载)
代码分割:对于一个大型的web项目来说,如果为了减少http请求,只打包出一个bundle.js文件,那么只要我们的需求修改了一点点,整个bundle.js都需要重新加载,得不偿失。所以我们不妨把代码分割成一块一块的,按需加载,而且还能利用浏览器缓存机制,如果文件没有修改,直接从缓存读取。也就是说,代码分割就是把代码切成很多块(chunk)。
懒加载:按需加载,页面需要什么文件我才去加载什么文件。我现在只知道应用在路由懒加载中,就是根据路由,按需加载不同的文件。
在上一章节提到使用CommonchunkPulgin只适合于多页面提取公共代码,不同于多页面应用的提取公共代码,单页面的代码分割和懒加载不是通过webpack
配置来实现的,而是通过webpack
的写法和内置函数实现的。
目前webpack
针对此项功能提供 2 种函数:1)import()
: 引入并且自动执行相关 js 代码。2)require.ensure()
: 引入但需要手动执行相关 js 代码。
一:webpack.config.js的配置
const webpack = require("webpack"); const path = require("path"); module.exports = { mode:'development', entry: { pageA: "./src/pageA.js" }, output: { path: path.resolve(__dirname, "dist"),
publicPath:'./dist/',//声明打包的chunk的相对路径 filename: "[name].bundle.js", chunkFilename: "[name].chunk.js"//代码分割出去的chunk的名字 }, };
二:使用require.ensure()进行代码分割
require.include("./moduleA.js"); // 将subPageA和subPageB共用的module.js打包在此pageA中 require.ensure(["./subA.js", "./subB.js"], // js文件或者模块名称,这里代表subA和subB一起打包,但不执行这两个包。 function() { var subPageA = require("./subA"); // 引入后需要手动执行,控制台才会打印 var subPageB = require("./subB"); }, "subPage" // 分割之后的chunk名字 ); require.ensure(["lodash"],function() {//第三方库也分割为一个文件 var _ = require("lodash"); _.join(["1", "2"]); },'vendor'); export default "page";
三:使用import()进行代码分割
// 将subPageA和subPageB共用的module.js打包在此pageA中 //如果没有定义这句话,moduleA.js将同时打包到A.chunk.js和B.chunk.js里面,就是重复打包了。 require.include("./moduleA.js"); import(/* webpackChunkName: 'A'*/ "./subA").then(function(subA) {//subA为文件subA.js的module console.log(subA); }); //如果想要把subA和subB都打包到一个chunk里面。只需要命名同样的webpackChunkName即可。 // import(/* webpackChunkName: 'A'*/ "./subB").then(function(subB) { // console.log(subB); // }); import(/* webpackChunkName: 'B'*/ "./subB").then(function(subB) { console.log(subB); }); import(/* webpackChunkName: 'lodash'*/ "lodash").then(function(_) { console.log(_.join(["1", "2"])); }); export default "page";
四:路由懒加载
一般没有用来路由懒加载是这样的:
import Vue from 'vue' import Router from 'vue-router' import Home from './views/Home.vue' import About from './views/About.vue' Vue.use(Router) export default new Router({ routes: [
{ path: '/home', name: 'home', component: Home }, { path: '/about', name: 'about', component: About } ]
使用路由懒加载之后,代码需要这样配置:
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) function loadView(view) { return () => import(/* webpackChunkName: "view-[request]" */ `@/views/${view}.vue`) } export default new Router({ routes: [ { path: '/home', name: 'home', component: loadView('Home') }, { path: '/about', name: 'about', component: loadView('About') } ] })
除了上面用到的import()引入组件,我们还可以使用webpack特有的require.ensure()
const Baz = r => require.ensure([], ()=>r(require('./Baz.vue')), '/baz')
将其他的文件配置完成后,我们就可以在浏览器中看到懒加载的效果了,即只有当路由匹配成功时,才会加载相应的组件,而且加载一次后会将它缓存,下次再访问这个路由,不会重新加载。
路由懒加载这里参考这编文章,很快就理解了:https://www.javascriptcn.com/read-37423.html