Cesium中級教程10
Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://cesium.coinidea.com/
webpack是打包JavaScript模組流行且強大的工具。它允許開發人員以直觀的方式構造程式碼和assets,並使用簡單的require語句根據需要載入不同型別的檔案。構建時,它將跟蹤程式碼依賴關係,並將這些模組打包到瀏覽器載入的一個或多個包中。
在本教程的前半部分,我們從頭開始建立了簡單的Web應用程式使用webpack,然後覆蓋後續步驟整合Cesium npm module。如果你喜歡使用cesiumjs開發Web應用,那麼webpack是一個好的選擇。如果您是剛接觸Cesium並且想要尋找學習構建您的第一個樣例應用,請檢視
在第二部分,我們將探索更高階的Webpack配置,以優化使用CesiumJS的應用程式。
在官方的cesium-webpack-example中可以找到優化CesiumJS webpack應用程式的完整程式碼和提示。
Prerequisites 先決條件
- 基本瞭解命令列、JavaScript和Web開發。
- 一個IDE或程式碼編輯器。Cesium團隊的開發人員使用Visual Studio Code,但是一個最小的程式碼編輯器(如Sublime文字)也完全沒有問題。
- 已安裝Node.js。我們建議使用最新的LTS版本。
Create a basic webpack app 建立基礎webpack應用
在本節中,我們將介紹如何使用webpack和開發伺服器設定基本的Web應用程式。如果您已經設定了一個應用程式,並且只想新增cesiumjs,請跳過Add CesiumJS to a webpack app。
Initialize an app with npm 使用npm初始化應用
為您的應用建立一個新的cesium-webpack。開啟控制檯,導航到新目錄,然後執行以下命令:
npm init
按照提示操作並填充有關應用程式的所有詳細資訊。按enter鍵使用預設值。這將建立package.json。
Create the app code 建立應用程式碼
為我們的應用程式程式碼建立一個src
建立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查詢包的所有javascript原始碼和依賴項的entry point起點。
建立src/index.js然後新增下列程式碼:
console.log('Hello World!');
Install and configure webpack 安裝和配置webpack
開始安裝webpack:
npm install --save-dev webpack
Configuration 配置
建立webpack.config.js以定義webpack配置物件。
const path = require('path');
const webpack = require('webpack');
module.exports = {
context: __dirname,
entry: {
app: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
}
};
context指定檔案的基本路徑。entry用於指定包。在這種情況下,app包的入口點是src/index.js。webpack將把打包後的app.js輸出到dist資料夾。
Loaders 載入
Webpack像模組一樣載入所有內容。使用loaders載入CSS和其他資產檔案。安裝style-loader、css-loader和url-loader。
npm install --save-dev style-loader css-loader url-loader
在webpack.config.js中新增兩個module.rules:一個用於css檔案,另一個用於其他靜態檔案。對於每個,test定義要載入的檔案型別,use指定載入程式的列表。
const path = require('path');
const webpack = require('webpack');
module.exports = {
context: __dirname,
entry: {
app: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}, {
test: /\.(png|gif|jpg|jpeg|svg|xml|json)$/,
use: [ 'url-loader' ]
}]
}
};
Plugins 外掛
定義index.html並使用一個名為html-webpack-plugin的webpack plugin將包注入該頁面。
npm install --save-dev html-webpack-plugin
在webpack.config.js中引用該外掛,然後將它注入到plugins。將src/index.html傳入作為我們的template。
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
context: __dirname,
entry: {
app: './src/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}, {
test: /\.(png|gif|jpg|jpeg|svg|xml|json)$/,
use: [ 'url-loader' ]
}]
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
};
配置檔案是一個javascript檔案,因此我們可以引入其他節點模組並執行操作。
Bundle the app 捆綁應用
使用package.json定義可以使用npm呼叫的指令碼。新增build命令。
"scripts": {
"build": "node_modules/.bin/webpack --config webpack.config.js"
}
此指令碼呼叫Webpack並傳遞進webpack.config.js配置檔案。
我們在這些指令碼中使用webpack和webpack-dev-server的本地安裝。這允許每個專案使用自己的單獨版本,這是webpack文件推薦的版本。如果您希望使用全域性版本,請使用npm install--global webpack全域性安裝它,並使用命令webpack--config webpack.config.js執行它。
當執行build命令時: npm run build
您應該看到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資料夾中。
Run the development server 執行開發伺服器
使用webpack-dev-server服務於開發構建然後可以在行動中看到我們的應用:
npm install --save-dev 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"
}
告訴開發伺服器為dist資料夾提供檔案。將其新增到webpack.config.js的底部。
// development server options
devServer: {
contentBase: path.join(__dirname, "dist")
}
最終,我們執行app
npm start
你應該看到你的內容在localhost:8080上呈現,看到“Hello World!“開啟瀏覽器控制檯時,顯示訊息。
Add CesiumJS to a webpack app 將CesiumJS加入到webpack應用
Install CesiumJS 安裝CesiumJS
從npmg上安裝cesium模組,並將其加入到package.json。
Configure CesiumJS in webpack 在webpack中配置CesiumJS
CesiumJS是一個龐大而複雜的庫。除了javascript模組之外,它還包括靜態資產,如css、image和json檔案。它包括Web worker檔案,以便在單獨的執行緒中執行密集計算。與傳統的npm模組不同,CesiumJS沒有定義入口點,因為庫的使用方式多種多樣。我們需要配置一些附加選項,以便與webpack一起使用。
首先,定義CesiumJS的位置。本教程基於原始碼,因此webpack可以包含單個模型並跟蹤依賴項。或者,也可以使用CesiumJS的內建(簡化或未簡化)版本。然而,這些模組已經被組合和優化,這給了我們更少的靈活性。
將下列程式碼加入到webpack.config.js的頂部:
// The path to the CesiumJS source code
const cesiumSource = 'node_modules/cesium/Source';
const cesiumWorkers = '../Build/Cesium/Workers';
將以下選項新增到配置物件,以解決webpack如何編譯CesiumJS的一些問題。
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
// Needed to compile multiline strings in Cesium
sourcePrefix: ''
},
amd: {
// Enable webpack-friendly use of require in Cesium
toUrlUndefined: true
},
node: {
// Resolve node module use of fs
fs: 'empty'
},
- output.sourcePrefix: 在每行之前新增\t製表符,以便覆蓋webpack預設值。CesiumJS有一些多行字串,因此我們需要用空字首''*覆蓋此預設值。
- amd.toUrlUndefined: true 告訴CesiumJS AMD webpack使用不符合標準toUrl函式的評估require語句的版本。
- node.fs: 'empty' 解決fs模組的某些第三方使用問題,該模組的目標是在節點環境中使用,而不是在瀏覽器中使用。
新增cesium alias,以便我們可以在應用程式程式碼中引用它。
resolve: {
alias: {
// CesiumJS module name
cesium: path.resolve(__dirname, cesiumSource)
}
},
Manage CesiumJS static files 管理CesiumJS中的靜態檔案
最後,確保靜態CesiumJS資產、小部件和web worker檔案得到正確的服務和載入。
作為構建過程的一部分,使用copy-webpack-plugin將靜態檔案複製到dist目錄。
npm install --save-dev copy-webpack-plugin
在* webpack.config.js*檔案中的上部引入:
const CopywebpackPlugin = require('copy-webpack-plugin');
並將其加入到plugins陣列中:
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
// Copy Cesium Assets, Widgets, and Workers to a static directory
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目錄以及built的web worker指令碼。
如果您使用的是CesiumJS倉庫的fork,那麼Build資料夾將不存在。執行npm run release生成輸出資料夾。有關詳細資訊,請參閱《Cesium生成指南》。
定義一個環境變數,該變數告訴CesiumJS使用webpackDefinePlugin載入靜態檔案的基本URL。plugins陣列現在將如下所示:
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
// Copy Cesium Assets, Widgets, and Workers to a static directory
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({
// Define relative base path in cesium for loading assets
CESIUM_BASE_URL: JSON.stringify('')
})
],
Require CesiumJS modules in our app 在應用中引用CesiumJS模組
在我們的應用程式中,有幾種方法可以引用CesiumJS模組。您可以使用CommonJS語法或ES6import語句。
您可以匯入整個CesiumJS庫,或者只需要引入您需要的特定模組。引入模組將導致webpack只編譯包中的那些模組及其依賴項,而不是整個庫。
CommonJS style require
引入所有的CesiumJS:
var Cesium = require('cesium/Cesium');
var viewer = new Cesium.Viewer('cesiumContainer');
引入獨立模組
var Color = require('cesium/Core/Color');
var color = Color.fromRandom();
ES6風格匯入
引入所有的CesiumJS:
import Cesium from 'cesium/Cesium';
var viewer = new Cesium.Viewer('cesiumContainer');
引入獨立模組
import Color from 'cesium/core/Color';
var color = Color.fromRandom();
Requiring asset files 引用asset檔案
webpack背後的原理是,每個檔案都被視為一個模組。這使得匯入資產與包括javascript相同。我們告訴Webpack如何使用載入器載入配置中的每種型別的檔案,所以我們只需要呼叫require。
require('cesium/Widgets/widgets.css');
Hello World!
建立一個新的檔案,src/css/main.css,為了樣式化我們的應用:
html, body, #cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
建立一個div用於index.html body中的CesiumJS Viewer。替換*<p>Hello World!</p>*使用下面的div:
<div id="cesiumContainer"></div>
刪除index.js中的內容幷包含Cesium和我們的CSS檔案:
var Cesium = require('cesium/Cesium');
require('./css/main.css');
require('cesium/Widgets/widgets.css');
為建立Viewer新增一行程式碼:
var viewer = new Cesium.Viewer('cesiumContainer');
使用npm start執行應用用於在瀏覽器中檢視Viewer。
複製並貼上你最喜歡的Sandcastle例子。例如,粒子系統例項可以得出一個很好的結論。
Advanced webpack configurations 高階webpack配置
webpack可以通過更多方式提高效能、減小包大小以及執行其他或複雜的構建步驟。在這裡,我們將討論一些與使用CesiumJS庫相關的配置選項。
在webpack.release.config.js的倉庫示例中可以找到優化生產Cesium webpack構建的配置。
Code splitting 程式碼分割
預設情況下,webpack將CesiumJS打包在與我們的應用程式相同的塊中,從而生成一個大檔案。我們可以將CesiumJS拆分成自己的包,並使用CommonChunksPlugin提高我們的應用程式效能。如果你最終為你的應用程式建立了多個塊,它們都可以引用一個常見的cesium塊。
將外掛新增到webpack.config.js檔案中,並指定分解CesiumJS模組的規則:
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'cesium',
minChunks: module => module.context && module.context.indexOf('cesium') !== -1
})
]
Enable source maps 啟用源對映
源對映允許Webpack將錯誤跟蹤回原始內容。它們提供或多或少詳細的除錯資訊,以換取編譯速度。我們建議使用*'eval'*選項。
devtool: 'eval'
在生產產品中,不推薦使用源對映。
Remove pragmas 移除編譯指令
CesiumJS原始碼中存在開發人員錯誤和警告,這些錯誤和警告已從我們的小型釋出版本中刪除。由於沒有內建的Webpack方法來刪除這些警告,因此我們將使用strip-pragma-loader。
安裝包:
npm install strip-pragma-loader --save-dev
在module.rules中將debug設為false,引入載入器:
rules: [{
// Strip cesium pragmas
test: /\.js$/,
enforce: 'pre',
include: path.resolve(__dirname, cesiumSource),
use: [{
loader: 'strip-pragma-loader',
options: {
pragmas: {
debug: false
}
}
}]
}]
Uglify and minify 混淆與壓縮
增刪和縮小程式碼允許在生產中使用較小的檔案大小。對於一個釋出版本,CesumJS會修改JavaScript檔案並縮小CSS檔案。
使用uglifyjs-webpack-plugin用於混淆CesiumJS原始碼。
npm install uglifyjs-webpack-plugin --save-dev
在配置檔案中引入他:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
在外掛列表中包含他:
plugins: [
new webpack.optimize.UglifyJsPlugin()
]
在css-loader上使用minimize選項用於優化CSS。
module: {
rules: [{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
// minify loaded css
minimize: true
}
}
]
}]
}
Resources 資源
官方的cesium-webpack-example倉庫包含最小webpack配置、本教程中介紹的Hello World程式碼以及可選程式碼配置的說明。
有關要包含在新應用程式中的CesiumJS功能的教程,請參閱Cesium Workshop教程。
在[Sandcastle]中探索例項,並檢視CesiumJS文件
要了解有關webpack的更多資訊,請檢視webpack概念,或深入閱讀文件。
Cesium中文網交流QQ群:807482793
Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://ces