Changing JS variable with Grunt for different environments

2.7k Views Asked by At

I'm trying to configure my JS build to do next:

I'm using a JS variable to define the application root:

globals.js

define(function (require) {
   "use strict";
   return {
      mainRoot: "http://myapp.com"
      //mainRoot: "http://localhost:3000" - local run
      //mainRoot: "http://myapp-test.com" - test server
   };
});

During local development I'm using code without Grunt build and running Grunt only for test & production builds.

Grunt is running from the Maven plugin using command-line configuration. So it is the only way to pass the environment variable.

pom.xml

<plugin>
    <groupId>pl.allegro</groupId>
    <artifactId>grunt-maven-plugin</artifactId>
    <configuration>
        <gruntOptions>
            <gruntOption>--verbose</gruntOption>
        </gruntOptions>
        <target>build</target>
    </configuration>
</plugin>

Grunt configuration is pretty simple and looks like this:

Gruntfile.js

grunt.registerTask('build', [
    'karma',
    'requirejs',
    'concat',
    'csso',
    'copy',
    'processhtml'
]);

The question:

How can I configure Grunt to change my variable in next way?

  1. Default value of mainRoot should be http://localhost:3000
  2. Environment variable should be set via command-line from the Maven plugin
  3. When running Grunt with PROD environment - mainRoot should be changed to http://myapp.com
  4. When running Grunt with TEST environment - mainRoot should be changed to http://myapp-test.com

Thank you!

1

There are 1 best solutions below

1
On BEST ANSWER

I find a combination of grunt-replace and grunt-config works well.

In your Gruntfile.js, configure grunt-config like this (see the README):

config: {
    local: {
        options: {
            variables: {
                mainroot: 'http://localhost:3000'
            }
        }
    },
    test: {
        options: {
            variables: {
                mainroot: 'http://myapp-test.com'
            }
        }
    },
    prod: {
        options: {
            variables: {
                mainroot: 'http://myapp.com'
            }
        }
    }
}

In your globals.js, create an @@ placeholder for grunt-replace to find and replace:

define(function (require) {
   "use strict";
   return {
      mainRoot: "@@MAINROOT"
   };
});

In your Gruntfile.js, configure grunt-replace like this:

replace: {
    my_target: {
        options: {
            patterns: [
                {
                    match: 'MAINROOT',
                    replacement: '<%= grunt.config.get("mainroot") %>'
                }
            ]
        },
        src: ... ,
        dest: ...
    }
}

Then create a command-line option such as --env, which will accept local or test or prod, and will default to local if omitted:

var envTarget = grunt.option('env') || 'local';

and update your build task to use config and replace:

grunt.registerTask('build', [
    'config:' + envTarget,
    'replace',
    'karma',
    'requirejs',
    'concat',
    'csso',
    'copy',
    'processhtml'
]);

Now you can run Grunt from the command-line with the new --env option:

grunt build --env=local
grunt build --env=test
grunt build --env=prod