Create a gist now

Instantly share code, notes, and snippets.

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

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
jwasilgeo commented Jun 16, 2016 edited

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

@molekilla

thanks!!!

@dcworldwide

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

@gund
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.

@bradjohnwoods

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

@tomwayson
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.

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