當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的深度使用者,還是希望保持對其的絕對控制的,這兩篇文章中的解決方案基本上滿足了我工作中的需求,我覺得還是比較完善的。
如果你覺得這篇文章對你有幫助,請移動到文章頂部,關注我的微信公眾號。
如果你有任何疑問和建議,歡迎留言和我交流。
相關文章
- 當Elasticsearch遇見KafkaElasticsearchKafka
- 當 Node.js 遇見 DockerNode.jsDocker
- 當Node.js遇見DockerNode.jsDocker
- 當 better-scroll 遇見 VueVue
- 【譯】當 Kotlin 遇見 GradleKotlinGradle
- 當Elasticsearch遇見智慧客服機器人Elasticsearch機器人
- [原始碼解析] 當 Java Stream 遇見 Flink原始碼Java
- 當深度學習遇見自動文字摘要深度學習
- 有容雲-PPT | 當微服務遇見容器微服務
- 當知識圖譜“遇見”深度學習深度學習
- 基於ArcGIS API for Javascript的地圖編輯工具APIJavaScript地圖
- 建立ArcGIS API for JavaScript的第一個示例程式APIJavaScript
- 當Atlas遇見Flink——Apache Atlas 2.2.0釋出!Apache
- 當 Kotlin 遇見 RxJava 多資料來源KotlinRxJava
- 當 Flutter 遇見 Web,會有怎樣的祕密 ?FlutterWeb
- 關於翻譯ArcGIS API for JavaScript開發書籍的經歷APIJavaScript
- ArcGIS API for JS 中的styleAPIJS
- 全程燒腦幹貨,當人工智慧遇見量子計算人工智慧
- ArcGIS API for JavaScript開發環境搭建及第一個例項demoAPIJavaScript開發環境
- ElasticSearch 遇見(4)Elasticsearch
- ArcGis api配合vue開發入門系列(一)引入arcgis api以及載入地圖APIVue地圖
- JavaScript 陣列常見操作 (二)JavaScript陣列
- ArcGIS API for JavaScript根據兩個點座標在地圖上畫線APIJavaScript地圖
- 遇見C++ LambdaC++
- javascript字串常用api使用匯總(二)JavaScript字串API
- 當“北歐精靈”歐若拉遇見蘋果最佳遊戲《光·遇》,網友直呼這麼聽歌太治癒了!蘋果遊戲
- 當人工智慧遇見農業,農民伯伯不再「粒粒皆辛苦」人工智慧
- 乾貨|當深度學習遇見自動文字摘要,seq2seq+attention深度學習
- 讀所羅門的密碼筆記01_當人類遇見機器密碼筆記
- 航空遇見大資料大資料
- arcgis api for flex三個點求夾角APIFlex
- Frida官方手冊 - JavaScript API(篇二)JavaScriptAPI
- ArcGis api配合vue開發入門系列(二)距離以及面積的測量APIVue
- 我遇見的那些面試題面試題
- 遇見程式設計師男友程式設計師
- Webpack 之常見見招拆招Web
- ArcGIS API for Silverlight 學習筆記API筆記
- webpack教程(二)Web