webpack4中的optimization.runtimeChunk是用来分离运行时的代码,我们看下面的例子来了解它的具体作用:

分离不含import()的

先看一个不包含import()的vue项目:

/*---App.vue---*/
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>
/*---About.vue---*/
<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>
/*---router.js---*/
mport About from '../views/About.vue'
Vue.use(VueRouter)
const routes = [
  {
    path: '/about',
    name: 'about',
    component:About
  }
]

打包,得到如下结果:

然后我们配置vue.config.js:

configureWebpack: {
	optimization: {
		runtimeChunk:{
			name:()=>'aaa'
		},
	},
}

再一次打包:

我们可以发现多了个aaa.***.js,它就是runtimeChunk配置的,是从app.***.js中分离出来的webpack相关代码,我们看看aaa.***.js内容:

(function(e) {
	function r(r) {
		for(var n, l, a = r[0], i = r[1], f = r[2], c = 0, s = []; c < a.length; c++) l = a[c], Object.prototype.hasOwnProperty.call(o, l) && o[l] && s.push(o[l][0]), o[l] = 0;
		for(n in i) Object.prototype.hasOwnProperty.call(i, n) && (e[n] = i[n]);
		p && p(r);
		while(s.length) s.shift()();
		return u.push.apply(u, f || []), t()
	}

	function t() {
		for(var e, r = 0; r < u.length; r++) {
			for(var t = u[r], n = !0, a = 1; a < t.length; a++) {
				var i = t[a];
				0 !== o[i] && (n = !1)
			}
			n && (u.splice(r--, 1), e = l(l.s = t[0]))
		}
		return e
	}
	var n = {},
		o = {
			aaa: 0
		},
		u = [];

	function l(r) {
		if(n[r]) return n[r].exports;
		var t = n[r] = {
			i: r,
			l: !1,
			exports: {}
		};
		return e[r].call(t.exports, t, t.exports, l), t.l = !0, t.exports
	}
	l.m = e, l.c = n, l.d = function(e, r, t) {
		l.o(e, r) || Object.defineProperty(e, r, {
			enumerable: !0,
			get: t
		})
	}, l.r = function(e) {
		"undefined" !== typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
			value: "Module"
		}), Object.defineProperty(e, "__esModule", {
			value: !0
		})
	}, l.t = function(e, r) {
		if(1 & r && (e = l(e)), 8 & r) return e;
		if(4 & r && "object" === typeof e && e && e.__esModule) return e;
		var t = Object.create(null);
		if(l.r(t), Object.defineProperty(t, "default", {
				enumerable: !0,
				value: e
			}), 2 & r && "string" != typeof e)
			for(var n in e) l.d(t, n, function(r) {
				return e[r]
			}.bind(null, n));
		return t
	}, l.n = function(e) {
		var r = e && e.__esModule ? function() {
			return e["default"]
		} : function() {
			return e
		};
		return l.d(r, "a", r), r
	}, l.o = function(e, r) {
		return Object.prototype.hasOwnProperty.call(e, r)
	}, l.p = "/";
	var a = window["webpackJsonp"] = window["webpackJsonp"] || [],
		i = a.push.bind(a);
	a.push = r, a = a.slice();
	for(var f = 0; f < a.length; f++) r(a[f]);
	var p = i;
	t()
})([]);

分离包含import()的

我们将上面的About页面改成import引用的:

/*---App.vue---*/
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>
/*---About.vue---*/
<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>
/*---router.js---*/
Vue.use(VueRouter)
const routes = [
  {
    path: '/about',
    name: 'about',
    component: () => import('../views/About.vue')
  }
]

打包,得到一下结果:

因为About是通过import()引用的,因此打包的时候从app.***.js中分离出去了,app.***.js中含有About的打包信息:

function u(e) {
	return i.p + "js/" + ({
		about: "about"
	}[e] || e) + "." + {
		about: "ab48dbb2"
	}[e] + ".js"
}

如果About页面发生变化,about.***.js会变化,同时app.***.js也会变化,因为app.***.js中有一段About打包信息的代码。现在配置vue.config.js::

configureWebpack: {
	optimization: {
		runtimeChunk:{
			name:()=>'aaa'
		},
	},
}

重新打包,结果如下:

同样分离出了aaa.***.js,它除了包含webpack相关代码,还分离出了About打包相关信息:

(function(e) {
	function r(r) {
		for(var n, a, i = r[0], c = r[1], l = r[2], f = 0, s = []; f < i.length; f++) a = i[f], Object.prototype.hasOwnProperty.call(o, a) && o[a] && s.push(o[a][0]), o[a] = 0;
		for(n in c) Object.prototype.hasOwnProperty.call(c, n) && (e[n] = c[n]);
		p && p(r);
		while(s.length) s.shift()();
		return u.push.apply(u, l || []), t()
	}

	function t() {
		for(var e, r = 0; r < u.length; r++) {
			for(var t = u[r], n = !0, a = 1; a < t.length; a++) {
				var c = t[a];
				0 !== o[c] && (n = !1)
			}
			n && (u.splice(r--, 1), e = i(i.s = t[0]))
		}
		return e
	}
	var n = {},
		o = {
			aaa: 0
		},
		u = [];

	function a(e) {
		return i.p + "js/" + ({
			about: "about"
		}[e] || e) + "." + {
			about: "2028de0a"
		}[e] + ".js"
	}

	function i(r) {
		if(n[r]) return n[r].exports;
		var t = n[r] = {
			i: r,
			l: !1,
			exports: {}
		};
		return e[r].call(t.exports, t, t.exports, i), t.l = !0, t.exports
	}
	i.e = function(e) {
		var r = [],
			t = o[e];
		if(0 !== t)
			if(t) r.push(t[2]);
			else {
				var n = new Promise((function(r, n) {
					t = o[e] = [r, n]
				}));
				r.push(t[2] = n);
				var u, c = document.createElement("script");
				c.charset = "utf-8", c.timeout = 120, i.nc && c.setAttribute("nonce", i.nc), c.src = a(e);
				var l = new Error;
				u = function(r) {
					c.onerror = c.onload = null, clearTimeout(f);
					var t = o[e];
					if(0 !== t) {
						if(t) {
							var n = r && ("load" === r.type ? "missing" : r.type),
								u = r && r.target && r.target.src;
							l.message = "Loading chunk " + e + " failed.\n(" + n + ": " + u + ")", l.name = "ChunkLoadError", l.type = n, l.request = u, t[1](l)
						}
						o[e] = void 0
					}
				};
				var f = setTimeout((function() {
					u({
						type: "timeout",
						target: c
					})
				}), 12e4);
				c.onerror = c.onload = u, document.head.appendChild(c)
			}
		return Promise.all(r)
	}, i.m = e, i.c = n, i.d = function(e, r, t) {
		i.o(e, r) || Object.defineProperty(e, r, {
			enumerable: !0,
			get: t
		})
	}, i.r = function(e) {
		"undefined" !== typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
			value: "Module"
		}), Object.defineProperty(e, "__esModule", {
			value: !0
		})
	}, i.t = function(e, r) {
		if(1 & r && (e = i(e)), 8 & r) return e;
		if(4 & r && "object" === typeof e && e && e.__esModule) return e;
		var t = Object.create(null);
		if(i.r(t), Object.defineProperty(t, "default", {
				enumerable: !0,
				value: e
			}), 2 & r && "string" != typeof e)
			for(var n in e) i.d(t, n, function(r) {
				return e[r]
			}.bind(null, n));
		return t
	}, i.n = function(e) {
		var r = e && e.__esModule ? function() {
			return e["default"]
		} : function() {
			return e
		};
		return i.d(r, "a", r), r
	}, i.o = function(e, r) {
		return Object.prototype.hasOwnProperty.call(e, r)
	}, i.p = "/", i.oe = function(e) {
		throw console.error(e), e
	};
	var c = window["webpackJsonp"] = window["webpackJsonp"] || [],
		l = c.push.bind(c);
	c.push = r, c = c.slice();
	for(var f = 0; f < c.length; f++) r(c[f]);
	var p = l;
	t()
})([]);

这样如果About页面发生变化,只有about.***.js和aaa.***.js发生变化,app.***.js不会发生变化。

回到顶部
我要评论

所有评论

返回
邮箱:
绑定
取消
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

邮箱:
绑定邮箱后,若有回复,会邮件通知。
提交
还可以输入500个字