Webpack 是一个颇受欢迎且功能强大的JavaScript模块打包工具。它允许开发者以一种直观的方式来构建代码和资源,并能够根据需要使用简单的 require 语句来加载不同类型的文件。在构建过程中,Webpack 会追踪代码之间的依赖关系,并将它们打包成一个或多个由 Web 浏览器加载的包。如果想利用 CesiumJS 开发更加高级的 Web 应用,本教程将是个不错的起点。如果是刚开始接触 Cesium 并且想学习构建您的第一个样例应用,请查看我们的入门教程。
在本教程中,您将学习到:
- 如何从零开始使用Webpack构建一个简易的Web应用;
- 如何将Cesium npm包集成到你的Web应用中。
前提条件
- 对命令行、JavaScript 和 Web 开发有基本的了解;
- 计算机中已安装 Node.js。建议使用最新的LTS版本。
通过 npm 初始化应用
- 创建一个新的目录来存放您的应用程序。
- 打开 terminal(控制台窗口)并导航至该目录。
- 执行
npm init命令,并按照提示输入应用程序相关信息。如果某些提示您不确定如何回答,直接按Enter键接受默认值即可。您可以随时修改npm init创建的package.json文件中的信息。
编写应用程序代码
- 创建一个名为
src的目录来放置您的应用代码。在构建应用时,Webpack 会自动在一个名为dist的目录中生成打包后的文件。 - 在步骤1所创建的
src目录中,新建index.html和index.js文件。 - 在
src/index.html中添加以下代码,作为我们起步的HTML页面模板:<!doctype html> <html> <head> <meta charset="utf-8" /> </head> <body> <p>你好,世界!</p> </body> </html> - 在
src/index.js中添加以下内容,作为起始的JavaScript代码模板:console.log("Hello World!"); - 创建一个
src/css/main.css文件,并添加以下CSS代码:html, body, #cesiumContainer { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; }
安装和配置Webpack
-
通过执行
npm install --save-dev webpack命令来安装 Webpack。这将在您的主目录中生成package-lock.json和package.json文件。同时,您的主目录中还会多出一个名为node_modules的新文件夹。 -
在主目录中新建一个
webpack.config.js文件。 -
通过在
webpack.config.js中加入以下代码来定义Webpack配置对象:const path = require("path"); const webpack = require("webpack"); module.exports = { context: __dirname, entry: { app: "./src/index.js", }, output: { filename: "app.js", path: path.resolve(__dirname, "dist"), }, };以上代码中
context指定了文件的基本路径;entry用来定义入口,其中src/index.js是我们的入口文件。Webpack将会输出名为app.js的打包文件到运行时创建的dist文件夹中。 -
Webpack 将所有资源视作模块进行加载。通过使用 loaders 我们可以加载 CSS 和其他资源文件。运行
npm install --save-dev style-loader css-loader url-loader命令来安装 style-loader、css-loader 和 url-loader。根据需要,您还可以安装任何未来可能用到的其他loader。这些loader可以在整个过程中的任何时刻被安装。 -
更新
webpack.config.js,向其中添加两个module.rules规则。第一个规则用于处理CSS文件,第二个规则用于管理其他静态文件。为每个规则定义一个test参数来指定需要加载的文件类型,以及一个use列表来指定使用的loader。更新后的webpack.config.js应该如下所示:const path = require("path"); const webpack = require("webpack"); module.exports = { context: __dirname, entry: { app: "./src/index.js", }, output: { filename: "app.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"], }, ], }, }; -
若要将
index.html定义为模板,并将我们的打包文件注入该页面,需要使用一个名为 html-webpack-plugin 的Webpack插件。使用命令npm install --save-dev html-webpack-plugin来安装这个插件。 -
在
webpack.config.js的plugins部分引入html-webpack-plugin,并将src/index.html设为模板。最后,在webpack.config.js中添加mode: 'development'来指定Webpack的模式为开发模式。此时的webpack.config.js看起来应该像这样: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: "app.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", }), ], mode: "development", };
打包应用程序
-
在项目的
package.json文件中定义可以通过npm运行的脚本命令,这里需要添加一个用于构建项目的build命令:"scripts": { "build": "node_modules/.bin/webpack --config webpack.config.js" }完成后,您的
package.json文件应该如下所示:{ "name": "cesiumjs-webpack-tutorial", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "node_modules/.bin/webpack --config webpack.config.js" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^6.2.0", "html-webpack-plugin": "^5.3.2", "style-loader": "^3.2.1", "url-loader": "^4.1.1", "webpack": "^5.50.0" } }请注意,本文件的具体内容会根据您在 通过 npm 初始化应用 中第3步所做的选择而有所不同。
-
运行命令
npm run build。如需安装 Webpack CLI,请使用命令npm install --save-dev webpack-cli。 -
如果没有错误,您的输出应类似于以下内容:
$ npm run build > cesiumjs-webpack-tutorial@1.0.0 build > node_modules/.bin/webpack --config webpack.config.js asset app.js 1.22 KiB [emitted] (name: app) asset index.html 376 bytes [emitted] ./src/index.js 28 bytes [built] [code generated] webpack 5.50.0 compiled successfully in 86 ms请确认
app.js和index.html文件已被添加到dist文件夹中。
运行开发服务器
-
为了提供开发构建并预览应用,您可以使用 webpack-dev-server 。首先,通过运行
npm install --save-dev webpack-dev-server来安装它。 -
接着,在
package.json文件中新增一个start脚本来运行开发服务器。注意,需要通过--config标志指定配置文件,同时使用--open标志来确保执行命令后浏览器会自动打开应用。更新后的package.json应如下所示:{ "name": "cesiumjs-webpack-tutorial", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "node_modules/.bin/webpack --config webpack.config.js", "start": "node_modules/.bin/webpack serve --config webpack.config.js --open" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^6.2.0", "html-webpack-plugin": "^5.3.2", "style-loader": "^3.2.1", "url-loader": "^4.1.1", "webpack": "^5.50.0", "webpack-cli": "^4.7.2", "webpack-dev-server": "^3.11.2" } } -
执行
npm start后,浏览器会自动打开http://localhost:8080/,您应该能看到一个渲染了 "你好,世界!" 的页面。
将 CesiumJS 集成到 Webpack 应用中
CesiumJS 是一个功能强大的开源 JavaScript 库,专为构建 3D 地球和地图而设计。它的功能复杂且内容丰富,不仅包含 JavaScript 模块,还包含了CSS、图像、json 文件等多种静态资源。此外,CesiumJS 还引入了Web Worker,以支持在不同线程中处理计算密集型任务。与传统的 npm 模块相比,CesiumJS 没有设置一个明确的 entry(入口),因此,在利用 webpack 进行项目构建时,您需要进行一些额外的配置。
首先,需要明确指出 CesiumJS 的位置。本教程通过源代码的方式引入 Cesium,这样 webpack 就可以识别库中包含的模块,并追踪它们之间的依赖关系。当然,您也可以使用 CesiumJS 的构建版本(已压缩或未压缩)。但需要注意的是,已构建的模块是预先打包和优化过的,这可能会在一定程度上限制您的灵活使用。
安装CesiumJS
- 通过命令
npm install --save-dev cesium安装Cesium模块。 - 更新您的
webpack.config.js来解决 CesiumJS 与 webpack 使用的 AMD 不兼容的问题,并添加一个cesium别名以便在应用程序代码中引用它。添加这些更改后,webpack.config.js应如下所示:// CesiumJS源码的路径 const cesiumSource = "node_modules/cesium/Source"; const cesiumWorkers = "../Build/Cesium/Workers"; 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: "app.js", path: path.resolve(__dirname, "dist"), // 编译Cesium中多行字符串所需 sourcePrefix: '', }, amd: { // 允许webpack友好地使用Cesium中的require toUrlUndefined: true, }, resolve: { alias: { cesium: path.resolve(__dirname, cesiumSource), }, mainFiles: ['index', 'Cesium'], }, 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", }), ], mode: "development", };
管理 CesiumJS 静态文件
为了确保 CesiumJS 的静态资源、Widgets 和 Web Worker 文件能正确加载,您需要使用 copy-webpack-plugin 将这些静态文件复制到 dist 目录中。
首先,通过运行 npm install --save-dev copy-webpack-plugin 安装插件。随后,您需要在 webpack.config.js 中配置该插件,以确保 Cesium 的 Assets、Widgets 和 Workers 被正确复制到 dist 目录中。更新后的webpack.config.js应该如下所示:
// CesiumJS源代码的路径
const cesiumSource = "node_modules/cesium/Source";
const cesiumWorkers = "../Build/Cesium/Workers";
const CopyWebpackPlugin = require("copy-webpack-plugin");
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: "app.js",
path: path.resolve(__dirname, "dist"),
sourcePrefix: "",
},
amd: {
// 使webpack能够以友好的方式使用Cesium中的require
toUrlUndefined: true,
},
resolve: {
alias: {
cesium: path.resolve(__dirname, cesiumSource),
},
mainFiles: ["index", "Cesium"],
},
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",
}),
// 将Cesium的Assets、Widgets和Workers复制到一个静态目录
new CopyWebpackPlugin({
patterns: [
{ from: path.join(cesiumSource, cesiumWorkers), to: "Workers" },
{ from: path.join(cesiumSource, "Assets"), to: "Assets" },
{ from: path.join(cesiumSource, "Widgets"), to: "Widgets" },
],
}),
new webpack.DefinePlugin({
// 在cesium中定义相对的基路径用于加载资源
CESIUM_BASE_URL: JSON.stringify(""),
}),
],
mode: "development",
};
将 CesiumJS 集成到应用中
-
更新您的
index.js来启动 CesiumJS,如初始化视图器、添加地形、创建 OSM Buildings 和定位相机至特定位置等。import { Ion, Viewer, Terrain, createOsmBuildingsAsync, Cartesian3, Math, } from "cesium"; import "cesium/Widgets/widgets.css"; import "../src/css/main.css"; // 你的访问令牌可以在 https://cesium.com/ion/tokens 找到。 // Ion.defaultAccessToken = "你的令牌在这里"; // 在ID为`cesiumContainer`的HTML元素中初始化Cesium Viewer。 const viewer = new Viewer("cesiumContainer", { terrain: Terrain.fromWorldTerrain(), }); // 添加Cesium OSM Buildings,一个全球性的3D建筑层。 const buildingTileset = await createOsmBuildingsAsync(); viewer.scene.primitives.add(buildingTileset); // 将相机飞向给定经纬度和高度的旧金山。 viewer.camera.flyTo({ destination: Cartesian3.fromDegrees(-122.4175, 37.655, 400), orientation: { heading: Math.toRadians(0.0), pitch: Math.toRadians(-15.0), }, });上述代码演示了如何利用 CesiumJS 创建一个场景,在地形上添加Cesium OSM Buildings,并将视图定位至旧金山。
-
更新
index.html,添加 CesiumContainer<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> </head> <body> <div id="cesiumContainer"></div> </body> </html> -
运行
npm run build,确保项目被正确构建。 -
使用
npm start运行您的应用,并在浏览器中打开 http://localhost:8080/ 查看集成了 CesiumJS 的效果。
您可以随意复制并粘贴您最喜爱的Sandcastle示例。例如,许多社区成员都喜欢的Cesium OSM Buildings演示。
高级 Webpack 配置及其他资源
Webpack 是一个强大的模块打包工具,它提供了一系列高级功能,可帮助提升应用的性能,减小包的体积,并实现复杂的构建过程。在此部分,我们将专门讨论一些与集成 CesiumJS 库时相关的高级配置选项。
启用 Source Maps
源映射(Source Maps)功能允许 Webpack 追溯编译后的代码中的错误和警告到其原始源代码,为开发者提供了丰富的调试信息。要在开发过程中充分利用这项功能以提高调试效率,我们推荐在 webpack.config.js 文件中将 devtool 选项设置为 eval。这项设置可以加快编译速度并优化开发体验:
devtool: 'eval'
然而,请注意,在生产环境中慎用源映射,以避免潜在的性能影响及安全问题。
其他资源
Cesium 官方提供的 cesium-webpack-example 仓库包含了对于初学者而言的最小 Webpack 配置以及本教程所涉及的基础代码示例。
您可以通过 CesiumJS 教程 来深入学习 CesiumJS 的各种功能和使用方式。此外,强烈推荐您探索 Sandcastle 示例库,它提供了丰富的案例,帮助您理解并掌握 CesiumJS 在实际应用中的强大能力。
如果您想进一步掌握 Webpack 的细节与高级特性,请参阅 Webpack 官方入门指南,这是学习基础知识的绝佳起点。对于那些希望深入理解其强大功能的用户来说,Webpack 的 API 文档 提供了详尽的信息和指引。