前言

使用vue-cli创建项目,使用webpack打包。其中,有一个webpack优化webpack.optimize.CommonsChunkPlugin,它会将node_modules中的必需模块提取到vendor文件中,项目开发中,增加第三方模块,比如element-uivue-echarts等,vendor的包都会增大。这个时候,就需要考虑减轻vendor包的大小,增加构建速度。我们可以使用webpack的外部扩展(externals)功能。

externals定义

externals配置选项,将指定的内容排除在构建的vendor中,但是,指定的内容需要出现在用户环境中。

以上是我的理解。

官方解释是:

The externals configuration option provides a way of excluding dependencies from the output bundles. Instead, the created bundle relies on that dependency to be present in the consumer's environment.

externals配置选项提供了「从输出的 bundle 中排除依赖」的方法。相反,所创建的 bundle 依赖于那些存在于用户环境(consumer's environment)中的依赖。

用法

防止将某些 import的包打包到bundle中,而是在运行时(runtime)再去外部获取这些扩展依赖(external dependencies)

可以通过多种编写方式实现:string,array,object,function,regex。这里,我只说一些简单的内容,详细讲解,我觉得这个解释不错。

module.exports = {
// ...
externals: [ // array形式
{ // object形式
'./a', 'a', // string形式
jquery: 'jQuery',
vue: 'Vue',
},
function(context, request, callback) { // function形式
if(request.substr(0, 1) !== '.') callback(null, 'commonjs ' + request)
callback()
},
/^[a-z\-0-9]+$/, // regex形式
]
}

除了function形式,必须在array形式中,其他形式,都可以提升,直接作为externals属性使用。比如string形式:

externals: {
'./a': 'a',
jquery: 'jQuery'
}

string

属性名称是jquery,表示应该排除import $ from 'jquery' 中的 jquery模块。为了替换这个模块,jquery的值将被用来检索一个全局的$变量。换句话说,当设置为一个字符串时,它将被视为全局的,我们需要在全局变量中,找到$,才能使程序正确运行。

array

数组内的每一个元素都可以是多种形式,包括object, regex, function, string四种:

object

object形式,可以直接作为externals的值,这种形式是绝大部分项目中的配置形式。它里面一定是键值对(key: value)的形式。

function

function的使用,只能在array形式中作为一个元素传入。

regex

正则匹配的形式,通过传入正则表达式来实现匹配。这个可以放在数组形式中,也可以直接作为externals的属性。

实际案例

案例地址

以上说了如何配置的问题,在工作中,具体会是一个怎样的表现呢。我挑选了一个常用的配置object形式,做了一些操作,对比下。

  • 第一种情况,完全不使用externals配置。

    第一种情况的截图



  • 第二种情况,通过npm run build --report得出的报告,将一些不常修改的大包作为外部扩展。

    这需要做两步操作:第一步修改webpack.base.conf.js文件,第二步,将外部扩展的内容通过其他方式加载到window环境,这里,我们通过<script>标签,并使用cdn来完成。

    配置的文件:webpack.base.conf.js

externals: {
vue : 'Vue',
"echarts": 'echarts',
"element-ui": 'ELEMENT'
}

在模板文件index.html中,添加<script>标签

<script src="https://unpkg.com/vue@2.5.17/dist/vue.min.js"></script>
<script src="https://unpkg.com/element-ui@2.4.11/lib/index.js"></script>
<script src="https://unpkg.com/echarts@4.1.0/dist/echarts.min.js"></script>

第二种情况的截图:



这两种情况,我们主要从打包的时间,打包之后包的大小,实际浏览器中加载时长三个方面来做比较。

打包时间

打包时间,由原来的38s缩短至18s,大大减少了打包时间。

打包之后包的大小

主要看vendor包的大小,由原来的1.45M缩小至41.3k,缩小的内容,我们使用cdn,使其存在于外部环境。

由于externals属性,是将依赖排除,本该将node_modules中依赖包打入到vendor bundle中,变成外部扩展。

浏览器加载

使用externals属性,外部扩展,会增加请求数,由原来的6个请求变成了9个请求。由于是使用CDN,非首次请求,会使用缓存中的数据,所以加载时间不受太大影响。

截图所示时间不同,这个和多方面因素有关。你在相同的环境,每次刷新得到的结果都不一样。

需要注意

如果发现问题,可以通过以下几个方向查找:

  1. script的先后顺序
  2. cdn的地址路径是否正确
  3. 浏览器的window属性值,是否和你的externals属性的value相对应。可以在console控制台输出看看。
  4. externals的打包支持什么类型的,就和output.libraryTargetoutput.library 这两个属性有关系了。唐霜讲的清楚点,可以看看

参考

  1. 外部扩展Externals
  2. webpack externals详解
  3. 本案例地址

webpack打包优化之外部扩展externals的实际应用的更多相关文章

  1. Webpack 打包优化之体积篇

    谈及如今欣欣向荣的前端圈,不仅有各类框架百花齐放,如Vue, React, Angular等等,就打包工具而言,发展也是如火如荼,百家争鸣:从早期的王者Browserify, Grunt,到后来赢得宝 ...

  2. Webpack 打包优化之速度篇

    在前文 Webpack 打包优化之体积篇中,对如何减小 Webpack 打包体积,做了些探讨:当然,那些法子对于打包速度的提升,也是大有裨益.然而,打包速度之于开发体验和及时构建,相当重要:所以有必要 ...

  3. webpack 打包优化的四种方法(多进程打包,多进程压缩,资源 CDN,动态 polyfill)

    如今,webpack 毫无疑问是前端构建领域里最耀眼的一颗星,无论你前端走哪条路线,都需要有很强的webpack 知识.webpack 的基本用法这里就不展开讲了.主要探讨一下如何提高 webpack ...

  4. 记一次webpack打包优化

    未进行打包优化的痛点: 随着项目的不断扩大,引入的第三方库会越来越多,我们每次build的时候会对所有的文件进行打包,耗时必定很长,不利于日常开发. 解决思路: 第三方库我们只是引入到项目里来,一般不 ...

  5. [转] Webpack 打包优化之体积篇

    谈及如今欣欣向荣的前端圈,不仅有各类框架百花齐放,如Vue, React, Angular等等,就打包工具而言,发展也是如火如荼,百家争鸣:从早期的王者Browserify, Grunt,到后来赢得宝 ...

  6. webpack打包优化并开启gzip

    应用场景:项目使用webpack2.x进行打包,打包后静态资源通过nginx转发配置: 问题:webpack打包后的资源文件特别,特别大,没打包之前页面一个页面js有2M左右(其中已经抽离了css)? ...

  7. 基于CommonsChunkPlugin,webpack打包优化

    前段时间一直在基于webpack进行前端资源包的瘦身.在项目中基于路由进行代码分离,http://www.cnblogs.com/legu/p/7251562.html.但是打包的文件还是很大,特别是 ...

  8. webpack打包优化点

    目录 1. noParse 2. 包含和排除目录 3. IgnorePlugin 4. happypack 5. DllPlugin动态链接库 6. 热更新 7. 开发环境 tree-shaking ...

  9. webpack打包优化实践

    事情缘由 近段时间在做基于scratch3.0的改造项目.基于scratch-gui改造,项目本身已经很大了,然后里面还要用到scratch-blocks,scratch-vm,scratch-ren ...

随机推荐

  1. 【学习笔记】python

    1.  len( s )  返回对象(字符.列表.元祖等)的长度或项目个数. >>>str = "runoob" >>> len(str) # ...

  2. 超越村后端开发(4:API开发)

    1.users相关的api开发 1.在settings中添加APPID,SECRET 2.在apps/users/views.py内: from chaoyuecun.settings import ...

  3. golang中使用mysql数据库

    安装 安装mysql驱动 go get github.com/go-sql-driver/mysql 安装sqlx驱动 go get github.com/jmoiron/sqlx 一.插入数据库 p ...

  4. 机器学习在入侵检测方面的应用 - 基于ADFA-LD训练集训练入侵检测判别模型

    1. ADFA-LD数据集简介 ADFA-LD数据集是澳大利亚国防学院对外发布的一套主机级入侵检测数据集合,包括Linux和Windows,是一个包含了入侵事件的系统调用syscall序列的数据集(以 ...

  5. Unity 案例

    Unity 案例-用Unity 开发的产品 水电站管理.监控.培训系统 石油加工管理系统 房地产开发 污水处理系统 陆海空军事训练 城市和社区监控,管理系统 虚拟展馆 家庭自动化系统 石油加工管理系统 ...

  6. [图解Java]读写锁ReentrantReadWriteLock

    图解ReentrantReadWriteLock 如果之前使用过读写锁, 那么可以直接看本篇文章. 如果之前未使用过, 那么请配合我的另一篇文章一起看:[源码分析]读写锁ReentrantReadWr ...

  7. 1. Ansible 简介

    目录 1. Ansible 是什么? 2. Ansible 特性 3. 控制主机需求 4. 被管理节点需求 1. Ansible 是什么? Ansible 是一个配置管理系统(configuratio ...

  8. SimMechanics/Second Generation倒立摆模型建立及初步仿真学习

    笔者最近捣鼓Simulink,发现MATLAB的仿真模块真的十分强大,以前只是在命令窗口敲点代码,直到不小心敲入simulink,就一发不可收拾.话说simulink的模块化建模确实方便,只要拖拽框框 ...

  9. 通过DeviceIoControl读磁盘的方式读取独占文件内容

    前言 windows操作系统中常见的一个文件存储系统是NTFS.在这个文件系统中MFT是它的核心.             图一 MFT是一个数据结构,上图是它的结构,它主要用来存放每个文件和目录在磁 ...

  10. JSP循环缓存列表

    两种方法: 例如,有下拉框 <select></select>其中选项需要循环显示 1.JAVA代码循环 <% for(int i=0;i<list.size(); ...