1. 程式人生 > >Cesium官方教程13--Cesium和Webpack

Cesium官方教程13--Cesium和Webpack

mage col 一點 告訴 fin 傳遞參數 width hash 6.0

原文地址:https://cesiumjs.org/tutorials/cesium-and-webpack/
Cesium 和 Webpack
Webpack是非常強大非常流行的JavaScript 模塊打包工具。它可以讓開發人員以一種簡單直觀的 require 方式去加載各種頁面需要的文件,極大的方便了開源人員對代碼和資源文件進行結構化設計。當編譯的時候,它會跟蹤代碼依賴性,把所有的模型打包到瀏覽器可以直接加載的一個或者多個bundles中。
在這個教程的前一半,我們創建一個簡單的web項目,學會使用webpack,然後再去集成 Cesium npm模塊。這是基於Cesium開發正式web項目的很好開端,但是它不是學習Cesium的最簡單示例,可以看一下我們的新手入門。
在教程的後半部分,我們將討論更多高級的webpack 配置參數,去優化使用Cesium的項目。
這個優化Cesium和Webpack集成的項目示例,可以查看官網webpack示例 代碼庫。
先決條件

對命令行,JavaScript語言和web開發需要有一個基本了解。
一個代碼編輯器(IDE)。Cesium團隊的開發人員都用 Webstorm, 但是 Sublime Text 等工具也可以。
安裝了Node.js 。LTS版本最好,但是只要是v6以上都可以的。

創建一個基本的 webpack 程序
第一部分,描述如何建立一個簡本的webpack程序以及一個開發測試服務器。如果你已經創建了程序,就想添加Cesium,直接看後面和Cesium繼承部分。

使用npm初始化程序
創建一個程序目錄,命名為cesium-webpack-app。打開控制臺,定位到該目錄下,運行下面的命令:
技術分享圖片
根據提示信息,填寫你的項目裏的詳細信息。一路按enter使用默認配置也是可以的。完成後,這個目錄下創建了一個 package.json文件。
編寫自己的程序代碼
在這個目錄下,創建一個源碼目錄src。這個目錄是我們項目源碼所在位置,我們編輯的文件都放這下面。當我們編譯後,webpack會自動生成編譯後文件放在 dist目錄下。
我們創建一個 src/index.html文件,用一個HTML頁面的模板。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>Hello World!</title>
</head>
<body>
<p>Hello World!</p>
</body>
</html>
現在我們需要添加我們程序的入口 。這個入口會告訴webpack去把所有依賴的源碼文件打包。打包後的文件才會在 index.html文件裏引用。
現在,為了簡單,我們新建 src/index.js文件,只添加下面這句確認環境配置好了。
技術分享圖片
安裝和配置webpack
下來我們安裝webpack。
技術分享圖片
技術分享圖片
webpack安裝
配置參數
創建一個名為webpack.config.js的文件。這是定義webpack的配置參數 的地方,它會傳給webpack的編譯器。
技術分享圖片
首先,我們需要從Nodejs中加載 path和我們剛剛安裝的webpack模塊。我們告訴webpack,context的及處理路徑是Node的全局變量__dirname,這個全局變量指的這個文件所在的目錄位置。我們設定了我們的程序入口是 src/index.js,而且把它命名為app。我們還告訴webpack把打包後的文件(這個文件的名稱叫app.js,因為我們設置了程序入口的[name])輸出到dist目錄下。最後export 把這個配置對象導出,其他文件才能用到這個配置。
加載器(Loaders)
我們還需要加載我們的css以及其他資源文件的方法。webpack允許我們像加載js模塊一樣,載入這些文件。我們需要使用 loaders。我們需要使用 style-loader, css-loader, 和 url-loader。
技術分享圖片
技術分享圖片
loader安裝
繼續往 webpack.config.js裏添加 module.rules。我們添加兩個規則,一個是為css文件,一個是為其他靜態文件。每個一個配置,我們定義 test過濾器來篩選這種類似的文件,還定義了一個use數組,指定這種類型用到的loader。
技術分享圖片
插件
項目已經創建好了,下來需要修改index.html ,讓它把打包文件引到頁面上。使用webpack的 插件(plugins) 中的 html-webpack-plugin。
技術分享圖片
技術分享圖片
安裝plugin
在webpack.config.js 文件的最開始加載這個插件,並添加到 plugins配置裏去。把 src/index.html 做為一個template設置,webpack就會自動在這個頁面註入一個我們的打包文件的引用。
技術分享圖片
註意,這個配置文件也是一個普通的JavaScript文件,所以我們可以引用任何Nodejs的模塊,做任何操作。

打包程序
在 package.json文件裏添加一點腳本配置,我們就能很方便的調用npm。把裏面默認的"test"腳本刪除掉,我們用不上它。添加一個build命令。
技術分享圖片
這個腳本就是簡單的調用了webpack命令,並把我們剛才新建的配置文件webpack.config.js 當作參數傳遞過去。
因為我們的webpack剛才是本地安裝。這樣每個項目都使用獨立的版本,這也是webpack的推薦安裝方式。如果你選擇全局安裝方式,使用 npm install --global webpack全局安裝webpack,然後這裏的build命令修改為 webpack --config webpack.config.js。
我們運行下編譯命令。
技術分享圖片
你應該可以看到webpack開始輸出了一些信息:
npm run build

[email protected] build C:\workspace\test-app
node_modules/.bin/webpack --config webpack.config.js

Hash: 2b42bff7a022b5d956a9
Version: webpack 3.6.0
Time: 2002ms
Asset Size Chunks Chunk Names
Assets/Textures/NaturalEarthII/2/0/3.jpg 10.3 kB [emitted]
app.js 162 kB 0 [emitted] app
技術分享圖片
譯者機器上的輸出

我們的打包文件app.js 和index.html 輸出到了 dist目錄。這些文件已經是可以使用的程序了。
技術分享圖片
編譯後的目錄
啟動開發服務器
這個還不算什麽。我們使用 webpack-dev-server 快速的搭建一個開發者服務器,我們的程序就可以實時查看了。
首先安裝webpack-dev-server
技術分享圖片
下來,在 package.json文件中增加另外的腳本。使用start命令去啟動服務,通過 --config參數傳遞參數。還傳一個 --open去自動在瀏覽器打開我們的頁面。
"scripts": {
"build": "node_modules/.bin/webpack --config webpack.config.js",
"start": "node_modules/.bin/webpack-dev-server --config webpack.config.js --open"
}
我們需要告訴服務器去哪裏尋找文件。這個需要和我們的webpack輸出目錄一致,也就是 dist目錄。所以在 webpack.config.js文件中增加一些配置。
技術分享圖片
最後,我們運行程序
技術分享圖片
你應該能看見程序已經在 localhost:8080運行了。如果你打開瀏覽器控制臺,因會看見“Hello World!” 已經輸出了。
技術分享圖片
瀏覽器命令行
webpack 程序裏集成 Cesium
我們的webpack程序已經搭好了框架,下來我們幹點有意思的,增加Cesium。

安裝Cesium
從npm中安裝 cesium 模塊,在 package.json 中增加開發依賴選項。
技術分享圖片
webpack中配置Cesium
Cesium是一個龐大的復雜的庫。除了JavaScript模塊之外,它還包含靜態資源css,圖片和json文件。它也包含為了多線程進行大量計算的web worker。和傳統npm模塊不同,Cesium也沒有定義一個入口,因為這個庫可以各種方式應用。為了正確使用,我們需要配置一些額外選項。
首先,我們定義Cesium所在位置。我們使用源碼,這樣我們就可以使用獨立模塊,依靠webpack可以跟蹤依賴性。其他方式是使用編譯好的(最小化壓縮或者未壓縮)版本的Cesium;可是,那些模塊已經被RequireJS optimizer 組合和優化,這種方式集成起來簡單避免犯錯,但是對於我們的優化靈活度不夠好。
在webpack.config.js,我們增加如下配置
技術分享圖片
我們選擇使用了npm 中的模塊,安裝容易一些,當然你也可以用 GitHub 庫 上的版本,或者解壓已發布版本下載。這時候僅僅需要更改cesiumSource 指向Cesium的 Source 目錄,相對 webpack.config.js 文件的相對路徑。
接著再增加一些配置項,為了解決使用webpack編譯Cesium的一些問題。

技術分享圖片
快速過下,為什麽這些配置選項需要配置。

output.sourcePrefix: ‘‘ 因為某些版本的webpack默認會在輸出的每一行的開始增加一個\t 字符。Cesium有很多多行字符串,所以我們需要使用空字符串 ‘‘來覆蓋這個選項。

amd.toUrlUndefined: true 告訴Cesium,webpack中計算 require聲明的AMD 模塊裏的toUrl 函數和標準的不兼容。

node.fs: ‘empty‘ 解決一些第三方庫使用的fs 模塊,它一般是用在NodeJS的環境裏,而不能在瀏覽器環境裏使用。
下來我們增加一個 cesium 別名(alias) ,我們就很容易的在項目裏引用,就像一個傳統的Node 模塊。
技術分享圖片
</figure>
管理Cesium 靜態文件
最後,我們確認一下Cesium的靜態資源,控件,web worker文件能被服務正確加載。
我們使用 copy-webpack-plugin,它能在編譯階段,把Cesium裏靜態文件整個拷貝到 dist 目錄下,確保我們的服務能訪問它。首先,安裝它。
技術分享圖片
下來在webpack.config.js文件最開始require它。
技術分享圖片
此外,在plugins 目錄下增加下述配置:
plugins: [
new HtmlWebpackPlugin({
template: ‘src/index.html‘
}),
// 拷貝Cesium 資源、控價、web worker到靜態目錄
new CopywebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: ‘Workers‘ } ]),
new CopywebpackPlugin([ { from: path.join(cesiumSource, ‘Assets‘), to: ‘Assets‘ } ]),
new CopywebpackPlugin([ { from: path.join(cesiumSource, ‘Widgets‘), to: ‘Widgets‘ } ])
],
我們直接拷貝了Assets和Widgets目錄。也拷貝了編譯好的 web worker腳本,他們已經使用 RequireJS optimizer編譯和優化過了。因為web woker設計就是運行在他們自己的線程裏,所以他們可以直接載入和運行。web worker很少需要調試他們原來的代碼。所以直接整個從 Build/Cesium/Workers目錄拷貝過去。
如果你用的GitHub庫的源碼,那麽這個Build目錄不存在。確認你定位到了Cesium的根目錄下,然後運行 npm run release去編譯輸出。更多信息可以查看Cesium編譯指導。
最後,我們使用DefinePlugin 定義了一個環境變量,這個告訴Cesium加載靜態文件的URL根路徑,並把它編譯到webpack裏去。最後plugins 的配置數組應該是這樣的:

plugins: [
new HtmlWebpackPlugin({
template: ‘src/index.html‘
}),
new CopywebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: ‘Workers‘ } ]),
new CopywebpackPlugin([ { from: path.join(cesiumSource, ‘Assets‘), to: ‘Assets‘ } ]),
new CopywebpackPlugin([ { from: path.join(cesiumSource, ‘Widgets‘), to: ‘Widgets‘ } ]),
new webpack.DefinePlugin({
//Cesium載入靜態的資源的相對路徑
CESIUM_BASE_URL: JSON.stringify(‘‘)
})
],
在我們的程序裏引用Cesium
現在我們的程序裏引用Cesium的獨立模塊有幾種方式。使用CommonJS的語法,以及最新的ES6的 import模塊聲明。
另外,你也可以通過一個 Cesium 引入整個Cesium庫(例如,我們在 Sandcastle中所用的方式)。你也可以只請求某個你需要的特定模塊。因為Cesium是一個巨大的庫,這種方式讓你只引用你用的特定模塊,而不是整個Cesium庫。
CommonJS 形式的 require

引用Cesium整個庫:

技術分享圖片
引用某個Cesium庫:
技術分享圖片
ES6 形式的 import
引用Cesium整個庫:
技術分享圖片
引用某個Cesium庫:
技術分享圖片
請求靜態資源文件
webpack的設計理念就是每個文件都當作一個模塊。所以導入靜態資源和導入js模塊完全相同。我們已經在loaders裏面配置了,告訴webpack每種類型的文件使用哪個loader,所以我們只需要調用 require:
技術分享圖片
Hello World! 示例
有了基本框架也學習如何引入Cesium文件,我們來創建一個簡單的Hello World程序。
再看下index.js文件。刪除它的內容,首先我們引入 Cesium,然後定義 Cesium的對象:
技術分享圖片
為了使用Cesium Viewer裏的控件,我們還需要引入Cesium的CSS:
技術分享圖片
在HTML的body部分,我們創建了一個viewer需要的div。在 index.html 文件裏,刪除 <p>Hello World!</p> 這一行,替換成下面:
技術分享圖片
最後,我們創建一個viewer的實例。返回到 index.js 文件,添加下面代碼:
技術分享圖片
當我們運行 npm start ,我們將看見瀏覽器裏的Cesium控件了。
技術分享圖片
Hello World 程序
為了美觀,我們用一些自定義css去掉頁面上的白色邊界。
創建一個新的文件src/css/main.css,增加下面的樣式:
技術分享圖片
在index.js裏require它,在其他require的後面。
技術分享圖片
重新npm start,Cesium的控件完美全屏了。

隨便拷貝粘貼 Sandcastle 中的示例。 我認為 粒子系統的示例 最能說明問題。技術分享圖片
示例程序

webpack 高級配置
webpack有很多其他方法增加性能、減小打包大小、執行額外的或者復雜的編譯過程。對於使用Cesium庫,我們將討論一些配置選項。
我們的最佳配置選項示例放在github的配置庫裏 webpack.release.config.js
代碼切片
webpack默認會把Cesium和整個程序代碼打進一個 chunk中,最終這個庫非常龐大。我們也可以用CommonChunksPlugin把Cesium打到它自己的包,提升程序的性能。如果最終你的程序創建了多個chunks,他們可以引用一個通用的cesiumchunk。
只需要在 webpack.config.js添加這個插件,然後設置打斷Cesium模塊的規則。

plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ‘cesium‘,
minChunks: module => module.context && module.context.indexOf(‘cesium‘) !== -1
})
]
這個插件最新版webpack上已經不能這麽配置了,使用config.optimization.splitChunks去設置,詳情點擊webpack-splitChunks
啟用 source maps
Source maps 允許webpack跟蹤原來代碼中的錯誤,它有很多配置項。它用編譯速度來換取或多或少的調試詳情信息。我們推薦使用‘eval‘選項,但是盡量使用你自己開發中最好的方式。
技術分享圖片
不推薦在最終產品代碼裏添加Source maps(容易被破解唄)。
刪除 pragmas
Cesium源碼裏包含了一些開發錯誤和警告信息,但是產品中是不需要的。通常我們使用 RequireJS Optimizer在release編譯下壓縮它。因為沒有webpack內置的方式去刪除這些警告,我們將使用 strip-pragma-loader。
首先,安裝。
技術分享圖片
然後在loader的 module.rules增加規則,並且 把 debug 設置為 false.
技術分享圖片
混淆和壓縮
混淆和壓縮代碼使最終產品的代碼變得更小。對於一個release編譯,Cesium會JavaScript文件,並且壓縮CSS文件。為了混淆Cesium源碼,我們使用 uglifyjs-webpack-plugin插件。
技術分享圖片
引入這個插件
技術分享圖片
在插件裏引用它
技術分享圖片
這個插件最新版webpack上已經不能這麽配置了,使用config.optimization.minimize去設置,詳情點擊webpack-optimization
為了壓縮css代碼,在css-loader中使用minimize選項。
技術分享圖片
相關資源
官方 cesium-webpack-示例 的git庫。包含最小的webpack配置,以及此篇教程的hello word代碼,還有部分可選的代碼配置選項。
學習如何基於Cesium開發項目實例,比如如何添加數據和配置樣式,那麽去學習 Cesium Workshop 教程。
玩下 Sandcastle以及官方用戶手冊。
深入學習webpack,可以看下webpack 概念 ,或者看下webpack的配置手冊 。
技術分享圖片

Cesium官方教程13--Cesium和Webpack