找回密码
 立即注册
查看: 329|回复: 0

Cesium中文教程-Cesium and Webpack

[复制链接]
发表于 2023-4-10 16:40 | 显示全部楼层 |阅读模式
目录
前提条件(Prerequisites)
创建一个基本webpack应用(Create a basic webpack app)
使用npm初始化应用程序(Initialize an app with npm)
创建应用程序代码(Create our application code)
安装和配置webpack(Install and configure webpack)
打包应用程序(Bundle the app)
运行开发服务器(Run the development server)
向webpack应用程序添加Cesium(Add Cesium to a webpack app)
安装Cesium(Install Cesium)
webpack中配置Cesium
管理Cesium静态文件(Manage Cesium static files)
Require Cesium modules in our app
Requiring asset files
Hello World!
高级webpack配置
代码分离(Code Splitting)
Enable source maps
Remove pragmas
Uglify and minify
资源(Resources)
附件
目录变更
最新目录结构

Webpack是一款受欢迎和功能强大的JavaScript模块打包工具。它允许开发人员以一种直观的方式构造他们的代码和资产,并根据需要使用简单的require语句加载不同类型的文件。当构建的时候,它将追踪代码依赖,并将这些模块打包到浏览器加载的一个或多个包中。
本教程前半部分,我们将使用webpack从头开始构建一个简单的web应用程序,然后介绍Cesium npm module的步骤。如果你想使用Cesium来开发web应用程序,那么这是一个很好的起点,但是对于使用Cesium入门的更简单示例,请参阅我们的入门教程(Getting Started Tutorial)。在第二部分,我们将探索使用Cesium优化应用程序的更高级webpack配置。
完整的应用程序及优化Cesium和webpack应用程序的技巧可以在cesium-webpack-example仓库中找到。
前提条件(Prerequisites)


  • 基本了解命令行、JavaScript和web开发;
  • 一个IDE或代码编辑器。Cesium开发团队人员使用Webstorm,但是最小化代码编辑器(例如Sublime Text)也可以工作;
  • Node.js安装,LTS版本是一个很好的起点,但是任何版本6或以上都可以工作。
创建一个基本webpack应用(Create a basic webpack app)

在第一部分,我们将描述如何使用webpack和开发服务器设置基本的web应用程序。如果你已经创建了一个web应用,只是想添加Cesium,可以跳到Add Cesium to a webpack app。
使用npm初始化应用程序(Initialize an app with npm)

为应用程序创建一个新的文件夹,让我们称为cesium-webpack-app。在当前目录下打开终端并运行一下命令:
  1. npm init
复制代码
按要求填写应用程序的描述。按回车键使用默认设置,所有的这些都适用于此应用程序。这将创建我们的package.json文件。
创建应用程序代码(Create our application code)

为我们的“source”创建一个src目录。这个目录将用于存放应用程序的代码,这些是我们需要编辑的文件。当创建的时候,webpack将在dist目录中生成输出或“distribution”文件。
在src下创建index.html文件,在文件中添加如下HTML模板页。
  1. <!DOCTYPE html>  
  2. <html>  
  3.   <head>  
  4.     <meta charset="utf-8">  
  5.     <meta http-equiv="X-UA-Compatible" content="IE=edge">  
  6.     <meta name="viewport"  
  7.       content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">  
  8.     <title>Hello World!</title>  
  9.   </head>  
  10.   <body>  
  11.     <p>Hello World!</p>  
  12.   </body>  
  13. </html>  
复制代码
现在需要为应用程序创建一个entry point。这将告诉webpack开始包含所有源代码和依赖项的地方。然后,这个包将被加载到我们的index.html文件中。
为了简单,创建一个新文件src/index.js,并向里添加一个快速行,这样我们就知道一切正常。
  1. console.log('Hello World!');  
复制代码
安装和配置webpack(Install and configure webpack)

让我们从安装webpack开始。
  1. npm install --save-dev webpack
复制代码
    Configuration
创建一个新的文件,叫webpack.config.js。在这里,我们将定义webpack配置(configuration)对象,之后将其传递给编辑器。
  1. const path = require('path');  
  2.   
  3. const webpack = require('webpack');  
  4.   
  5. module.exports = {  
  6.     context: __dirname,  
  7.     entry: {  
  8.         app: './src/index.js'  
  9.     },  
  10.     output: {  
  11.         filename: '[name].js',  
  12.         path: path.resolve(__dirname, 'dist'),  
  13.     }  
  14. };  
复制代码
首先,我们需要获取Node的路径,以及我们刚刚安装的webpac模块。在配置中,我们将告诉webpack基础路径内容是什么,并提供节点全局变量_dirname来指定该文件的位置。我们指定我们的entry到src/index.js,称为app。我们将告诉webpack输出打包文件(由于我们指定使用entry[name],所以将命名为app.js)到dist文件夹。然后导出这个对象,使其可以在任何地方使用。
    Loaders
我们还需要一种加载css文件和其它资产文件的方法。Webpack可以让我们像加载模块一样,加载任何东西,其使用loaders完成。我们将使用style-loader,css-loader和url-loader。
  1. npm install --save-dev style-loader css-loader url-loader  
复制代码
回到开始向webpack.config.js文件中添加module.rules。我们将添加两个规则,一个是为css文件,另一个是为其它静态文件。对于这两种方法,我们将定义一个test,用于测试我们希望用该加载器加载的文件类型,以及一个用于指定加载器列表的数组。
  1. const path = require('path');  
  2.   
  3. const webpack = require('webpack');  
  4.   
  5. module.exports = {  
  6.     context: __dirname,  
  7.     entry: {  
  8.         app: './src/index.js'  
  9.     },  
  10.     output: {  
  11.         filename: '[name].js',  
  12.         path: path.resolve(__dirname, 'dist'),  
  13.     },  
  14.     module: {  
  15.         rules: [{  
  16.             test: /\.css$/,  
  17.             use: [ 'style-loader', 'css-loader' ]  
  18.         }, {  
  19.             test: /\.(png|gif|jpg|jpeg|svg|xml|json)$/,  
  20.             use: [ 'url-loader' ]  
  21.         }]  
  22.     }  
  23. };  
复制代码
    插件(Plugins)
我们正在创建一个web应用程序,所以需要定义index.html文件并将我们的打包文件注入到该页面。我们将使用html-webpack-plugin插件(plugin)来实现这一点。
  1. npm install --save-dev html-webpack-plugin  
复制代码
需要插件在webpack.config.js文件顶部,并添加其到plugin。我们将通过src/index.html作为模板,webpack将把打包文件的引用注入到页面主体中。
  1. const path = require('path');  
  2.   
  3. const webpack = require('webpack');  
  4. const HtmlWebpackPlugin = require('html-webpack-plugin');  
  5.   
  6. module.exports = {  
  7.     context: __dirname,  
  8.     entry: {  
  9.         app: './src/index.js'  
  10.     },  
  11.     output: {  
  12.         filename: '[name].js',  
  13.         path: path.resolve(__dirname, 'dist'),  
  14.     },  
  15.     module: {  
  16.         rules: [{  
  17.             test: /\.css$/,  
  18.             use: [ 'style-loader', 'css-loader' ]  
  19.         }, {  
  20.             test: /\.(png|gif|jpg|jpeg|svg|xml|json)$/,  
  21.             use: [ 'url-loader' ]  
  22.         }]  
  23.     },  
  24.     plugins: [  
  25.         new HtmlWebpackPlugin({  
  26.             template: 'src/index.html'  
  27.         })  
  28.     ]  
  29. };  
复制代码
注意:请记住,配置文件只是一个JavaScript文件,因此我们可以加入其它节点模块并执行其操作。
打包应用程序(Bundle the app)

我们将定义一些使用package.json作为输入输出的npm,且很容易调用的脚本。可以任意删除默认的测试脚本,因为我们在这里不使用它。让我们添加build命令。
  1. "scripts": {  
  2.   "build": "node_modules/.bin/webpack --config webpack.config.js"  
  3. }  
复制代码
这个脚本只是调用webpack并传入我们创建的webpack.config.js配置文件。
注意:我们在这些脚本中使用webpack的本地安装和webpac-dev-server。这允许每个项目使用自己独立的版本,这也是webpack documentation推荐的。如果你喜欢使用全局版,请使用npm install --global webpack安装它,并使用命令webpack --config webpack.config.js运行。
当你运行编译命令时,
  1. npm run build
复制代码
应该会看到webpack的一些输出是这样开始的:
  1. npm run build  
  2.   
  3. > test-app@1.0.0 build C:\workspace\test-app  
  4. > node_modules/.bin/webpack --config webpack.config.js  
  5.   
  6. Hash: 2b42bff7a022b5d956a9  
  7. Version: webpack 3.6.0  
  8. Time: 2002ms  
  9.                                         Asset       Size  Chunks                    Chunk Names  
  10.      Assets/Textures/NaturalEarthII/2/0/3.jpg    10.3 kB          [emitted]  
  11.                                        app.js     162 kB       0  [emitted]         app  
复制代码
app.js打包文件和index.html文件将输出到dist文件夹。这些文件可以作为web应用程序提供。
运行开发服务器(Run the development server)

这不是很令人振奋。让我们使用webpack-dev-server来快速构建一个开发版本,并查看应用程序的运行情况。
首先,安装webpack-dev-server及其依赖。
  1. npm install --save-dev webpack-dev-server
复制代码
接下来,向packa.json中添加另一脚本。我们将使用start命令来运行开发服务,像build命令一样通过—config标识传递config文件。我们将传递可选择项—open标识,以便在运行命令时在浏览器中打开应用程序。
  1. "scripts": {  
  2.   "build": "node_modules/.bin/webpack --config webpack.config.js",  
  3.   "start": "node_modules/.bin/webpack-dev-server --config webpack.config.js --open"  
  4. }  
复制代码
我们需要告诉开发服务器从哪里提供文件。这与我们放置webpack输出文件夹相同,在本例中是dist。将其添加到webpack配置文件webpack.config.js的底部。
  1. // development server options  
  2. devServer: {  
  3.     contentBase: path.join(__dirname, "dist")  
  4. }  
复制代码
最后,我们运行app。
  1. npm start  
复制代码
你应该可以看到在localhost:8080上提供的内容,如果打开控制台,你应该看到我们的“Hello World!”信息打印在那里。




向webpack应用程序添加Cesium(Add Cesium to a webpack app)

现在我们有了一个使用webpack运行的基本应用程序,让我们来进入有意思的部分,加入Cesium。
安装Cesium(Install Cesium)

从npm中安装cesium模块,并添加到package.json文件作为依赖包。
  1. npm install --save-dev cesium  
复制代码
webpack中配置Cesium

Cesium是一个庞大和复杂的程序库。除了JavaScript模块之外,其也包含有静态资产,例如css、图片和json文件。它包含用于另一线程中执行密集计算的web worker文件。不像传统的npm模块,Cesium并没有定义一个入口点,因为库的使用方式多种多样。为了正确使用它,我们需要配置一些附加选项。
首先,需要定义Cesium的位置。我们将使用源代码,这允许我们使用单独的模块,并通过利用webpack来跟踪依赖关系。另一种是使用Cesium的build(缩小或未缩小)版本。然而,这些模块已经使用RequireJS optimizer进行了组合和优化,其为简单集成带来了一些问题,同时也降低了我们自己优化的灵活性。
在webpack.config.js中,在配置对象上面添加以下内容:
  1. // The path to the Cesium source code  
  2. const cesiumSource = 'node_modules/cesium/Source';  
  3. const cesiumWorkers = '../Build/Cesium/Workers';  
复制代码
注意:虽然为了便于安装,我们选择使用npm模块。但是你可以使用GitHub repository或者解压缩的版本下载。只需要将cesiumSource更新为Cesium Source目录相对于webpack.config.js文件的位置。
接下来,我们将向配置对象添加以下选项,以解决webpack如何编译Cesium的问题。
  1. output: {  
  2.     filename: '[name].js',  
  3.     path: path.resolve(__dirname, 'dist'),  
  4.   
  5.     // Needed to compile multiline strings in Cesium  
  6.     sourcePrefix: ''  
  7. },  
  8. amd: {  
  9.     // Enable webpack-friendly use of require in Cesium  
  10.     toUrlUndefined: true  
  11. },  
  12. node: {  
  13.     // Resolve node module use of fs  
  14.     fs: 'empty'  
  15. },  
复制代码
让我们快速看下这些单独配置选型的原因以及为什么包含它们:

  • output.sourcePrefix:’’因为webpack的一些版本,默认输出时在每行前添加\t tab字符。Cesium有多行字符串的实例,所以我们需要用空前缀覆盖这个默认值;
  • amd.toUrlUndefined:true 告诉Cesium,AMD webpack用于评估require语句的版本不符合标准的toUrl函数;
  • node.fs:‘empty’解决对fs模块的第三方使用,其目标是在节点环境中而不是浏览器中使用。
接下来添加cesium的别名,以便在应用程序代码中像传统节点模块一样方便应用它。
  1. resolve: {  
  2.     alias: {  
  3.         // Cesium module name  
  4.         cesium: path.resolve(__dirname, cesiumSource)  
  5.     }  
  6. },
复制代码
管理Cesium静态文件(Manage Cesium static files)

最后,我们要确保静态资产、部件和web工作文件得到了正确的服务和加载。将使用copy-webpack-plugin,其允许我们作为构建处理的一部分,去复制Cesium静态文件到dist目录中,以便为它们提供服务。先安装它:
  1. npm install --save-dev copy-webpack-plugin  
复制代码
然后在webpack.config.js顶部require它。
  1. const CopywebpackPlugin = require('copy-webpack-plugin');  
复制代码
另外,添加如下到plugins数组。
  1. plugins: [  
  2.     new HtmlWebpackPlugin({  
  3.         template: 'src/index.html'  
  4.     }),  
  5.     // Copy Cesium Assets, Widgets, and Workers to a static directory  
  6.     new CopywebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' } ]),  
  7.     new CopywebpackPlugin([ { from: path.join(cesiumSource, 'Assets'), to: 'Assets' } ]),  
  8.     new CopywebpackPlugin([ { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' } ])  
  9. ],  
复制代码
我们按原样复制资产和小部件目录。此外,我们使用build web worker脚本,其已经使用RequireJS optimizer编译和优化过。由于web workers被设计成在自己的线程中单独运行,它们可以按原样加载和运行。Web workers很少(有的话)以其原始形式进行调试。我们将从Build/Cesium/Workers目录中复制这些内容。
注意:如果你把Cesium指向GitHub仓库的克隆,那build文件夹将不存在。确保导航到基本Cesium目录,并运行npm run release来生成构建输出。有关更多信息,请参见Cesium Build Guide。
最后,我们定义一个环境变量,其告诉Cesium使用webpack内置的DefinePlugin加载静态文件的基本URL。plugins数组看起来像这样:
  1. plugins: [  
  2.     new HtmlWebpackPlugin({  
  3.         template: 'src/index.html'  
  4.     }),  
  5.     // Copy Cesium Assets, Widgets, and Workers to a static directory  
  6.     new CopywebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' } ]),  
  7.     new CopywebpackPlugin([ { from: path.join(cesiumSource, 'Assets'), to: 'Assets' } ]),  
  8.     new CopywebpackPlugin([ { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' } ]),  
  9.     new webpack.DefinePlugin({  
  10.         // Define relative base path in cesium for loading assets  
  11.         CESIUM_BASE_URL: JSON.stringify('')  
  12.     })  
  13. ],  
复制代码
Require Cesium modules in our app

现在有几种不同的方式可以在应用程序中requireCesium以及单独Cesium模块。有CommonJS语法,以及ES6模块使用的新import语句。
此外,你可以在一个Cesium对象(例如,在Sandcastle中那样)中导入整个Cesium库。你也可以只要求自己需要的模块。由于Cesium库如此大,这允许只包含指定的模块及其依赖,而不是包含整个Cesium库。
CommonJS格式的require
要求所有Cesium库在一个对象下:
  1. var Cesium = require('cesium/Cesium');  
  2. var viewer = new Cesium.Viewer('cesiumContainer');  
复制代码
要求单独的模块:
  1. var Color = require('cesium/Core/Color');  
  2. var color = Color.fromRandom();  
复制代码
ES6格式的import
在一个对象下要求所有Cesium库:
  1. import Cesium from 'cesium/Cesium';  
  2. var viewer = new Cesium.Viewer('cesiumContainer');  
复制代码
要求一个单独的模块:
  1. import Color from 'cesium/core/Color';  
  2. var color = Color.fromRandom();  
复制代码
Requiring asset files

Webpack背后的原理是,每个文件都被当作一个模块来对待。这使得导入资产与包含JavaScript模块完全相同。我们已经告诉webpack如何使用加载器加载配置文件中的每种类型的文件,所以我们只需要调用require。
  1. require('cesium/Widgets/widgets.css');
复制代码
Hello World!

现在,我们已经设置好了环境,并且知道了如何包含Cesium文件,让我们来创建一个简单的Hello World示例。
再看一下index.js文件,删除其内容。首先,我们将包含Cesium,接着定义Cesium对象:
  1. var Cesium = require('cesium/Cesium');  
复制代码
为了使用Cesium视图部件,我们需要包含它的CSS:
  1. require('cesium/Widgets/widgets.css');  
复制代码
在HTMLbody中,我们将为查看器创建一个div。在index.html文件,去掉<p>Hello World!</p>行并换成:
  1. <div id="cesiumContainer"></div>
复制代码
最后,我们创建一个viewer实例,返回index.js添加一行:
  1. var viewer = new Cesium.Viewer('cesiumContainer');  
复制代码
当我们使用npm start运行应用程序时,我们会在浏览器中看到Cesium Viewer。


为了看起来清爽,我们通过包含一些自己定义的css来清除掉白色边框。创建一个新文件,src/css/main.css,添加如下样式:
  1. html, body, #cesiumContainer {  
  2.     width: 100%;  
  3.     height: 100%;  
  4.     margin: 0;  
  5.     padding: 0;  
  6.     overflow: hidden;  
  7. }  
复制代码
在你的index.js文件中包含它,另一个需要声明:
  1. require('./css/main.css');  
复制代码
再次启动应用程序,你将看到查看器全屏显示效果。


你可以随意复制和粘贴自己最喜欢的Sandcastle示例。我认为粒子系统(The Particle System)的粒子是一个很好的选择。


高级webpack配置

Webpack可以通过许多方式来提高性能、减少包大小和执行额外的或复杂的构建步骤。这里我们将讨论一些与使用Cesium库相关的配置选项。
注意:对于最优化生产Cesium webpack build的配置可以在我们的示例仓库webpack.release.config.js中找到。
代码分离(Code Splitting)

Webpack默认情况下会将Cesium打包到与应用程序相同的块(chunk)中,这最终会变得很大。我们可以使用CommonChunkPlugin将Cesium分离成它自己的包,从而提高应用程序的性能。如果你最终为应用程序创建多个快,那么它们都可以引用一个公共的cesium块。
仅仅需要在webpack.config.js文件中添加plugin,指定分离Cesium模块的规则:
  1. plugins: [  
  2.     new webpack.optimize.CommonsChunkPlugin({  
  3.         name: 'cesium',  
  4.         minChunks: module => module.context && module.context.indexOf('cesium') !== -1  
  5.     })  
  6. ]  
复制代码
Enable source maps

Source maps允许webpack将错误追踪到原始内容,并且有许多选项。它们提供一些详细的调试信息,以换取编译速度。我推荐使用‘eval’选项,但需要尝试什么对你的开发最有效。
  1. devtool: 'eval'  
复制代码
Source maps不建议在生成中使用。
Remove pragmas

我们在Cesium源代码中包含开发人员错误和警告,这些对产品构建来说是不必要的。习惯上,在缩小的版本构建中,我们使用RequireJS Optimizer优化器来删除它们。由于没有内置的webpack方法来删除这些警告,所以我们将使用strip-pragma-loader。
首先安装它:
  1. npm install strip-pragma-loader --save-dev
复制代码
然后将加载程序包含在module.rules中,调试设置为false。
  1. rules: [{  
  2.     // Strip cesium pragmas  
  3.     test: /\.js$/,  
  4.         enforce: 'pre',  
  5.         include: path.resolve(__dirname, cesiumSource),  
  6.         use: [{  
  7.             loader: 'strip-pragma-loader',  
  8.             options: {  
  9.                 pragmas: {  
  10.                     debug: false  
  11.                 }  
  12.             }  
  13.         }]  
  14. }]  
复制代码
Uglify and minify

在生产环境中,Uglifying和minifying代码允许更小的文件大小。对于release构建,Cesium将uglify JavaScript文件,缩小CSS文件。
为了uglify Cesium源代码,我们使用uglifyjs-webpack-plugin。
  1. npm install uglifyjs-webpack-plugin --save-dev  
复制代码
require它,
  1. const UglifyJsPlugin = require('uglifyjs-webpack-plugin');  
复制代码
将其包含到插件列表中。
  1. plugins: [  
  2.     new webpack.optimize.UglifyJsPlugin()  
  3. ]  
复制代码
为了缩小加载的任何css,我们将在css加载器(css-loader)上使用最小化选项。
  1. module: {  
  2.     rules: [{  
  3.         test: /\.css$/,  
  4.         use: [  
  5.             'style-loader',  
  6.             {  
  7.                 loader: 'css-loader',  
  8.                 options: {  
  9.                     // minify loaded css  
  10.                     minimize: true  
  11.                 }  
  12.             }  
  13.         ]  
  14.     }]  
  15. }
复制代码
资源(Resources)

官方的cesium-webpack-example仓库包含本教程中介绍的最小webpack配置和hello world代码,以及可选代码配置说明。
要了解新应用程序中包含的一些Cesium特性,如添加和样式化数据,请参阅Cesium Workshop Tutorial。
在文档(Documentation)的帮助下,把玩Sandcastle。
要学得更多关于webpack的知识,请查看webpack的概念(Concepts),或者投入到Documentation。
附件

目录变更




最新目录结构

https://cesium.com/learn/cesiumjs-learn/




https://cesium.com/learn/unreal/



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-23 08:00 , Processed in 0.091868 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表