Cesium and Webpack
require statements. When building, it will trace code dependencies and pack these modules into one or more bundles that are loaded by the browser.
In the first half of this tutorial, we’ll build a simple web app from the ground up using webpack, and then cover the steps to integrate the Cesium npm module. This is a good place to start if you’d like to use Cesium to develop a web application, but for an even simpler example of getting started with Cesium, take a look at our Getting Started Tutorial.
In the second half, we’ll explore more advanced webpack configurations for optimizing an application using Cesium.
The completed application and tips for optimizing a Cesium and webpack application can be found in the official cesium-webpack-example repository.
- A browser that supports WebGL. If in doubt, make sure your browser is Cesium ready.
- An IDE or code editor. Developers on the Cesium team members use Webstorm, but a minimal code editor such as Sublime Text will also work.
- Node.js installed. The LTS version is a good place to start, but any version 6 or above will work.
Create a basic webpack app
In this first section, we’ll describe how to set up a basic web application with webpack and the development server. If you’ve already got an app set up and just want to add Cesium, skip to Add Cesium to a webpack app.
Initialize an app with npm
Create a new directory for your application. Let’s call it
cesium-webpack-app. Open a console and run the following command in that new directory:
Follow the prompts and populate any details about your application. Press enter to use the defaults, all of which will work for this application. This will create our
Create our application code
Create a new directory called
src for our “source”. This is where all our app code will live, and these are the files we’ll edit. When we build, webpack will produce output or “distribution” files in the
src/index.html and add code for a boilerplate HTML page.
Now we need to create an entry point for the application. This will be where we tell webpack to start including all of our source code and dependencies for our bundle. That bundle will then be loaded in our
For now, we’ll keep it simple. Create a new file
src/index.js and add a quick line so we know everything’s working.
Install and configure webpack
Let’s begin by installing webpack.
Create a new file called
webpack.config.js. This is where we’ll define our webpack configuration object, which we can then pass along to the compiler.
First we’ll require
path from Node, and the
webpack module we just installed. In the configuration, we’ll tell webpack what our base path is with
context and supply the Node global
__dirname to specify the location of this file. We specify our
entry to be
src/index.js, and we’ll call it
app. We’ll tell webpack to output the bundle (which will be named
app.js since we specified using the entry
[name]) to the
dist folder. Then
export this object so it can be used elsewhere.
We’ll also need a way to load in our css files and other asset files. webpack lets us load everything like a module, and that’s accomplished using loaders. We’ll be using the
Let’s go ahead and add
webpack.config.js. We’ll add two rules, one for css files and one for other static files. For each, we’ll define a
test for the types of file we wanted loaded with that loader, as well as an array
use to specify the list of loaders.
Require the plugin at the top of the
webpack.config.js file and add it to
plugins. We’ll pass
src/index.html as our
template, and webpack will inject a reference to the bundle into the page body.
Bundle the app
We’ll define some scripts that will be easy to call with
npm in out
package.json. Feel free to remove the default
"test" script as we won’t be using it here. Let’s add the
This script simply calls webpack and passes in the
webpack.config.js configuration file we’ve created.
We’re using the local installation of webpack and the webpack-dev-server in these scripts. This allows each project to use its own individual version, and is what is recommended by the webpack documentation. If you’d prefer to use the global version, install it globally with
npm install --global webpack and use the command
webpack --config webpack.config.js to run.
When you run the build command,
you should see some output from webpack starting with something like this:
app.js bundle and
index.html file will be output into the
dist folder. These files are ready to be served out as a web app.
Run the development server
That’s not very exciting. Let’s use the
webpack-dev-server to quickly serve up a development build and see our app in action.
First, install it as a dev dependency.
Next, let’s add another script to our
package.json. We’ll use the
start command to run the development server, passing the config file via the
--config flag as we did for
build. Optionally, we’ll pass the
--open flag top to open the application in our browser when the command is run.
We’ll need to tell the development server where to serve our files from. This will be the same folder where we put the output from webpack, in this case,
dist. Add this at the bottom of your webpack configuration in
Finally, we can run the app!
You should see your content served at
localhost:8080, and if you open up the console, you should see our “Hello World!” message printed there.
Add Cesium to a webpack app
Now that we have a bare bones application running with webpack, let’s get to the fun part and add Cesium.
cesium module from npm and add it to our
package.json file as a dev dependency.
Configure Cesium in webpack
First, let’s define where Cesium is. We’ll use the source code, which allows us to use the individual models and trace the dependencies by leveraging webpack. The alternative would be to use the built (minified or unminified) version of Cesium; however, these modules are already combined and optimized using the RequireJS optimizer, which poses some problems for easily integrating the library and gives us less flexibility will our own optimizations.
webpack.config.js, we add the following above our configuration object:
Next, we’ll add the following options to our configuration object in order to resolve some quirks with how webpack compiles Cesium.
Let’s take a quick look at the reasoning for those individual configuration options and why they are included:
output.sourcePrefix: ''is needed because some versions of webpack default to adding a
\ttab character before each line when output. Cesium has instances of multiline strings, so we need to override this default with an empty prefix
amd.toUrlUndefined: truetells Cesium that the version of AMD webpack uses to evaluate
requirestatements is not compliant with the standard
node.fs: 'empty'resolves some third-party usage of the
fsmodule, which is targeted for use in a Node environment rather than the browser.
Next let’s add a
cesium alias so we can easily reference it in our application code like a traditional Node module.
Manage Cesium static files
Lastly, let’s make sure the static Cesium asset, widget, and web worker files are being served and loaded correctly.
We’ll use the
copy-webpack-plugin, which will allow us as part of the build process to copy the static files included in Cesium over to our
dist directory so they can be served. First, install it.
Then require it near the top of our
Additionally, add the following to the
We’re copying the
Widgets directories as-is. Additionally we’ll use the built web worker scripts, which have already been compiled and optimized with the RequireJS optimizer. Since the web workers are designed to run separately in their own thread, they can be loaded and run as-is. The web workers rarely, if ever, will be needed in their original form for debugging. We’ll copy these over from the
If you have pointed Cesium at a clone of the GitHub repo, the
Build folder will not already exist. Make sure you navigate to the base Cesium directory and run
npm run release to produce the build output. For more information, see the Cesium Build Guide.
Lastly, we’ll define an environment variable that tells Cesium the base URL at which to load static files using the
DefinePlugin that’s built into webpack. The
plugins array will now look like this:
Require Cesium modules in our app
There are a few different ways we can now require Cesium as well as individual Cesium modules within our application. There is the CommonJS syntax, as well as the new
import statements that ES6 modules use.
Additionally, you can import the whole Cesium library under one
Cesium object (for instance, this is what we do in Sandcastle). You can also require only the specific modules you need. Since Cesium is such a big library, this will allow you to include only the specified modules and their dependencies in your bundle, instead of the entire Cesium library.
To require all of the Cesium libraries under one object:
To require an individual module:
ES6 style import
To require all of the Cesium library under one object:
To require an individual module:
Requiring asset files
Now that we have our environment set up and we know how to include Cesium files, let’s duplicate the Hello World app from the original Getting Started Tutorial.
Let’s take another look at our
index.js file. Delete its contents. First, we’ll include
Cesium. The following defines the
In order to use the Cesium Viewer widget, we’ll need to include its CSS:
In the HTML body, we’ll create a div for the viewer to live. In the
index.html file, remove our
<p>Hello World!</p> line and replace it with this div:
Finally, we’ll create an instance of viewer. Back in
index.js add one more line:
And when we run the app with
npm start we’ll see the Cesium Viewer in our browser!
For both your sanity and mine, let’s get rid of that white border by including some custom css.
Create a new file,
src/css/main.css, and add the following styles:
Require it in your
index.js file, right beneath the other require statements:
Start the application again, and you’ll see the viewer in its full-screen glory.
Advanced webpack configurations
webpack can be leveraged in many more ways to increase performance, decrease your bundle size, and perform additional or complex build steps. Here we’ll discuss a few configuration options relevant to using the Cesium library.
Our configuration for an optimal production Cesium webpack build can be found in our example repo at
Webpack by default packages Cesium in the same chunk as our application, which ends up being huge. We can split Cesium out into its own bundle and increase the performance of our app by using the
CommonChunksPlugin. If you end up creating multiple chunks for your own application, they can all reference one common
Just add the plugin to your
webpack.config.js file, and specify the rule for breaking out Cesium modules:
Enable source maps
Source maps allow webpack to trace errors back to the original content, and there are many options. They offer more or less detailed debugging information in exchange for compiling speed. We recommend using the
'eval'option, but play around with what works best for your development.
Source maps are not recommended for production.
We include developer errors and warnings in the Cesium source code that are not necessary for a production build. Traditionally, we remove them using the RequireJS Optimizer in minified release builds. Since there’s no built-in webpack way to remove these warnings, we’ll use the
First, install it,
then include the loader in
debug set to
Uglify and minify
To uglify the Cesium source, we’ll use the
and include it in the list of plugins.
To minify any css we load in, we’ll use the
minimize option on the
The official cesium-webpack-example repo contains the minimal webpack configuration and hello world code covered in this tutorial, as well as instructions for optional code configurations.
For a tour of some Cesium feature to include in your new app, such as adding and styling data, see the Cesium Workshop Tutorial.