davetgreen
davetgreen

Reputation: 109

Making a config change visible to subsequent tasks

Using: Grunt 1.01, load-grunt-config, jit-grunt.

I'm looking to put a simple means of setting a development/production flag in place for use in certain Grunt tasks.

The first task that needs the flag is webpack.js, in order to switch between the development and production builds of React. Here's that file:

module.exports = function( grunt ) {

    // Get the task that was invoked from the command line.
    var theTask = process.argv[2];

    // Check to see if it's a production task. If so, change the
    // `env` variable accordingly.
    if ( theTask !== undefined && theTask.indexOf('prod') === 0 ) {
        grunt.config.set('env', 'production');
    }

    return {
        app: {
            entry: './<%= siteInfo.build_dir %>/<%= siteInfo.temp_dir %>/<%= siteInfo.app_dir %>/<%= siteInfo.app_file %>.js',
            output: {
                path: '<%= siteInfo.build_dir %>/<%= siteInfo.temp_dir %>',
                filename: '<%= siteInfo.bundle_file %>.tmp.js'
            },
            stats: false,
            failOnError: true,
            progress: false,
            plugins: [
              new webpack.DefinePlugin({
                'process.env.NODE_ENV': JSON.stringify(grunt.config.data.env)
              }),
            ]
        }
    }

};

In the context of this task, it works perfectly. If I run grunt prod then the correct version of React is being included in the bundled JS.

However, I was under the (most certainly) mistaken impression that by setting the env variable using grunt.config.set this update to Grunt's config object would then be available to subsequent tasks.

As I've found out, env is undefined if I console.log(grunt.config.data.env) in another task.

Any pointers or suggestions of alternative approaches appreciated!

Upvotes: 0

Views: 39

Answers (1)

theaccordance
theaccordance

Reputation: 889

Instead of returning the config, try this:

Create a pre-build task which sets any config/options prior to running your tasks. You can check if the task is prod or not by checking this.name, and then since it's a simple value, set it using grunt.option:

function preBuild() {

    grunt.option('env', this.name === 'prod' ? 'production' : 'development');
    grunt.task.run(['task1', 'task2', task3']);
}

grunt.registerTask('prod', preBuild);
grunt.registerTask('dev', preBuild);

Using a lo-dash template, you can pass the option value to your config. Grunt compiles the lo-dash template strings when the task accessing it is run:

grunt.initConfig({
    app: {
        entry: './<%= siteInfo.build_dir %>/<%= siteInfo.temp_dir %>/<%= siteInfo.app_dir %>/<%= siteInfo.app_file %>.js',
        output: {
            path: '<%= siteInfo.build_dir %>/<%= siteInfo.temp_dir %>',
            filename: '<%= siteInfo.bundle_file %>.tmp.js'
        },
        stats: false,
        failOnError: true,
        progress: false,
        plugins: [
          new webpack.DefinePlugin({
            'process.env.NODE_ENV': "<%= grunt.option('env') %>"
          }),
        ]
    }
});

Upvotes: 1

Related Questions