Incompatible with Webpack

I was trying to utilize Cesium in an application that utilizes Webpack and ran into numerous errors that state:

"require function is used in a way, in which dependencies cannot be statically extracted"

These errors come when trying to "require" specific modules, like Viewer, for example.

I also tried just requiring the entire Cesium module and found errors that correspond to an issue with the older version of Autolinker that Cesium includes. See the commit that fixes the issue here:

https://github.com/iam4x/Autolinker.js/commit/a54cd13581947e645d8dbdc2dd3def2b827a08e8

I just opened a pull request to update to the latest version of Autolinker: https://github.com/AnalyticalGraphicsInc/cesium/pull/2690

I haven’t used Webpack so I can’t really comment on why it wouldn’t work with Cesium AMD modules. By the “entire Cesium module” I assume you mean Source/Cesium.js, correct? The Build/Cesium.js modules are not AMD. You might want to ask the Webpack folks to help diagnose the problem (unless someone else on this list happens to have experience and can chime in). I know others have successfully used other systems (like browserify with deamdify).

If you figure out what the problem is and it turns out to be something on the Cesium side, we would probably take a pull request to fix it (assuming it wasn’t too intrusive).

I know it doesn’t solve your problem, but I hope it helps.

Webpack is supposed to support amd and commonjs modules, and is commonly used with react, which is what I’m using it with. Here are the errors that I get when trying to include Viewer.js from source, just so that information is captured somewhere:

WARNING in ./Source/Core/buildModuleUrl.js

Critical dependencies:

47:15-22 require function is used in a way, in which dependencies cannot be statically extracted

67:24-31 require function is used in a way, in which dependencies cannot be statically extracted

@ ./Source/Core/buildModuleUrl.js 47:15-22 67:24-31

WARNING in ./Source/ThirdParty/knockout-3.2.0.js

Critical dependencies:

19:128-135 require function is used in a way, in which dependencies cannot be statically extracted

@ ./Source/ThirdParty/knockout-3.2.0.js 19:128-135

WARNING in ./Source/Core/TaskProcessor.js

Critical dependencies:

124:27-34 require function is used in a way, in which dependencies cannot be statically extracted

@ ./Source/Core/TaskProcessor.js 124:27-34

What I meant by the entire module is the Build/Cesium/Cesium.js file. In this case I only ran into the issue with autolinker. The “modules” don’t necessarily have to be amd, since there is usually some method provided by webpack to shim modules that need to be handled specially.

Hi Nick,

I haven’t used Webpack, but I have used browserify, which works similarly.

Cesium is a bit tricky to use in this sort of environment, because:

  • It uses Web Workers to do work in background threads, to improve performance.

  • It has a number of static assets that are needed at runtime, other than JavaScript and CSS, such as the star texture, Viewer UI images, and data used to transform between the Earth fixed and inertial frames.

To make this all work, I’ve created an npm module with a lightly-customized version of Cesium: https://www.npmjs.com/package/terriajs-cesium

To use it:

  1. npm install --save terriajs-cesium

  2. require-in individual Cesium types from the Source/[Core/Renderer/Scene/Widgets/etc] directories, e.g.:

var Viewer = require(‘terriajs-cesium/Source/Widgets/Viewer/Viewer’);

  1. Make sure the contents of node_modules/terriajs-cesium/wwwroot/build is somewhere on your web server at runtime, and tell buildModuleUrl where it is, e.g.:

buildModuleUrl.setBaseUrl(’./Cesium/build/’);

You may still get some warnings from WebPack at build time (I don’t see any from Browserify). I think they’ll be harmless.

Kevin

Hey all,

We’re running into the same issues. Kevin Ring’s fork has us up and running for now, but we’d definitely like to be on the main cesium repo. Kevin, just glancing at your repo, I noticed the gulpfile that does some processing (building / copying some assets around). Can you give more detail on what other customizations you made to support browserify (if any)?

The biggest issue is the use of require dynamically in Knockout, TaskProcessor, and buildModuleUrl. There seem to be some webpack ways using plugins to avoid these. We’re looking into them.

Other projects we’ve done have avoided the issue completely by just including the build cesium source/css as a separate tag in the .

Mike

I’ve recently opened pull requests for most of my changes, and they’ve been merged. So here’s what’s still unique about my fork:

I’ve removed the package.json in each of the Source/[Core/Scene/etc] directories. I don’t know exactly why those files are there (something to do with Dojo builds?) but they confuse Browserify.

I’ve completely replaced the normal Cesium cesiumWorkerBootstrapper.js with my own. Mine is very simple, it just loads a prebuilt Cesium-WebWorkers.js (which is built by gulp using Browserify) and requires-in the worker module.

I have a package.json at the root that allows the whole thing to be published as an npm module.

And finally the gulpfile, as mentioned above, builds all of Cesium’s workers into a single js file using browserify and copies runtime assets from the Source directory to a wwwroot directory that is expected to be accessible via the web server at runtime,

FWIW I’m one of the founders of Cesium and I work every day on an application built on that terriajs-cesium package (Australia’s official National Map), so you should feel reasonably confident using it.

Thanks for the quick and detailed response Kevin. I definitely feel a lot better about using your fork, but I would argue that perhaps its best to get your changes into the main cesium repo. IMHO, npm/browserify/webpack are definitely getting a lot of interest in the community and having Cesium work with all of them out of the box would be ideal.

To those who do come across this thread, there are currently three main errors that Nick mentioned above:

WARNING in ./Source/Core/buildModuleUrl.js

Critical dependencies:

47:15-22 require function is used in a way, in which dependencies cannot be statically extracted

67:24-31 require function is used in a way, in which dependencies cannot be statically extracted

@ ./Source/Core/buildModuleUrl.js 47:15-22 67:24-31

WARNING in ./Source/ThirdParty/knockout-3.2.0.js

Critical dependencies:

19:128-135 require function is used in a way, in which dependencies cannot be statically extracted

@ ./Source/ThirdParty/knockout-3.2.0.js 19:128-135

WARNING in ./Source/Core/TaskProcessor.js

Critical dependencies:

124:27-34 require function is used in a way, in which dependencies cannot be statically extracted

@ ./Source/Core/TaskProcessor.js 124:27-34

Both TaskProcessor and BuildModuleUrl errors are safe to ignore if you are using webpack, as the warning areas are really just checking to see if require is the AMD require and if not they default to using the baseUrl that you can config using Kevin’s instructions, #3 above (buildModuleUrl.setBaseUrl(‘./Cesium/build/’):wink:

The Knockout errors are due to a current (fixed) bug in knockout 3.2.0 with how they defined their module wrapper code. Forcing the knockout code in my cesium distribution to be 3.3.0 fixed that error completely. Still, I believe that this warning can be safely ignored as well because it is in the code that’s checking for AMD require, and doesn’t do anything crazy with it if it doesn’t find it. Webpack just doesn’t know this and complains.

However, webpack does still complain about the BuildModuleUrl. I found a bazooka method to remove those errors, I’m still learning Webpack but if you configure the ‘module’ has with the code below, it instructs webpack to ignore all those require errors. I call this a bazooka because as far as I can tell, it will ignore all errors wherever they may be, safe or not to ignore. So be warned. If I find another, better way, I’ll post it.

In the ‘module’ section of your webpack config, place the following line:

// rest of config
module : {
unknownContextCritical : false,
// rest of your loaders
}

``

Hope that helps! And double thanks to Kevin for doing all the real work!

Hey all,

So after getting pretty good at webpack and thanks to Kevin’s nice fork and description, I believe its definitely possible to get pure Cesium (and not terriajs-cesium) into webpack with minimal trouble. These are the steps I had to do to get vanilla Cesium working with webpack.

  1. As Kevin said, remove the package.json files in the Source/* directories. These also seem to confuse webpack as well as browserify. I doubt the intent is to publish just the Cesium Scene Directory as a package for example, so I’d argue these could probably be deleted anyway. On the other hand, I don’t know why they’re really there. As Kevin said, they seem to be related to Dojo builds. Can anyone shed light on them?

  2. You need to have built versions of the workers done and publicly available on whatever server you run Cesium on. These versions of the workers can be used as is from Cesium’s “Build” directory. They do not have to be webpack-built or browserify-built workers since the web worker build has everything it needs minified in one file. You get in trouble if require.js tries to request extra modules, hence why you need to just the built version of the workers.

  3. Copy Assets to a folder where you serve up your app (the others are not really necessary as far as i can tell). You need to set the value of buildModuleUrl.setBaseUrl(‘path/to/Assets/parent/’); to be where you placed Assets.

I’ll also create an issue on Github that spells this out. I’d be happy to create a PR that makes these changes.

Mike

So to clarify - you guys are talking about using the original, non-bundled Cesium source folder layout as input to Webpack, rather than the prebuilt minified Cesium.js?

Mark, yes. I haven’t tested out the prebuilt one, I’ll try it out soon hopefully as that’s definitely a use case a lot of people have.

Hi,

I am working on creating a plugin for Cesium library (http://cesiumjs.org/index.html) in Kibana 4 (https://github.com/elastic/kibana).
I am new to Webpack and unable to install with Kibana server which node js server and it's using Webpack. Below is the error I see while starting Kibana. Any help is appreciated.

$ npm install cesium@1.18.0 node_modules/cesium └── requirejs@2.1.22

$ npm start

ERROR in ./~/cesium/~/requirejs/bin/r.js Module parse failed: /home/praveen/development/kibana4-dev/kibana/node_modules/cesium/node_modules/requirejs/bin/r.js Line 1: Unexpected token ILLEGAL You may need an appropriate loader to handle this file type. | #!/usr/bin/env node | /** | * @license r.js 2.1.22 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved. @ ./~/cesium/index.js 5:16-36

ERROR in ./~/cesium/Source/Workers/createGeometry.js Module not found: Error: Cannot resolve module 'Workers' in /home/praveen/development/kibana4-dev/kibana/node_modules/cesium/Source/Workers @ ./~/cesium/Source/Workers/createGeometry.js 23:47-79

ERROR in ./~/cesium/Build/Cesium/Workers/createGeometry.js Module not found: Error: Cannot resolve module 'Workers' in /home/praveen/development/kibana4-dev/kibana/node_modules/cesium/Build/Cesium/Workers @ ./~/cesium/Build/Cesium/Workers/createGeometry.js 77:21106-21121

ERROR in ./~/cesium/Build/CesiumUnminified/Workers/createGeometry.js Module not found: Error: Cannot resolve module 'Workers' in /home/praveen/development/kibana4-dev/kibana/node_modules/cesium/Build/CesiumUnminified/Workers @ ./~/cesium/Build/CesiumUnminified/Workers/createGeometry.js 22681:47-79

at Object.exports.create (/home/praveen/development/kibana4-dev/kibana/node_modules/boom/lib/index.js:21:17) at LazyOptimizer.failedStatsToError (/home/praveen/development/kibana4-dev/kibana/src/optimize/BaseOptimizer.js:167:17) at Compiler. (/home/praveen/development/kibana4-dev/kibana/src/optimize/lazy/LazyOptimizer.js:44:22) at Compiler.applyPlugins (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/node_modules/tapable/lib/Tapable.js:26:37) at Watching._done (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/lib/Compiler.js:78:17) at Watching. (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/lib/Compiler.js:51:17) at /home/praveen/development/kibana4-dev/kibana/node_modules/webpack/lib/Compiler.js:403:12 at Compiler.next (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/node_modules/tapable/lib/Tapable.js:67:11) at Compiler. (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/lib/CachePlugin.js:40:4) at Compiler.applyPluginsAsync (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/node_modules/tapable/lib/Tapable.js:71:13) at Compiler. (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/lib/Compiler.js:400:9) at Compilation. (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/lib/Compilation.js:576:13) at Compilation.applyPluginsAsync (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/node_modules/tapable/lib/Tapable.js:60:69) at Compilation. (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/lib/Compilation.js:571:10) at Compilation.applyPluginsAsync (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/node_modules/tapable/lib/Tapable.js:60:69) at Compilation. (/home/praveen/development/kibana4-dev/kibana/node_modules/webpack/lib/Compilation.js:566:9)

Hi,

I'm very new to Cesium but I have a Netbeans/npm/nodejs project that uses webpack and "requires" Cesium and it works. I did it last night with some playing and following the tutorials. Those errors for me were due to either not having the compiled Assets available to the Client (or misdirected) or a couple of webpack settings to handle multiline strings and other things.

My repository is here, if it helps: https://bitbucket.org/matt_jd/nodejscesium

Matthew

Thanks for the prompt reply. I will keep messing around with webpack..

Give this a try:

Hi Tj,

My team is in the middle of moving to Webpack and we've run into issues porting our Cesium code over to our new architecture. We ran into this answer online and are trying to use your package, but can't figure out what import model you're using. Should we be running import { BingMapsApi } from 'cesium-webpack' or something else?

Thanks!

I updated the instructions in the README.md. Basically just:

var Cesium = require(‘webpack-cesium’);

or

import Cesium from ‘webpack-cesium’;

This will get you the root object, then, use whatever you want.