Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Grunt to preprocess and replace environment variables

I have an angular app setup that's using grunt, but I'd like to be able to use grunt as a preprocessor to replace variables and I haven't been able to find anything that matches my needs.

For instance, if I change the name of my main app module to "someAppName" in a config file, I'd like to just use something like "ENV.APP_NAME" in various html and js files and have that replaced by an appropriate value for that environment.

Ideally I'd like to have a config file somewhere along these lines, either as a .json file or using module.exports to expose an object, which specifies values for different environments:

{
    APP_NAME:{
        dev: "someAppDev",
        prod: "someApp"
    },
    API_BASE:{
        dev: "localhost:8000/",
        prod: "https://www.some-site.com/api/"
    }
}

and then I could create a grunt task and pass it either "dev" or "prod" to have it run the preprocessor and replace each instance with the corresponding value. I've found this https://github.com/STAH/grunt-preprocessor but the examples are confusing and I don't think it's quite what I'm looking for.

Is there anything like this that allows you to create preprocessed environment variables and read them from an external config file, or am I forced to build my own grunt plugin? Has anyone achieved something similar with grunt?

EDIT: I've begun building a grunt plugin for this specific task, once it's done and tested I'll post it up on npm

like image 790
ejfrancis Avatar asked Feb 07 '15 22:02

ejfrancis


2 Answers

Use grunt-ng-constant.

Npm install this plugin:

npm install grunt-ng-constant --save-dev

Then in grunt write to config file:

ngconstant: {
  // Options for all targets
  options: {
    space: '  ',
    wrap: '"use strict";\n\n {%= __ngModule %}',
    name: 'config',
  },
  // Environment targets
  development: {
    options: {
      dest: '<%= yeoman.app %>/scripts/config.js'
    },
    constants: {
      ENV: {
        myvar1: 'Hello from devel',
        myname: 'John Doe'
      }
    }
  },
  production: {
    options: {
      dest: '<%= yeoman.dist %>/scripts/config.js'
    },
    constants: {
      ENV: {
        myvar1: 'Hello',
        myname: 'John Doe'
      }
    }
  }
},

Then add to grunt task:

 grunt.task.run([
    'clean:server',
    'ngconstant:development',
    'connect:livereload',
    'watch'
  ]);

Running task would generate config.js with constants defined in gruntfile. Then add config.js to your index.html:

<script src="/scripts/config.js" />

Inject it to your app:

var app = angular.module('myApp', [ 'config' ]);

And inject into controller:

.controller('MainCtrl', function ($scope, $http, ENV) {
      console.log(ENV.myvar1);
  });

You can set different variables for production and different for development, by setting it in gruntfile and setting ng:production or ng:development.

Refer this article explaining the procedure for more information.

like image 198
changtung Avatar answered Sep 30 '22 20:09

changtung


You could do something making use of grunt-string-replace while loading some config values into Grunt from a JSON file. Suppose you had this in myconfig.json:

{
  "appName": "MyGrowth",
  "version": "1.1.2",
}

Then perhaps load the config into Gruntfile.js from JSON with something like:

grunt.initConfig({
    myConfig: grunt.file.readJSON('myconfig.json'),
// ... the rest of the stuff in your initConfig goes sure
}

Then you would have some sort of task like this maybe:

'string-replace': {
    version: {
        options: {
            replacements: [
                {
                    pattern: /MY_VERSION/ig,
                    replacement: '<%= myConfig.version %>'
                }
            ]
        },
        files: [{
          expand: true,
          cwd: 'src/',
          src: '**/*.js',
          dest: 'dist/'
        }]
    }
}

That would make actual changes to the files if you had 'src' and 'dest' in the same folder, otherwise it would put the processed files in the dest folder.

I've not actually used this recipe for preprocessing, but I use it for other types of things like replacing tags in a framework with the app name as configured in package.json.

Hope it helps.

like image 26
Michael Oryl Avatar answered Sep 30 '22 20:09

Michael Oryl