Cesium中級教程10 - CesiumJS and webpack


Cesium中文網:http://cesiumcn.org/ | 國內快速訪問:http://cesium.coinidea.com/
webpack是打包JavaScript模塊流行且強大的工具。它允許開發人員以直觀的方式構造代碼和assets,並使用簡單的require語句根據需要加載不同類型的文件。構建時,它將跟蹤代碼依賴關系,並將這些模塊打包到瀏覽器加載的一個或多個包中。

在本教程的前半部分,我們從頭開始建立了簡單的Web應用程序使用webpack,然后覆蓋后續步驟集成Cesium npm module。如果你喜歡使用cesiumjs開發Web應用,那么webpack是一個好的選擇。如果您是剛接觸Cesium並且想要尋找學習構建您的第一個樣例應用,請查看Getting Started Turtorial

在第二部分,我們將探索更高級的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目錄。當我們構建應用程序時,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查找包的所有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-loadercss-loaderurl-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

> test-app@1.0.0 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';

本教程使用npm模塊以便於安裝,但您也可以克隆Github倉庫或下載解壓使用release版本

將以下選項添加到配置對象,以解決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' } ])
    ],

這將復制AssetsWidgets目錄以及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。替換

Hello World!

使用下面的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://cesium.coinidea.com/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM