Skip to content

Instantly share code, notes, and snippets.

@gund
Last active February 12, 2024 00:06
Show Gist options
  • Save gund/6b22d5ffae42849252abc9a689eb656d to your computer and use it in GitHub Desktop.
Save gund/6b22d5ffae42849252abc9a689eb656d to your computer and use it in GitHub Desktop.
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
Copy link

jwasilgeo commented Jun 16, 2016

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

@molekilla
Copy link

thanks!!!

@dcworldwide
Copy link

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

@gund
Copy link
Author

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.

Copy link

ghost commented Nov 7, 2016

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

@tomwayson
Copy link

tomwayson commented Dec 5, 2016

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

@jigar1101
Copy link

It was very helpful! Thanks @gund

@AlexOliinyk1
Copy link

After web-pack was configured I got next errors

`(Emitted value instead of an instance of Error) Cannot find source file 'compiler.es5.ts': Error: Can't resolve './compiler.es5.ts' in 'C:\Users\alexo\OneDrive\projects\proliant_gis\test\arcgis\node_modules
@angular\compiler@angular'
@ ./~/@angular/platform-browser-dynamic/@angular/platform-browser-dynamic.es5.js 7:0-72
@ ./src/main.ts
@ multi ./src/main.ts

ERROR in C:/Users/alexo/OneDrive/projects/proliant_gis/test/arcgis/src/app/map/map.component.ts (2,1): Import assignment cannot be used when targeting ECMAScript 2015 modules. Consider using 'import * as ns
from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.

ERROR in C:/Users/alexo/OneDrive/projects/proliant_gis/test/arcgis/src/app/map/map.component.ts (2,22): Cannot find module 'esri/Map'.

ERROR in C:/Users/alexo/OneDrive/projects/proliant_gis/test/arcgis/src/app/map/map.component.ts (3,1): Import assignment cannot be used when targeting ECMAScript 2015 modules. Consider using 'import * as ns
from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.

ERROR in C:/Users/alexo/OneDrive/projects/proliant_gis/test/arcgis/src/app/map/map.component.ts (3,26): Cannot find module 'esri/views/MapView'.

ERROR in C:/Users/alexo/OneDrive/projects/proliant_gis/test/arcgis/src/app/map/map.component.ts (2,1): Import assignment cannot be used when targeting ECMAScript 2015 modules. Consider using 'import * as ns
from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.

ERROR in C:/Users/alexo/OneDrive/projects/proliant_gis/test/arcgis/src/app/map/map.component.ts (2,22): Cannot find module 'esri/Map'.

ERROR in C:/Users/alexo/OneDrive/projects/proliant_gis/test/arcgis/src/app/map/map.component.ts (3,1): Import assignment cannot be used when targeting ECMAScript 2015 modules. Consider using 'import * as ns
from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.

ERROR in C:/Users/alexo/OneDrive/projects/proliant_gis/test/arcgis/src/app/map/map.component.ts (3,26): Cannot find module 'esri/views/MapView'.
Child html-webpack-plugin for "index.html":
[./node_modules/html-webpack-plugin/lib/loader.js!./src/index.html] ./~/html-webpack-plugin/lib/loader.js!./src/index.html 1.09 kB {0} [built]
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] build: webpack
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\alexo\AppData\Roaming\npm-cache_logs\2017-07-25T12_39_27_381Z-debug.log`

My webconfig changes from standard AlexOliinyk1/esri-webpack@d35b1dd

webconfig - https://github.com/AlexOliinyk1/esri-webpack/blob/master/arcgis/webpack.config.js

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