深入浅出webpack之externals的使用


Posted in Javascript onDecember 04, 2017

我们通常在做项目时可能会把第三方库打包到bundle中,比如下面这张图

深入浅出webpack之externals的使用

如果不想把第三方库打包到bundle中,这就有了externals。官方的使用externals比较简单

externals

官网文档解释的很清楚,就是webpack可以不处理应用的某些依赖库,使用externals配置后,依旧可以在代码中通过CMD、AMD或者window/global全局的方式访问。

只需三步——

1.在HTML中引入第三方库的cdn

2.在webpack中配置externals

externals: {
 jquery: "jQuery",
}

3.在js中引用

const $ = require("jquery");
$("#content").html("<h1>hello world</h1>");

好,现在我们可以随心所欲的使用jquery插件并保证不会打包到bundle中。external是怎么办到的呢?下面我们通过bundle的源码来分析下原理。

深入浅出webpack之externals的使用

这里的/* 0 */和__webpack_require__分别指打包前js对应的模块函数,这里就不细说了。这里可以看到module.exports = jQuery,就是说我们externals中的key指的是require的东西,value指的就是它,就是说“当require的参数是jquery的时候,使用jQuery这个全局变量引用它”。这种最简洁的externals配置方式为默认的global模式,就是在window上挂一个全局变量,然后直接可以使用这个变量。具体的流程是这样,我们在源码中使用require('jquery')后,可以直接把jquery加到externals中,得到一个打包的trunk.js,但是在引入这个trunkjs之前,肯定要先引入jquery这个库文件,这个库文件会创建一个全局变量jQuery,而咱们的trunkjs中externals的jquery是global模式,所以实际上trunkjs引入jquery的时候,就会从全局变量中引用,即module.export = jQuery

深入浅出webpack之externals的使用

当然,既然是通过这种externals方式,其实我们可以不用require引入,直接使用全局变量也是可以的。

jQuery("#content").html("<h1>hello world</h1>");

大家如果注意到我刚说过的global模式的话,没错,你也许已经猜到了,我可以任意的使用不同的输出方式。如果打包文件我想运行到node环境下,我得使用commonjs规范,所以你要这么写。

externals: {
 jquery: "commonjs2 jQuery",
}

打包后会是这样子。

深入浅出webpack之externals的使用

然后我的项目中还用到了lodash,也想把它从bundle中移除,之前我的代码是这样子,引的是npm包

深入浅出webpack之externals的使用

深入浅出webpack之externals的使用

现在我们的externals配置如下

externals: {
  jquery: "jQuery",
  _: "lodash"

}

深入浅出webpack之externals的使用

我们必须要去掉这个const ,否则的话会报一个错误 lodash is not defined。为什么会这样呢?因为我们的lodash输出是global格式的,我在这里先卖一个关子,我们先统一一下输出格式,加一个libraryTarget字段

深入浅出webpack之externals的使用

这个东西是干嘛用的呢?

他是我们输出文件的模块化规范,想想我们上面配置的commonjs jquery是运行在node下,总之记住一句话——我们最长使用的模块化方案是commonjs2和umd,前者是为node环境,后者是为浏览器环境。一共有这几种规范:

"var" - Export by setting a variable: var Library = xxx (default)

"this" - Export by setting a property of this: this["Library"] = xxx
"commonjs" - Export by setting a property of exports: exports["Library"] = xxx
"commonjs2" - Export by setting module.exports: module.exports = xxx
"amd" - Export to AMD (optionally named - set the name via the library option)
"umd" - Export to AMD, CommonJS2 or as property in root

深入浅出webpack之externals的使用

然后报这个错误,也就是说我们的模块没有正确的输出,回到我们的externals,它更多的是指定当你引用一个包的时候,这个包(lodash)应该遵循哪种模块化方式(common,root,amd等等)引入,这意思就是说,打包的时候不需要关心他到底怎么输出。

externals: {
  jquery: "jQuery",
  lodash: {
   commonjs: 'lodash',
   commonjs2: 'lodash',
   amd: 'lodash',
   root: '_'
  }
 },

ok,记得要将之前的覆盖掉,替换成下面的require,因为在externals中我们规范的commmonjs规范为lodash

深入浅出webpack之externals的使用

也就是说,这就是我们最初的代码,即没有用过externals时候的代码,看,也就是说我们只需要配置externals和libraryTarget就可以,其他的业务逻辑代码不需要改变。包括我们的项目中还用了echarts,这个通通不用改变!!!!!

深入浅出webpack之externals的使用

也就是说最终的代码是externals配合libraryTarget一起使用,如果去掉umd的话,会报这个错误

深入浅出webpack之externals的使用

相应的源码是这样子

深入浅出webpack之externals的使用

就是说我不知道通过那种方式输出,所以我应该告诉webpack,我通过umd方式输出,即将你的 lodash 暴露为所有的模块定义下都可运行的方式。它将在 CommonJS, AMD 环境下运行,或将模块导出到 global 下的变量.加上umd的源码如下

深入浅出webpack之externals的使用

看到了吧,我通过require('lodash')引入模块,输出走的是commonjs规范,贴下最终的配置

entry: {
  main: './src/index.js'
 },
 externals: {
  jquery: "jQuery",
  lodash: {
   commonjs: 'lodash',
   commonjs2: 'lodash',
   amd: 'lodash',
   root: '_'
  }
 },
 output: {
  filename: '[name].[chunkhash].js',
  path: path.resolve(__dirname,'dist'),
  libraryTarget: 'umd'
 },

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
在js中使用&quot;with&quot;语句中跨frame的变量引用问题
Mar 08 Javascript
javascript 二维数组的实现与应用
Mar 16 Javascript
一个可以增加和删除行的table并可编辑表格中内容
Jun 16 Javascript
jQuery html()方法使用不了无法显示内容的问题
Aug 06 Javascript
javascript数组去重方法汇总
Apr 23 Javascript
js+HTML5基于过滤器从摄像头中捕获视频的方法
Jun 16 Javascript
JS实现图片局部放大或缩小的方法
Aug 20 Javascript
利用Angularjs和原生JS分别实现动态效果的输入框
Sep 01 Javascript
js实现table添加行tr、删除行tr、清空行tr的简单实例
Oct 15 Javascript
postman自定义函数实现 时间函数的思路详解
Apr 17 Javascript
layui输入框只允许输入中文且判断长度的例子
Sep 18 Javascript
ant-design表单处理和常用方法及自定义验证操作
Oct 27 Javascript
基于js 字符串indexof与search方法的区别(详解)
Dec 04 #Javascript
基于JavaScript中字符串的match与replace方法(详解)
Dec 04 #Javascript
基于JSONP原理解析(推荐)
Dec 04 #Javascript
利用Javascript获取选择文本所在的句子详解
Dec 03 #Javascript
微信小程序图片选择区域裁剪实现方法
Dec 02 #Javascript
vue中eventbus被多次触发以及踩过的坑
Dec 02 #Javascript
Angular之toDoList的实现代码示例
Dec 02 #Javascript
You might like
回首过去10年中最搞笑的10部动漫,哪一部让你节操尽碎?
2020/03/03 日漫
4月1日重磅发布!《星际争霸II》6.0.0版本更新
2020/04/09 星际争霸
flash用php连接数据库的代码
2011/04/21 PHP
php的ddos攻击解决方法
2015/01/08 PHP
laravel5.4利用163邮箱发送邮件的步骤详解
2017/09/22 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
JQuery SELECT单选模拟jQuery.select.js
2009/11/12 Javascript
extjs中form与grid交互数据(record)的方法
2013/08/29 Javascript
动态加载JS文件的三种方法
2013/11/08 Javascript
jquery mobile的触控点击事件会多次触发问题的解决方法
2014/05/08 Javascript
如何让你的Lightbox支持滚轮缩放及Base64图片
2014/12/04 Javascript
JavaScript中创建字典对象(dictionary)实例
2015/03/31 Javascript
jQuery实现冻结表格行和列
2015/04/29 Javascript
基于Bootstrap实现tab标签切换效果
2020/04/15 Javascript
Jquery组件easyUi实现手风琴(折叠面板)示例
2016/08/23 Javascript
AngularJS extend用法详解及实例代码
2016/11/15 Javascript
基于Bootstrap和jQuery构建前端分页工具实例代码
2016/11/23 Javascript
js 调用百度分享功能
2017/02/27 Javascript
JS简单实现自定义右键菜单实例
2017/05/31 Javascript
vue-router单页面路由
2017/06/17 Javascript
layui--js控制switch的切换方法
2019/09/03 Javascript
Python高级应用实例对比:高效计算大文件中的最长行的长度
2014/06/08 Python
Python多线程编程(三):threading.Thread类的重要函数和方法
2015/04/05 Python
python模块简介之有序字典(OrderedDict)
2016/12/01 Python
python给微信好友定时推送消息的示例
2019/02/20 Python
python中设置超时跳过,超时退出的方式
2019/12/13 Python
波兰家具和室内装饰品购物网站:Vivre
2018/04/10 全球购物
哄娃神器4moms商店:美国婴童用品品牌
2019/03/07 全球购物
Brother加拿大官网:打印机、贴标机、缝纫机
2019/10/09 全球购物
梅西百货官网:Macy’s
2020/08/04 全球购物
腾讯公司的一个sql题
2013/01/22 面试题
安全承诺书格式
2014/05/21 职场文书
教师竞聘上岗演讲稿
2014/09/03 职场文书
大学生暑期社会实践证明范本
2014/10/24 职场文书
维稳工作承诺书
2015/01/20 职场文书
2015年优质护理服务工作总结
2015/04/08 职场文书