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

如果不想把第三方库打包到bundle中,这就有了externals。官方的使用externals比较简单,只需三步——
1.在HTML中引入第三方库的cdn
2.在webpack中配置externals
externals: {
jquery: "jQuery",
}
3.在js中引用
const $ = require("jquery");
$("#content").html("<h1>hello world</h1>");
好,现在我们可以随心所欲的使用jquery插件并保证不会打包到bundle中。external是怎么办到的呢?下面我们通过bundle的源码来分析下原理。

这里的/* 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

当然,既然是通过这种externals方式,其实我们可以不用require引入,直接使用全局变量也是可以的。
jQuery("#content").html("<h1>hello world</h1>");
大家如果注意到我刚说过的global模式的话,没错,你也许已经猜到了,我可以任意的使用不同的输出方式。如果打包文件我想运行到node环境下,我得使用commonjs规范,所以你要这么写。
externals: {
jquery: "commonjs2 jQuery",
}
打包后会是这样子。

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


现在我们的externals配置如下
externals: {
jquery: "jQuery",
_: "lodash"
}

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

这个东西是干嘛用的呢?
他是我们输出文件的模块化规范,想想我们上面配置的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

然后报这个错误,也就是说我们的模块没有正确的输出,回到我们的externals,它更多的是指定当你引用一个包的时候,这个包(lodash)应该遵循哪种模块化方式(common,root,amd等等)引入,这意思就是说,打包的时候不需要关心他到底怎么输出。
externals: {
jquery: "jQuery",
lodash: {
commonjs: 'lodash',
commonjs2: 'lodash',
amd: 'lodash',
root: '_'
}
},
ok,记得要将之前的覆盖掉,替换成下面的require,因为在externals中我们规范的commmonjs规范为lodash

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

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

相应的源码是这样子

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

看到了吧,我通过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'
},
webpack之深入浅出externals的更多相关文章
- webpack里的externals
最近在用webpack做一些是sdk相关的东西,有几个概念总结一下: 1.library要做sdk,一定要做的一个配置,用于说明最终的SDK暴露给调用者的一个名称例如:library: 'HelloJ ...
- 详解前端模块化工具-webpack
webpack是一个module bundler,抛开博大精深的汉字问题,我们暂且管他叫'模块管理工具'.随着js能做的事情越来越多,浏览器.服务器,js似乎无处不在,这时,使日渐增多的js代码变得合 ...
- 基于 Webpack 引入公共库的几种方式
以 jquery 和其插件 jquery-modal 为例,记录下引入公共库的几种方式. 为了方便,首先安装 jquery 和 jquery-modal: cnpm i jquery jquery-m ...
- 优化Webpack打包速度
1. Webpack 可以配置 externals 来将依赖的库指向全局变量,从而不再打包这个库,比如对于这样一个文件: import React from 'react'; console.lo ...
- webpack点滴
一个比较完整的webpack的配置,自己配置不断更新. const path = require('path') const configs = require('./configs/') const ...
- 彻底解决Webpack打包慢的问题
转载 这几天写腾讯实习生 Mini 项目的时候用上了 React 全家桶,当然同时引入了 Webpack 作为打包工具.但是开发过程中遇到一个很棘手的问题就是,React 加上 React-Route ...
- 【Webpack】320- Webpack4 入门手册(共 18 章)(下)
介绍 1. 背景 最近和部门老大,一起在研究团队[EFT - 前端新手村]的建设,目的在于:帮助新人快速了解和融入公司团队,帮助零基础新人学习和入门前端开发并且达到公司业务开发水平. 本文也是属于[E ...
- 基于Gulp + Browserify构建es6环境下的自动化前端项目
随着React.Angular2.Redux等前沿的前端框架越来越流行,使用webpack.gulp等工具构建前端自动化项目也随之变得越来越重要.鉴于目前业界普遍更流行使用webpack来构建es6( ...
- vue客户端渲染首屏优化之道
提取第三方库,缓存,减少打包体积 1. dll动态链接库, 使用DllPlugin DllReferencePlugin,将第三方库提取出来另外打包出来,然后动态引入html.可以提高打包速度和缓存第 ...
随机推荐
- mysql单独可连接,php连接mysql失败之 Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
此种解决方案使用场景: 1,mysql单独可以启动而且远程工具也可以连接 2,php无法连接. 3,find / -name mysql.sock 可以找到文件路径 4,报错 Can't connec ...
- Linux入门(15)——Ubuntu16.04安装codeblocks搭建C/C++的IDE环境
安装codeblocks: sudo add-apt-repository ppa:damien-moore/codeblocks-stable sudo apt-get update sudo ap ...
- C++点滴20130802
1.sprintf与printf,fprintf为三兄弟.其中printf输出到屏幕,fprintf输出到文件,而sprintf输出到字符串中.通常情况下,屏幕是可以输出的,文件也可以写的(除非磁盘满 ...
- LINUX 笔记-ls命令
常用参数: -l :列出长数据串,包含文件的属性与权限数据等 -a :列出全部的文件,连同隐藏文件(开头为.的文件)一起列出来(常用) -d :仅列出目录本身,而不是列出目录的文件数据 -h :将文件 ...
- 从零起步学python计划及感想
从纯传统bi转型过来的技术顾问,比较有优势的是对业务的熟悉,对数据有敏感度,熟悉数据模型.但是长年累月基本都是用sql处理问题.目前还没有经历过sql解决不了的问题,一个sql解决不了就用临时表,几个 ...
- PyQt5安装目录中找不到designer.exe与pyrcc5.exe
我安装的是PyQt5的5.9版本,在安装目录下找不到designer.exe文件.在摸索一段后发现5.9版本对库文件和相关的开发工具是分开发布的.QtDesigner是在pyqt5-tools的包里. ...
- Android: Only the original thread that created a view hierarchy can touch its views 异常
最近自己再写一个小项目练手,创建一个线程从网络获取数据然后显示在 recyclerView 上.写好后发现页面能够显示,但是有时候会把请求的数据显示过来,有时候不会.点开 android monito ...
- hihocoder 1015题
代码 #include <iostream> #include <string> #include <typeinfo> #include <vector&g ...
- Hat's Fibonacci
Problem Description A Fibonacci sequence is calculated by adding the previous two members the sequen ...
- Group(), Groups(),& Groupdict()
group() 返回一个或多个匹配的字串.如果只有一个参数,结果只有单个字符串:如果有多个参数,结果是一个元组,元组里每一项对应一个参数.没有参数,group1默认是0(整个匹配串被返回).如果gro ...