作为前端开发人员,在开发的时候,生产环境中会把js,css,图片等压缩,尽量减少文件的大小,从而提升响应速度,尤其是移动端。
在我们使用vue-cli3打包项目的时候,我们的js/css文件都是会根据依赖关系自动打包压缩的,但是项目比较大的时候,引入的外部库很多,往往打出来的包vender.js会很大,导致首屏加载很慢。
这时候用webpack提供的externals属性,像vue.js 、vuex.js 、vue-router.js 等这些外部库,基本不会变的,如果将它们独立出来单独加载就能利于浏览器的缓存机制,不用每次都重新加载这些库js,并且大大的减少了打包的vendor.js文件。
这时候用webpack提供的externals属性,像vue.js 、vuex.js 、vue-router.js 等这些外部库,基本不会变的,如果将它们独立出来单独加载就能利于浏览器的缓存机制,不用每次都重新加载这些库js,并且大大的减少了打包的vendor.js文件。
下面我们以vue-cli3项目为例进行说明:
首先我们看看我们的main.js文件示例:
import 'Vue' from 'vue'
import 'VueRouter' from 'vue-router'
import * as BABYLON from 'babylonjs'
然后我们新建vue.config.js文件
module.exports = {
// ...
externals: {
// 我们挂载在全局的变量名称:引入的模块名称
'vue': 'Vue',
'vue-router': 'VueRouter',
'babylonjs': 'BABYLON',
}
这样配置之后,我们在main.js中引入的相关模块就不会打包至js文件中,而是会去找html中找我们使用script引入的文件,所以接下来,我们要在html中引入文件。
<script src="https://cdn.jsdelivr.net/npm/[email protected]">script>
<script src="https://unpkg.com/[email protected]/dist/vue-router.js">script>
<script src="https://cdn.babylonjs.com/babylon.js">script>
注意:引入cdn的时候最好使用官方的,不然挂了就…
我们来查看一下效果:
优化前:
优化后:
由此可见,第三方包被我们抽离出来之后,chunk和vendor体积大大减小了。
之所以区分两个环境主要原因是,当我们在开发环境的时候,使用cdn引入js文件会比我们直接模块引入要慢,不是很方便。所以我们想要配置,只在生产环境下才使用externals。
那么,配置的思路就是对当前环境进行判定,如果是生产环境,我们就使用externals;如果是开发环境,就不使用。
vue.config.js代码修改为:
module.exports = {
// ...
configureWebpack: config => {
const plugins = [];
// 利用环境变量进行判断是否是生产环境production
if (process.env.NODE_ENV === 'production') {
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'babylonjs': 'BABYLON'
}
}
// 然后将新增externals选项合并至plugins配置中
config.plugins = [
...config.plugins,
...plugins
]
},
chainWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 生产环境下注入一个变量cdn 变量可以在html中通过htmlWebpackPlugin.options进行获取
config.plugin('html')
.tap(args => {
args[0].cdn = 'prod';
return args;
})
}
}
}
既然要在区分两个环境,自然在html中也要进行区分,这个时候就要用到我们在vue.config.js中注入的cdn变量来进行判断了。
html修改为:
<% if(htmlWebpackPlugin.options.cdn == 'prod'){ %>
<script src="https://cdn.jsdelivr.net/npm/[email protected]">script>
<script src="https://unpkg.com/[email protected]/dist/vue-router.js">script>
<script src="https://cdn.babylonjs.com/babylon.js">script>
<% } %>
运行项目,当在开发的时候没有引用cdn, 生产环境下使用了cdn,这就算是完成配置啦~
你以为这就结束了吗?哈哈哈没有,我们还可以继续优化配置一下。
// vue.config.js
const isProduction = process.env.NODE_ENV === 'production';
const cdn = {
css: [],
js: [
'https://cdn.jsdelivr.net/npm/[email protected]',
'https://unpkg.com/[email protected]/dist/vue-router.js',
'https://cdn.babylonjs.com/babylon.js'
]
}
module.exports = {
configureWebpack: config => {
if (isProduction) {
// 用cdn方式引入,分离第三方插件
config.externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'babylonjs': 'BABYLON'
}
}
},
chainWebpack: config => {
if (isProduction) {
config.plugin('html')
.tap(args => {
args[0].cdn = cdn;
return args;
})
}
}
}
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>static/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="<%= BASE_URL %>static/favicon.ico" type="image/x-icon" />
<title>my-projecttitle>
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style">
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet">
<% } %>
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script">
<% } %>
head>
<body>
<noscript>
<strong>We're sorry but eye-admin doesn't work properly without JavaScript enabled. Please enable it to continue.strong>
noscript>
<div id="app">div>
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>">script>
<% } %>
body>
html>
不过使用externals属性要注意的是,虽然可以优化首屏加载速度,但是由于静态资源分离,也会增加http请求数量。所以如果是小项目,最好就不要用externals属性,因为小项目打包的出来的vender.js体积不大,建议项目体量较大的项目再用比较合适。
真是要加油学习呢~
[1]: vue-cli3项目打包优化配置要点
[2]: [email protected]使用及配置说明
[3]: webpack使用HtmlWebpackPlugin进行cdn配置