当ArcGIS API for JavaScript遇见Webpack(二)
来源:互联网 发布:快速赚钱 知乎 编辑:程序博客网 时间:2024/06/06 00:23
当ArcGIS API for JavaScript遇见Webpack(二)
作者:liuyl 邮箱:liuyl.gisuni@gmail.com
关于作者:GIS从业者,主要在ArcGIS平台下做WebGIS开发
广告移到前面以免你看不到
公众号开通了,欢迎扫描下面二维码进行关注,我争取每周都写一两篇文章,记录和分享工作和学习中的收获。内容将主要是WebGIS开发方面的,欢迎在公众号中留言和我进行交流。
写在最前面
如果你还没有看过并理解了上一篇 当ArcGIS API for JavaScript遇见Webpack(一) 的内容的话,请移步第一篇。
为什么写这篇文章
在上一篇中,我们成功的让ArcGIS API for JavaScript和Webpack和谐地相处了。
如果是个Demo的话,这就算是成功了。不过我们是要做项目的,第三方库比如jquery、lodash甚至是react之类的,总是要用到一些。甚至更进一步,我们要开发一个基于ArcGIS API for JavaScript的组件库,并希望像其他第三方库一样用import
语句引用。
这时你会发现,ArcGIS API for JavaScript和Webpack的相处并不如表面上那么和谐,问题一个接一个出现……现在,我们来一个个地解决这些问题。
下面是正文
正常情况下引入第三方库
关于正常情况下,也就是不引入ArcGIS API for JavaScript,或是dojo,又或是AMD时,第三方库的引用还是比较简单的,有大量教程可供参考,这里简单列一下。
(以下均以从CDN引入jquery、lodash和react.js为例、且不考虑把第三方库的代码直接一同打包的情况)
- 引入js文件
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script><script src="https://cdn.bootcss.com/lodash.js/4.17.4/lodash.min.js"></script><script src="https://cdn.bootcss.com/react/15.6.1/react.js"></script>
- 修改webpack配置
externals
项
将webpack的externals
项配置成如下
externals: [ { jquery: 'jQuery', lodash: '_', react: 'React', },]
这一步的配置可以让我们在代码中使用import
语句引入第三方库,比如:
import $ from 'jquery' import _ from 'lodash' import React from 'react'
- 修改webpack配置
plugins
项(可选)
在webpack的plugins
项配置中添加如下代码
plugins: [ new webpack.ProvidePlugin({ $: 'jquery', _: 'lodash', }),]
这一步的配置可以让我们不需要再通过import
语句引入jquery和lodash,而是可以直接在全局使用$和_符号
在引入ArcGIS API for JavaScript的情况下引入第三方库
假设按照第一篇中我们引入了ArcGIS API for JavaScript,并按照上面所述引入第三方库、修改webpack配置。然后写一个例子,比如这样:
import Map from 'esri/Map'import MapView from 'esri/views/MapView'const $mapDom=$('<div style="width:400px;height:300px"></div>').appendTo($('body'))var map = new Map({ basemap: 'streets'})var view = new MapView({ container: yourDom, map: map})
直接访问应用,喜闻乐见地在控制台看到了错误信息。
这里我们同时引用了jquery和api,这个错误信息取决于jquery和api在html页中的引入次序,主要是两类错误。
multipleDefine错误
这主要是由于在html页中api的init.js在第三方库(如jquery.js)之前被引入。
具体成因我没有搞清楚,欢迎补充~
找不到库文件错误
当在html页中api的init.js
在第三方库(如jquery.js
)之后被引入时,就会导致这个错误。
第一篇时我们讨论过webpack的externals
项配置,它是用来标明外部引用的。
externals: [ { jquery: 'jQuery', },]
这个配置会让打包生成的js文件的最前面生成类似这样的代码
define(["jQuery", ……], function (__WEBPACK_EXTERNAL_MODULE_3__,……){ ... })
对dojo比较熟的同学会看出来,当AMD不认识jQuery
时,就会在其工作路径下寻找jQuery.js
文件,找不到的话就会报上面的错误。
如何避免错误
针对上述第1个错误,我们需要在html文件中将api的init.js
文件放在其他第三方库的后面引入。
针对第2个错误,我们可以在api的init.js
文件引入后,人为地将第三方库的全局名称define
到AMD中,html文件中大致这样:
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script><script src="https://cdn.bootcss.com/lodash.js/4.17.4/lodash.min.js"></script><script src="https://cdn.bootcss.com/react/15.6.1/react.js"></script><script src="https://js.arcgis.com/4.4/init.js"></script><script> define("jQuery",[],function () { return jQuery }) define("lodash",[],function () { return lodash }) define("React",[],function () { return React })</script><script> require(['app.js'],function () { })</script>
webpack的配置按上面说的正常情况进行修改即可。
写一个基于ArcGIS API for JavaScript的组件库
正常情况下写一个类库时,webpack的output
配置项,应该配置成如下的样子
output: { libraryTarget: 'umd', library: 'YourLib', ……}
libraryTarget: 'umd'
意味着我们的库可以通过输出全局变量引入,也支持commonJs或AMD方式引入,大部分我们常使用的第三方库都是这样的。但正如前所说,这样的库在ArcGIS API for JavaScript的init.js
文件之后引入时会导致multipleDefine
错误。
我们的库是基于ArcGIS API for JavaScript的,也就是不得不在api后面引入,如果我们设置了libraryTarget: 'umd'
,那么就同样会遇到multipleDefine
错误。
解决这个问题,就把webpack的output
项设置成如下所示
output: { libraryTarget: 'var', library: 'MyLib', ……}
libraryTarget: 'var'
其实是默认值,就是向全局输出一个MyLib
变量,在应用中引入这个库时,同样需要手动define
一下,整个引入流程大致如下:
webpack配置
externals: [ { mylib: 'MyLib', },]
html文件
<script src="https://js.arcgis.com/4.4/init.js"></script><script src="/mylib.js"></script><script> define("MyLib",[],function () { return MyLib })</script><script> require(['app.js'],function () { })</script>
应用调用文件
import myLib from 'mylib'myLib.testFun()
最后,这个库如何封装和调用ArcGIS API for JavaScript
function createMap(dom){ window.require(['esri/Map', 'esri/views/MapView'], (Map, MapView) => { var map = new Map({ …… }) this.view = new MapView({ container: dom, map: map, }) })}export default createMap
上面只是个示例,这里就不能用import
语句调用api了,而是使用传统的require
语句。但是要注意的是不能直接写require
,因为webpack会对require
语句进行编译,用window.requrire
不会被编译。
当然,我感觉通过webpack的适当配置,还是有可能实现使用import
语句调用api的,欢迎有兴趣的同学继续探索。
写在最后
关于ArcGIS API for JavaScript和Webpack之间的纠葛就写到这了。
这两篇里面的内容实际上折腾了我挺长时间,当然也是在这个过程中才逐渐理解了webpack的核心逻辑,还是挺值得的。
ArcGIS API for JavaScript和Webpack之间的集成,其实还有一些其他的解决方案,比如esri-loader。我没有尝试去用过,据说有坑,有兴趣的同学倒也不妨一试。对于我这个ArcGIS API for JavaScript的深度用户,还是希望保持对其的绝对控制的,这两篇文章中的解决方案基本上满足了我工作中的需求,我觉得还是比较完善的。
如果你觉得这篇文章对你有帮助,请移动到文章顶部,关注我的微信公众号。
- 当ArcGIS API for JavaScript遇见Webpack(二)
- 当ArcGIS API for JavaScript遇见Webpack(一)
- Arcgis API for Javascript入门(二)
- ArcGIS API for Javascript 实现在线要素编辑(二)
- (二)ArcGIS API For JavaScript之Hello_World
- ArcGIS API for Javascript 实现在线要素编辑(二)
- vue-cli&webpack&arcgis API For JS的天坑之路(二)
- ArcGIS API for JavaScript
- ArcGIS.Server.9.3和ArcGIS API for JavaScript实现Toc功能(二)
- ArcGIS.Server.9.3和ArcGIS API for JavaScript实现Toc功能(二)
- ArcGIS API for JavaScript DEMO使用-ArcGIS Web 开发学习(二)
- ArcGIS API for Javascript(中文版!!) 谁有啊。。。。。。。
- Arcgis API for Javascript入门(一)
- 学习ArcGIS API for JavaScript(1)
- 【ArcGis for javascript从零开始】之二 ArcGIS for JavaScript安装本地API
- 深入浅出ArcGIS 9.3 Javascript API(二)
- arcgis api for JavaScript相关
- arcgis api for JavaScript相关
- NOIP 2009 提高组 潜伏者
- CentOSping的通外网ping不通本地主机
- maven使用阿里云仓库
- Hadoop完全分布式安装Hive
- Error calling RCTDeviceEventEmitter.emit in ReactNative && error calling appregistry.runapplication
- 当ArcGIS API for JavaScript遇见Webpack(二)
- Indian Buffet Process(印度自助餐过程)介绍
- MySQL半同步复制
- 基于vue+node+mongo实现一个锤子商城
- 生成随机数的类Random和ThreadLocalRandom
- python爬虫(urllib简介)
- xiaoxin juju needs help HDU
- 二叉树的遍历
- 监听器实现案例----自定义session扫描器和统计在线用户人数及用户信息