Environment specific configuration for an AngularJS application
A couple of weeks ago I blogged about my experiment with Grails and AngularJS. When I deployed the application "in production" I realized that I needed to change the Urls for accessing the Grails backend. In development mode Grails is running in an own Tomcat instance on a different port, while in production the Grails backend and the AngularJS frontend application are both served from the same Tomcat instance. In fact, both parts get exported to one .war file. After a bit of research I came across the grunt-ng-constant task which is named to be a "plugin for dynamic generation of angular constant modules". Sounds like what I needed ;)
To install the grunt plugin add the following code to your "devDependencies" and run an npm install afterwards:
grunt-ng-constant": "^1.0.0"
In your Gruntfile.js configure the task and define the constants that should be exposed as needed:
// environment specific configuration
ngconstant: {
// Options for all targets
options: {
name: 'config',
},
development: {
options: {
dest: '<%= yeoman.app %>/scripts/config.js'
},
constants: {
ENV: {
name: 'development',
apiEndpoint: 'http://localhost:8080/grails-backend/'
}
}
},
production: {
options: {
dest: '<%= yeoman.app %>/scripts/config.js'
},
constants: {
ENV: {
name: 'production',
apiEndpoint: ''
}
}
}
}
The Grunt task will create a file scripts/config.js within your application which contains the "constants". In your application code you can inject the ENV object where needed and use the ENV properties in your code (e.g. ENV.apiEndpoint).
Next up: Include the ngconstant:development and ngconstant:production subtasks inthe default tasks used by Grunt. In my Grails/yeoman setup Grails will run grunt serve in development mode which means I had to add the ngconstant:development task into chain of tasks that get executed then "serve" was run:
grunt.task.run([
'clean:server',
'ngconstant:development',
'wiredep',
'concurrent:server',
'autoprefixer',
'connect:livereload',
'watch'
]);
When I let Grails build the .war file the Grunt "build" task gets executed by Grails. So this is the right place to hook into the production configuration:
grunt.registerTask('build', [
'clean:dist',
'ngconstant:production',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);