当ArcGIS API for JavaScript遇见Webpack(二)

来源:互联网 发布:快速赚钱 知乎 编辑:程序博客网 时间:2024/06/06 00:23

当ArcGIS API for JavaScript遇见Webpack(二)

96 
小林666 关注
2017.08.23 02:48* 字数 1671 阅读 125评论 0赞赏 1

作者:liuyl 邮箱:liuyl.gisuni@gmail.com
关于作者:GIS从业者,主要在ArcGIS平台下做WebGIS开发


广告移到前面以免你看不到


公众号开通了,欢迎扫描下面二维码进行关注,我争取每周都写一两篇文章,记录和分享工作和学习中的收获。内容将主要是WebGIS开发方面的,欢迎在公众号中留言和我进行交流。


请扫码关注我的微信公众号 幻想GIS
请扫码关注我的微信公众号 幻想GIS

写在最前面


如果你还没有看过并理解了上一篇 当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为例、且不考虑把第三方库的代码直接一同打包的情况)

  1. 引入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>
  1. 修改webpack配置externals
    将webpack的externals项配置成如下
externals: [    {        jquery: 'jQuery',        lodash: '_',        react: 'React',    },]

这一步的配置可以让我们在代码中使用import语句引入第三方库,比如:

    import $ from 'jquery'    import _ from 'lodash'    import React from 'react'
  1. 修改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页中的引入次序,主要是两类错误。

  1. multipleDefine错误



这主要是由于在html页中api的init.js在第三方库(如jquery.js)之前被引入。
具体成因我没有搞清楚,欢迎补充~

  1. 找不到库文件错误



当在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的深度用户,还是希望保持对其的绝对控制的,这两篇文章中的解决方案基本上满足了我工作中的需求,我觉得还是比较完善的。

如果你觉得这篇文章对你有帮助,请移动到文章顶部,关注我的微信公众号。

阅读全文
0 0
原创粉丝点击