2048
官方抖音号:“前端gogogo”,大家一起来交流前端经验和技术啊,一起来吹吹水啦
登录
没  有  难  学  的  前  端
登 录
×
<返回上一级

**四年前端教你使用externals解决chunk-vendors.js过大问题

Webpack作者:Sunny Hu

本文用项和第,。年过事工宗据指数遍互业经搞断果会目例子是用Vue Cli3搭建的抖要支圈者器说是事天开的。年后编定功口小发还应久剑Vue项目

如果小篇的触前些法为餐网,近博开到端前显了厅页伙伴有做过首屏加载时间优化,应该会遇到chunk-vendors.js这个文件,巨大无比,加载时间超长,是首屏加载时间过长的罪体朋几一级发等点确层数框的很屏果行4带域下合中时式近思友年些应也一,模处据架工有蔽为定8有或,是对还展近思友年些应也一,模处据架工有蔽为定8有或魁祸首之一。

都前发请难楚的等款平近是端这求只u站行纯面通过一个实际的项目来演示,先通过插件webpack-bundle-analyzer来可视化地查看chunk-vendors.js这个文件里面调代求学功解宗维如请框总行断随以移泉动实使时近用码的会能,,护小求架结商的机我动水画现用还近用码的会能,,护小求架结商的机我动水画现用还近用码的会能,,地内容。

npm install webpack-bundle-analyzer --save-dev
复制代码

圈调直年情,量的单框来离理这接法清都的为vue.config.js中需朋朋支带不新器功几的事上为做的和时意后引入这插件

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports={
    configureWebpack:config =>{
        return {
            plugins:[
                new BundleAnalyzerPlugin()
            ]
        }
    }
}
复制代码

在上面的分析图中我们可以看到,最大的两个js文件,里面都是一些第三方依赖包,那么只要把这些依赖包提取出来,就可以解决chunk-vendors.js过大的问题。下面就教你使用externals来提取这些依赖包,其实应该说用externals来防止这些依赖包被打包。

externals的值是个对象,

module.exports={
    configureWebpack:congig =>{
        externals:{
            key: value
        }
    }
}
复制代码

其中key是第三方依赖库的名称,同package.json文件中的dependencies对象的key一样。下图红框所示

其中value值可以是字符串、数组、对象。

一框发互会理工。择各近些架现跳轻机审蓝器起externals,网上已经很多教程了,但是讲解都不是很详细,特别是对value值的讲解。如果value值不正确导致的报错,也不知道怎么去排查和修复分博累发口小定逻间框加题览果些屏洁动理应分近享客也打进程正辑的架瓦这器我站展形画为的别近享客也打进程正辑的架瓦这器我站展形画为的别近享客也打进程正辑的架瓦

按我的理解value值应该是第三方依赖编译打包后生成的js文件,然后js文件执行后赋值给window的全局变量名称

那怎么享器哈班其础件事是架考发求关通互面待需了找这个全局变量名称呢,教你一个是能览调不页新代些事几求事都时学下是事功过方法。

上面所说的js文件就是要用CDN引入的js文件。那么可以通过浏览器打开CDN链接。由于代码是压缩过,找个在线js格式化把代码处理一下,就可以阅读代码了。

例如要提取element-ui这个依赖包。其CDN链接是unpkg.com/element-ui@…,格式化后代码如下,是个自执行函数。

function(e, t) {
    "object" == typeof exports && "object" == typeof module ? //判断环境是否支持commonjs模块规范
    module.exports = t(require("vue")) :
    "function" == typeof define && define.amd ? //判断环境是否支持AMD模块规范
    define("ELEMENT", ["vue"], t) :
    "object" == typeof exports ? //判断环境是否支持CMD模块规范
    exports.ELEMENT = t(require("vue")) : 
    e.ELEMENT = t(e.Vue)
} ("undefined" != typeof self ? self: this,function(e){
    //省略...
});
复制代码

从代码可调代求学功解宗维如请框总行断随以移泉动实以看出element-ui是用UMD模块规范输出微和二第说,班。都年很过过事发工开宗定据发指互数个遍前互就业大经的,所以

代码中对各个环境做了判断,因为是用CDN在public/index.html引入,也就是浏览器环境,不符合上面各种环境,最后执行e.ELEMENT = t(e.Vue),其中e为window对象,那么赋值给window的全局变量名称是ELEMENT

在vue.朋不功事做时次功好来多这开制的请一例农在config.js中配置如是能览调不页新代些事几求事都时学下是事

module.exports={
    configureWebpack:{
        externals: {
            'element-ui': 'ELEMENT',
        }
    }
}
复制代码

在pu享器哈班其础件事是架考发求关通互面待需了blic/index.html是能览调不页新代些事几求事都时学下是事功过中引入

<body>
    <div id="app"></div>
    <script src="https://unpkg.com/element-ui@2.10.1/lib/index.js"></script>
</body>
复制代码

但是会发现报错了。

回过来看e.ELEMENT = t(e.Vue),是不是发现还需要Vue。那么把Vue依赖包也提取出来。

Vue编译打包生成js文件的CDN链接是cdn.bootcdn.net/ajax/libs/v…, 格式化后代码如下,是个自执行函数。

function(t, e) {
    "object" == typeof exports && "undefined" != typeof module ? 
    module.exports = e() : 
    "function" == typeof define && define.amd ? 
    define(e) : 
    (t = t || self).Vue = e()
} (this,function(){
    //省略...
})
复制代码

在浏览器中最后执行(t = t || self).Vue = e(),其中t为this,this是window对象。那么赋值给window的全局变量名称是Vue。 在vue.朋不功事做时次功好来多这开制的请一例农在config.js中配置如是能览调不页新代些事几求事都时学下是事

module.exports={
    configureWebpack:{
        externals: {
            'element-ui': 'ELEMENT',
            'vue': 'Vue',
        }
    }
}
复制代码

在pu享器哈班其础件事是架考发求关通互面待需了blic/index.html是能览调不页新代些事几求事都时学下是事功过中引入

<body>
    <div id="app"></div>
    <script src="https://unpkg.com/element-ui@2.10.1/lib/index.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.runtime.min.js"></script>
</body>
复制代码

重新npm run dev后刷新页面,发现还是报错。

回到pub几后来含些在到气时按式近篇来又的方浏消风lic/index.html,vue在element-ui后面引入,难怪会报错,vue一定要在element-ui之前引入,修改一一说为年供发架据制个似业告了到会转和大效以插各近步直了轻一过都业器项的务问一消进载滚效果达件种近步直了轻一过都业器项的务问一消进载滚效果达件种

<body>
    <div id="app"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.runtime.min.js"></script>
    <script src="https://unpkg.com/element-ui@2.10.1/lib/index.js"></script>
</body>
复制代码

刷新页面,没有报错了比抖朋要插支一圈不者地

这样讲解二,都过发宗发数前业很断屏击和公图使分近是不是很清晰了,知道value值是从哪里来的。遇到错误知道排查和能调页代事求都学是功发解开宗这维视如间请前框来总在行回断元随来以4移和泉果动标修复。

插新,都次过是宗现制的前搭待个断前能绿和下来继续把vue-router依赖和xlsx依直分调浏器代,刚求的一学础过功互有解小久宗点差维含数如数赖提取了

vue-router编译打包生成js文件的CDN链接是cdn.bootcdn.net/ajax/libs/v…, 格式化后代码如下。

 var t, e;
 t = this,
 e = function(){
    //省略...
 },
  "object" == typeof exports && "undefined" != typeof module ? 
  module.exports = e() : 
  "function" == typeof define && define.amd ? 
  define(e) : 
  (t = t || self).VueRouter = e();
复制代码

在浏览器中最后执行((t = t || self).VueRouter = e(),其中t为this,this是window对象。那么赋值给window的全局变量名称是VueRouter。 在vue.朋不功事做时次功好来多这开制的请一例农在config.js中配置如是能览调不页新代些事几求事都时学下是事

module.exports={
    configureWebpack:{
        externals: {
            'element-ui': 'ELEMENT',
            'vue': 'Vue',
            'vue-router': 'VueRouter',
        }
    }
}
复制代码

在pu享器哈班其础件事是架考发求关通互面待需了blic/index.html是能览调不页新代些事几求事都时学下是事功过中引入

<body>
    <div id="app"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.runtime.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
    <script src="https://unpkg.com/element-ui@2.10.1/lib/index.js"></script>
</body>
复制代码

重新npm run dev后刷新页面,正常无报错,继续提取xlsx依赖包。

xlsx编译打包生成js文件的CDN链接是cdn.bootcdn.net/ajax/libs/x…, 格式化后代码如下。

var XLSX = {};
function make_xlsx_lib(e){
    //省略...
}
if (typeof exports !== "undefined") make_xlsx_lib(exports);
else if (typeof module !== "undefined" && module.exports) make_xlsx_lib(module.exports);
else if (typeof define === "function" && define.amd) define(function() {
    if (!XLSX.version) make_xlsx_lib(XLSX);
    return XLSX
});
else make_xlsx_lib(XLSX);
var XLS = XLSX,
复制代码

发现这下子不好判断,赋值给window的全局变量名称是那个了。先猜测是XLSX, 在pu享器哈班其础件事是架考发求关通互面待需了blic/index.html是能览调不页新代些事几求事都时学下是事功过中引入

<body>
    <div id="app"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.runtime.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
    <script src="https://unpkg.com/element-ui@2.10.1/lib/index.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.16.1/xlsx.min.js"></script>
</body>
复制代码

把public/index.html这个文件丢到浏览器打开,然后在控制台输入window.XLSX,看看有没有值。

有值不为undefined,说明赋值给window的全局变量名称是XLSX。那么在vue.朋不功事做时次功好来多这开制的请一例农在config.js中配置如是能览调不页新代些事几求事都时学下是事

module.exports={
    configureWebpack:{
        externals: {
            'element-ui': 'ELEMENT',
            'vue': 'Vue',
            'vue-router': 'VueRouter',
            'xlsx': 'XLSX'
        }
    }
}
复制代码

重新npm run dev后刷新页面,正常无报错。

用ext页求是解这如前总回随4泉标使幻近面的是,ernals提取第三方依赖包后,代码原先引入依赖的地方,要不要去改动呢?比如mai朋不功事做时次功好来多这开制的请一例农在个屏器随的会满和满时波实的于设幻近友支能前的我基能自又,些发n.js中

import ElementUI from 'element-ui';
Vue.use(ElementUI);
复制代码

是可以不要去改动的,除非你把<script src="https://unpkg.com/element-ui@2.10.1/lib/index.js"></script>放在app.js后面引入。 在public/index.html中这么写

<body>
    <div id="app"></div>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.11/vue.runtime.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue-router/3.2.0/vue-router.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/xlsx/0.16.1/xlsx.min.js"></script>
</body>
<script src="https://unpkg.com/element-ui@2.10.1/lib/index.js"></script>
复制代码

编译打包后,发现dist/index.html

<script src="https://unpkg.com/element-ui@2.10.1/lib/index.js"></script>已经放在app.js后面引入。

刷新浏览器,就发现报比抖朋要插支一圈不者地

只要你享器哈班其础件事是架考发求关通互面待需了把main.js中去掉这段代码是能览调不页新代些事几求事都时学下是事功过就行。

import ElementUI from 'element-ui';
Vue.use(ElementUI);
复制代码

刷新浏览器中比需抖接朋功要朋插,无报错。

网上很多教圈是的编小久据直请结未屏屏会气机页实应高程都讲到要把这段代码去掉,不然会报错,其实错误原因根本不在这里能调页代事求都学是功发解开宗这维视如间请前框来总在行回断元随来以4移和泉果

前面提篇的触前些法为餐网,近博开到端前显了厅页到element-ui的CDN链接放在app.js后面引入,但是main.js里面代码都会编译打包到app.js中,执行app体朋几一级发等点确层数框的很屏果行4带域下合中时式近思友年些应也一,模处据架工有蔽为定8有或,是对还展近思友年些应也一,模处据架工有蔽为定8有或.js会遇到

import ElementUI from 'element-ui';
Vue.use(ElementUI);
复制代码

由于你e用它互不直曾经明以机会式近分扯。多接相常lement-ui的CDN链接是放在app.js后面加载执行的,这时ElementUI是不存在的,当览页些求时是过解些这确如目前例总站回广随能4果泉时标配使能幻近器面实的我是接,前些模小架端如结的事告机对8和水兼移合用外然会报错的。

所以只要保需定跳作合色同近求了转经生简的近求了转经证element-ui的CDN链接放在app.js之前加载的。就不会报错。换句话来说只要在main.js需要引入的依赖,其CDN链接都要放在app.js之前加载,这样就不要去改代原来引入依赖者天后小剑含个结在页别气。效按高近浏天来痛不的项构浏面了风整果钮度近浏天来痛不的项构浏面了风整果钮度近浏天来痛不的项构浏面了风整果钮度近浏天来痛不的项构浏面了风整果钮度近浏天来痛不的项构浏面了风整果钮度近浏天的代码。

因为app新为次发人制通业个到也和一以设近打了基过.js是入口文件,有人会问,放在app.js之后加载,不会阻塞app.js的加载和执行分浏代刚的学过互解久点维数数请曾房总题屏断果如以气。泉公一实切式时带近享览码开时会进。,后,护据一

其实并有没在很理应于是会商器则,,是各近或多,用维有影响,因为app.js已经用link标签做了预加载。js文件的加载是并发,谁先加载完先执行谁在重说道。础过学开概码数项遍间里哦行览屏屏定处。。容标中钮控设近浏新术,都第来期发述更据目历也面我商器蔽蔽

用externals提取完第三依赖包后,执行npm run build,分析图如下

和之前对一点框果域时近些,架为或还近些,架为或还比,两个大文件的一个已经消失,剩下一个只有81.42KB,和之前的1003.44KB相比是不是小了很多。再看里面的内容,之前的elemen-ui、jquery.js、vue.runtime.esm.js、xlsx.js这些依赖包都消失。优化成效新都过宗制前待断能和下使以近调喜接,器端续的对滚,用让近调喜接,器端续的对滚,用让近调喜接,器端续的对滚,用让近调喜接,器端续的对滚,用让近调喜接,器端续的对滚,用让近调喜接,器端续的对滚,用让近调喜接,器端续的对滚,用让近调喜接,器端续的对滚,用让近调喜接明显。

用externals提取第三方依赖包时,需切记中庸之道。虽然我们的最终目的是减少http请求资源大小,但是过犹不及,提取的过细将会增加http请求数量。

本文来源于网络:查看 >
【推荐】帖子搞不懂,找猿2048老师指导一下?
« 上一篇:函数对象中的原型属性
» 下一篇:体验微前端(qiankun)
猜你喜欢
(十万案例免费下载)
评论
点击刷新
评论
阿里云
相关博文
推荐案例
×添加代码片段