Create a gist now

Instantly share code, notes, and snippets.

@gund /index.html
Last active Mar 31, 2017

What would you like to do?
ArcGIS JSAPI setup build with Webpack for production (start reading from webpack.config.js)
<!DOCTYPE html>
<html>
<head>...</head>
<body>
<!-- Load Esri lib -->
<link rel="stylesheet" href="//js.arcgis.com/4.0/esri/css/main.css">
<script src="//js.arcgis.com/4.0/"></script>
<!-- Load our AMD app -->
<script type="text/javascript">
// Wrap our app startup in AMD module
require([
'/vendor.bundle.js', // <-- Vendor bundle?
'/app.bundle.js' // <-- Your application
],
function (vendor, app) {
// Do whatewer initialization needed here...
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>...</head>
<body>
<!-- Load Esri lib -->
<link rel="stylesheet" href="//js.arcgis.com/4.0/esri/css/main.css">
<script src="//js.arcgis.com/4.0/"></script>
<!-- Load our AMD app -->
<script type="text/javascript">
// Wrap our app startup in AMD module
require([
'/<%= htmlWebpackPlugin.files.js[0] %>', // <-- Vendor bundle?
'/<%= htmlWebpackPlugin.files.js[1] %>' // <-- Your application
],
function (vendor, app) {
// Do whatewer initialization needed here...
//
// NOTE: htmlWebpackPlugin.files.js is an Array
// that contains names of your bundles in order they were built
});
</script>
</body>
</html>
// In order to bundle an app with ArcGIS API in wepback
// first you have to turn your bundle target to AMD, so
// ...
output: {
...
libraryTarget: "amd" // <-- There we go
...
}
// ...
// Also we have to tell webpack to skip all the JSAPI libraries from being bundled
// So they will become externals (all dojo and esri libs)
// ...
externals: [
function(context, request, callback) {
if (/^dojo/.test(request) ||
/^dojox/.test(request) ||
/^dijit/.test(request) ||
/^esri/.test(request)
) {
return callback(null, "amd " + request);
}
callback();
}
]
// ...
// Now exlude bundles from being injected into index.html page (ex. for html-webpack-plugin)
// ...
plugins: [
...
new require('html-webpack-plugin')({
template: '.../index.html', // <-- Your template
chunksSortMode: 'dependency', // <-- Important if you wont to refer to your bundles after they are built
inject: false // <-- This is exclusion
})
...
]
// ...
// For most of the cases this might be enough in webpack configuration
// and depending on your bundles config you just have to `require` them in your index.html
// See index.html file above
// However you might want to hash your bundles for production deployments
// In this case hardcoding your bundles in index.html would not work anymore
// Each new build (or once you changed the code) will generate bundles with different hashes
// So for this you might use some plugins like WebpackMd5Hash or standard webpack chunkhash plugin
// and your fileName would probably look smth like this
output: {
...
filename: '[name].[chunkhash].bundle.js' // <-- here you no more getting a static file names
...
}
// ...
// In order to include those files in your index.html I am using chunk-manifest-webpack-plugin
// It has pretty simple setup
plugins: [
...
new require('chunk-manifest-webpack-plugin')({
filename: "manifest.json", // <-- A file with build info
manifestVariable: "webpackManifest" // <-- A variable to wich you can refer later (not important)
})
...
]
// This seput will generate additional manifest.json file in your build directory
// Which will contain info about your bundles in JSON format
// And you now will be able to include your bundles in index.html with proper names
// See index.prod.html above

jwasilgeo commented Jun 16, 2016 edited

Thanks for including the helpful and informative comments in this gist. Cool stuff.

thanks!!!

Thanks. Does this work with Hot module replacement? I'm struggling to get it working.

Owner

gund commented Oct 3, 2016

Thanks guys, glad it helpful.

@dcworldwide I actually used HMR with this setup under early Angular2 beta setup.
If it's still relevant you can have a look at this config. Anyway if you have some questions I'm glad to answer if I can :)

Thanks.

I'm trying this after ejecting from a 'create-react-app' project. I get the following error:
Cannot set property 'options' of undefined

tomwayson commented Dec 5, 2016 edited

@bradjohnwoods, you can see an example of that in https://github.com/davetimmins/create-react-app-arcgis

@gund, I think this commented explanation of the config helped a lot of people, thx!

FYI - I explain why this workaround is needed and go a bit deeper into how it works as well as an alternative solution that supports lazy loading the ArcGIS API w/ esri-loader in this blog post.

It was very helpful! Thanks @gund

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment