Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Dojo build
added grunt task
re-named packages and organized folders/files to make build configuration easier
updated readme w/ npm/bower/grunt instructions for installing, running, and builds
resolves #36 and resolves #41
  • Loading branch information
tomwayson committed Oct 23, 2014
commit b3ef06069e2281d5a8037a0f9f32580685a342ad
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
# dojo-bootstrap-map-js

A boilerplate application demonstrating how to use the Esri [ArcGIS API for JavaScript](//js.arcgis.com) with [Bootstrap Map](//github.com/Esri/bootstrap-map-js) and [Dojo Bootstrap](//github.com/xsokev/Dojo-Bootstrap) to create a responsive mapping application using [Bootstrap](//getbootstrap.com) components without a dependency on jQuery.
An application boilerplate demonstrating how to use the Esri [ArcGIS API for JavaScript](//js.arcgis.com) with [Bootstrap Map](//github.com/Esri/bootstrap-map-js) and [Dojo Bootstrap](//github.com/xsokev/Dojo-Bootstrap) to create a responsive mapping application using [Bootstrap](//getbootstrap.com) components.

[View it live](http://esri.github.io/dojo-bootstrap-map-js/src/)

![App Screenshot](https://raw.githubusercontent.com/Esri/dojo-bootstrap-map-js/master/dojo-bootstrap-map-js.png)

The goal of this application boilerplate is to demonstrate how to build a mapping application that utilizes the best parts of Dojo (AMD modules, classes and widgets, promises, i18n, routing, etc) along with the responsive UI of Bootstrap. NOTE: not all of the above have been incorporated into this boilerplate yet.
This boilerplate is ideal for mobile-first applications because it combines the responsive layout of Bootstrap with the ability optimize the JavaScript and CSS code by running a Dojo build. Furthermore, it does not incur the overhead of loading jQuery on the page, which is essentially redundant once you've already loaded Dojo.

The goal of this application boilerplate is to demonstrate how to build a mapping application that utilizes the best parts of Dojo (AMD modules, classes and widgets, promises, i18n, routing, custom builds, etc) along with the responsive UI of Bootstrap. NOTE: not all of the above have been incorporated into this boilerplate yet.

For simpler examples of how to get started with [Bootstrap Map](//github.com/Esri/bootstrap-map-js) and [Dojo Bootstrap](//github.com/xsokev/Dojo-Bootstrap), see the [Boostrap Map demo pages](http://esri.github.io/bootstrap-map-js/demo/dojo/getstarted.html).

## Instructions

See requirements below before attempting these instructions.

1. [Fork and clone the repo](https://help.github.com/articles/fork-a-repo)
2. `cd` into the `dojo-bootstrap-map-js` folder
3. Run `bower install`
4. Run and try the samples.
3. Run `bower install` to download Dojo and other dependencies
4. Run `npm install` to download Grunt tasks
5. Run `grunt slurp` to download the Esri JSAPI
6. Run `grunt serve` to load the boilerplate into a web browser
7. Modify the code as needed
8. Run `grunt build` to build the app under the `dist` folder

## Requirements

* Notepad or your favorite text editor
* Web browser with access to the Internet
* Node and Grunt if you want to use the command line development tools
* You will also need to install [Node](http://nodejs.org/), [Bower](http://bower.io/), and [Grunt](http://gruntjs.com/) in order to download dependencies and build the app via the command line.

## Resources

Expand Down
80 changes: 72 additions & 8 deletions gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,70 @@ module.exports = function(grunt) {
travis: {
dest: 'src/esri'
}
},
// clean the output directory before each build
clean: ['dist'],
// dojo build configuration, mainly taken from dojo boilerplate
dojo: {
dist: {
options: {
profile: 'profiles/app.profile.js' // Profile for build
}
},
options: {
dojo: 'src/dojo/dojo.js', // Path to dojo.js file in dojo source
load: 'build', // Optional: Utility to bootstrap (Default: 'build')
// profiles: [], // Optional: Array of Profiles for build
// appConfigFile: '', // Optional: Config file for dojox/app
// package: '', // Optional: Location to search package.json (Default: nothing)
// packages: [], // Optional: Array of locations of package.json (Default: nothing)
// require: '', // Optional: Module to require for the build (Default: nothing)
// requires: [], // Optional: Array of modules to require for the build (Default: nothing)
releaseDir: '../dist', // Optional: release dir rel to basePath (Default: 'release')
cwd: './', // Directory to execute build within
// dojoConfig: '', // Optional: Location of dojoConfig (Default: null),
// Optional: Base Path to pass at the command line
// Takes precedence over other basePaths
// Default: null
basePath: './src'
}
},
// this copies over index.html and replaces
// the perl regexp section of build.sh in the dojo boilerplate
'string-replace': {
index: {
src: './src/index.html',
dest: './dist/index.html',
options: {
replacements: [
// remove isDeubug
{
pattern: /isDebug: *true,/,
replacement: ''
},
// strip js comments
{
pattern: /\s+\/\/.*$/gm,
replacement: ''
},
// replace newlines w/ whitespace
{
pattern: /\n/g,
replacement: ' '
},
// strip html comments
{
pattern: /<!--[\s\S]*?-->/g,
replacement: ''
},
// collapse whitespace
{
pattern: /\s+/g,
replacement: ' '
}
]
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
Expand All @@ -102,13 +166,11 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-open');
grunt.loadNpmTasks('grunt-build-gh-pages');
grunt.loadNpmTasks('grunt-esri-slurp');

grunt.registerTask('default', ['watch']);
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-dojo');
grunt.loadNpmTasks('grunt-string-replace');

grunt.registerTask('default', [
'serve'
]);
grunt.registerTask('default', ['serve']);

grunt.registerTask('serve', function (target) {
grunt.task.run([
Expand All @@ -121,7 +183,9 @@ module.exports = function(grunt) {

grunt.registerTask('hint', ['jshint']);

grunt.registerTask('gh-pages', ['buildGhPages:ghPages']);

grunt.registerTask('slurp', ['esri_slurp:dev']);

grunt.registerTask('build', ['clean', 'dojo', 'string-replace']);

grunt.registerTask('gh-pages', ['buildGhPages:ghPages']);
};
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@
"grunt-contrib-jshint": "^0.10.0",
"grunt-contrib-watch": "~0.5.3",
"grunt-esri-slurp": "^1.1.0",
"grunt-open": "~0.2.3"
"grunt-open": "~0.2.3",
"grunt-contrib-clean": "^0.6.0",
"grunt-dojo": "^0.3.0",
"grunt-string-replace": "^0.2.7"
},
"engines": {
"node": ">=0.8.0"
Expand Down
124 changes: 124 additions & 0 deletions profiles/app.profile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/**
* Look to `util/build/buildControlDefault.js` for more information on available options and their default values.
*/

var profile = {
// `basePath` is relative to the directory containing this profile file; in this case, it is being set to the
// src/ directory, which is the same place as the `baseUrl` directory in the loader configuration. (If you change
// this, you will also need to update run.js.)
basePath: '../src/',

// This is the directory within the release directory where built packages will be placed. The release directory
// itself is defined by `build.sh`. You should probably not use this; it is a legacy option dating back to Dojo
// 0.4.
// If you do use this, you will need to update build.sh, too.
// releaseName: '',

// Builds a new release.
action: 'release',

// Strips all comments and whitespace from CSS files and inlines @imports where possible.
cssOptimize: 'comments',

// Excludes tests, demos, and original template files from being included in the built version.
mini: true,

// Uses Closure Compiler as the JavaScript minifier. This can also be set to "shrinksafe" to use ShrinkSafe,
// though ShrinkSafe is deprecated and not recommended.
// This option defaults to "" (no compression) if not provided.
optimize: 'closure',

// We're building layers, so we need to set the minifier to use for those, too.
// This defaults to "shrinksafe" if not provided.
layerOptimize: 'closure',

// A list of packages that will be built. The same packages defined in the loader should be defined here in the
// build profile.
packages: [
// Using a string as a package is shorthand for `{ name: 'app', location: 'app' }`
'app',
'dgrid',
'dijit',
'dojo',
'dojox',
'esri',
'put-selector',
'xstyle',
'dojo-bootstrap',
{
name: 'bootstrap-map-js',
location: 'bootstrap-map-js/src'
}
],

// Strips all calls to console functions within the code. You can also set this to "warn" to strip everything
// but console.error, and any other truthy value to strip everything but console.warn and console.error.
// This defaults to "normal" (strip all but warn and error) if not provided.
stripConsole: 'all',

// The default selector engine is not included by default in a dojo.js build in order to make mobile builds
// smaller. We add it back here to avoid that extra HTTP request. There is also an "acme" selector available; if
// you use that, you will need to set the `selectorEngine` property in index.html, too.
selectorEngine: 'lite',

// Any module in an application can be converted into a "layer" module, which consists of the original module +
// additional dependencies built into the same file. Using layers allows applications to reduce the number of HTTP
// requests by combining all JavaScript into a single file.
layers: {
// This is the main loader module. It is a little special because it is treated like an AMD module even though
// it is actually just plain JavaScript. There is some extra magic in the build system specifically for this
// module ID.
'dojo/dojo': {
// By default, the build system will try to include `dojo/main` in the built `dojo/dojo` layer, which adds
// a bunch of stuff we do not want or need. We want the initial script load to be as small and quick to
// load as possible, so we configure it as a custom, bootable base.
boot: true,
customBase: true,
include: [
// include the app
'app/main',
// dpendencies of esri/map that will be requested if not included
'dojox/gfx/path',
'dojox/gfx/svg',
'dojox/gfx/shape',
'esri/dijit/Attribution',
// layer types from nested require block in Map.js
'esri/layers/ArcGISDynamicMapServiceLayer',
'esri/layers/FeatureLayer'
// NOTE: if you add other layer types to config, include here
// 'esri/layers/ArcGISTiledMapServiceLayer'
]
}//,

// In this demo application, we load `app/main` on the client-side, so here we could build a separate layer containing
// that code. (Practically speaking, you probably just want to roll everything into the `dojo/dojo` layer,
// but this helps provide a basic illustration of how multi-layer builds work.) Note that when you create a new
// layer, the module referenced by the layer is always included in the layer (in this case, `app/main`), so it
// does not need to be explicitly defined in the `include` array.
// 'app/main': {}
},

// Providing hints to the build system allows code to be conditionally removed on a more granular level than simple
// module dependencies can allow. This is especially useful for creating tiny mobile builds. Keep in mind that dead
// code removal only happens in minifiers that support it! Currently, only Closure Compiler to the Dojo build system
// with dead code removal. A documented list of has-flags in use within the toolkit can be found at
// <http://dojotoolkit.org/reference-guide/dojo/has.html>.
staticHasFeatures: {
// The trace & log APIs are used for debugging the loader, so we do not need them in the build.
'dojo-trace-api': false,
'dojo-log-api': false,

// This causes normally private loader data to be exposed for debugging. In a release build, we do not need
// that either.
'dojo-publish-privates': false,

// This application is pure AMD, so get rid of the legacy loader.
'dojo-sync-loader': false,

// `dojo-xhr-factory` relies on `dojo-sync-loader`, which we have removed.
'dojo-xhr-factory': false,

// We are not loading tests in production, so we can get rid of some test sniffing code.
'dojo-test-sniff': false
}
};
2 changes: 1 addition & 1 deletion src/app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ define(['dojo/topic',
'app/widget/Map',
'app/widget/NavBar',

'dojo/i18n!./app/nls/strings.js',
'dojo/i18n!app/nls/strings',

'dojo/domReady!'],
function(
Expand Down
5 changes: 2 additions & 3 deletions src/css/app.css → src/app/resources/app.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
@import url("//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css");
@import url("../esri/css/esri.css");
@import url("../bootstrap-map-js/src/css/bootstrapmap.css");
@import url("../../esri/css/esri.css");
@import url("../../bootstrap-map-js/src/css/bootstrapmap.css");

body {
padding-top: 50px;
Expand Down
6 changes: 3 additions & 3 deletions src/app/widget/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ define([
'esri/dijit/LocateButton',
'esri/dijit/Geocoder',

'bootstrap-map-js/bootstrapmap',
'bootstrap-map-js/js/bootstrapmap',

'dojo/text!./templates/Map.html'
], function(declare, array, lang,
Expand All @@ -32,8 +32,8 @@ define([

_initMap: function() {
//if( this.config.map.id ) {
//this.map = BootstrapMap.createWebMap(this.config.map.id, this.mapNode, this.config.map.options);
//BootstrapMap.createWebMap(this.config.map.id, this.mapNode, this.config.map.options);
//this.map = BootstrapMap.createWebMap(this.config.map.id, this.mapNode, this.config.map.options);
//BootstrapMap.createWebMap(this.config.map.id, this.mapNode, this.config.map.options);
//} else {
this.map = BootstrapMap.create(this.mapNode, this.config.map.options);
this._initLayers();
Expand Down
6 changes: 3 additions & 3 deletions src/app/widget/NavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ define([

'dojo/text!./templates/NavBar.html',

'bootstrap/Collapse',
'bootstrap/Dropdown',
'bootstrap/Modal'
'dojo-bootstrap/Collapse',
'dojo-bootstrap/Dropdown',
'dojo-bootstrap/Modal'
], function(declare, query, touch, topic, _WidgetBase, _TemplatedMixin, template) {
return declare([_WidgetBase, _TemplatedMixin], {
templateString: template,
Expand Down
15 changes: 8 additions & 7 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@

<link rel="shortcut icon" href="./favicon.png">

<title></title>
<title>Dojo Bootstrap Map</title>

<link href="./css/app.css" rel="stylesheet">
<!-- NOTE: getting bootstrap from CDN for now
until we bring in as a dependency and
only include necessary styles -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="app/resources/app.css">

<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
Expand All @@ -36,13 +40,10 @@
'esri',
'put-selector',
'xstyle',
{
name: 'bootstrap',
location: window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + '/dojo-bootstrap'
},
'dojo-bootstrap',
{
name: 'bootstrap-map-js',
location: window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + '/bootstrap-map-js/src/js'
location: 'bootstrap-map-js/src'
}
],
selectorEngine: 'lite',
Expand Down