Warning: Creating default object from empty value in /homepages/39/d161420129/htdocs/p373.net/wp/wp-content/themes/p373b/admin/functions.php on line 183
Adventures in Grunt-Land Part II: How to dynamically update files with Grunt-Replace

Adventures in Grunt-Land Part II: How to dynamically update files with Grunt-Replace

In the previous post, I went over how to setup Grunt so that you can have environment based builds.  A build for your development environment would have a destination of builds/development, builds for staging would go to builds/staging, and builds for production go to builds/production.  You get the idea.

In this post, let’s take our environment based configuration a step further, and actually update our Chrome extension manifest to have permissions based on the environment we’re building for.

In manifest.json we have:

    "permissions": ["http://localhost", "http://staging.mysite.com", "http://mysite.com"],

When a user goes to install our Chrome extension they will be able to see all of these things listed under the permissions the extension has access to communicate with.  We don’t like this.

Instead, we will use Grunt-Replace, to process our manifest file and update it with permissions that will place in our environment config.  Here is the code, and I’ll explain what’s going on below.

// manifest.json
"permissions": @@PERMISSIONS

// Gruntfile.js
grunt.initConfig({
  replace: grunt.file.readJSON('grunt/replace.json'),
})

grunt.registerTask('build', [
        'clean:dist',
        'replace:dist',        
        'chromeManifest:dist',
        'useminPrepare',
        // 'concurrent:dist',
        'notConcurrent',
        'cssmin',
        'concat',
        'uglify',
        'copy',
        'usemin',
        'replace:clean',
        'compress'
    ]);

// grunt/replace.json
{
  "dist": {
    "options": {
      "patterns": [{
        "match": "PERMISSIONS",
        "replacement": "<%= JSON.stringify(env[BUILD_ENV].permissions)%>"
      }]
    },
    "files": [
      {
        "expand": true, 
        "flatten": true, 
        "src": ["<%= yeoman.app%>/manifest.json"],
        "dest": "<%= yeoman.app %>/"
      }
    ]
  },
  "clean": {
    "options": {
        "patterns": [{
            "match": "/permissions[\\s\\S]*?\\]/",
            "replacement": "permissions\": @@PERMISSIONS",
            "expression": true
          }
        ],
        "prefix": ""
      },
      "files": [
        {
        "expand": true, 
        "flatten": true, 
        "src": ["<%= yeoman.app%>/manifest.json"],
        "dest": "<%= yeoman.app %>/"
        }
      ]
  }
}

 

First, I would like to point out that you’ll notice I’ve abstracted the replace config into a json file.  I noticed that my Gruntfile config was getting out of controller, so I think having your grunt configs in separate files underneath a grunt/ directory is a good, clean pattern.  There is a gotcha here, make sure that you use “expression”: true, and NOT “expression”: “true”.

As well, you will notice that I have two targets: dist and clean.  The chromeManifest task does its magic by reading manifest.json in the source directory, so I need to modify manifest.json in the source directory and then once chromeManifest task is completed, we need to revert it back to its original form for future tasks.  The replace:dist task modifies the manifest.json file in place, and then replace:clean, puts it back.

And there you have it, now our Chrome extension will only have permissions specified for the appropriate build.

    This entry was posted in Coding, Ruby/Rails, Technology and tagged , , . Bookmark the permalink. Both comments and trackbacks are currently closed.