Create a gist now

Instantly share code, notes, and snippets.

@gund /index.html
Last active Jul 25, 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

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'
@ ./~//.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! arcgis@0.0.0 build: webpack
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the arcgis@0.0.0 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