从Grunt任务设置NODE_ENV

时间:2017-07-07 10:46:31

标签: node.js webpack gruntjs grunt-shell

我想在Grunt任务开始时将NODE_ENV变量设置为developmentproduction,但它看起来并不像我想象的那么简单。

原因,为什么我希望这是因为我使用grunt-webpack,它希望NODE_ENV正确设置为“开发”或“生产”。但是如果可能的话,我也想完全从grunt初始化我的任务。

我使用grunt-shellcross-env模块创建了以下测试Gruntfile:

function log(err, stdout, stderr, cb, e) {
    if (err) {
        cb(err);
        return;
    }

    console.log(process.env.NODE_ENV);
    console.log(stdout);
    cb();
}

module.exports = function(grunt) {

    grunt.initConfig({
        shell: {
            dev: {
                command : 'cross-env NODE_ENV="development"',
                options: {
                    callback: log
                }
            },
            dist: {
                command : 'cross-env NODE_ENV="production"',
                options: {
                    callback: log
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-shell');

};

log()的第6行应该回显process.env.NODE_ENV的实际值,但它会不断地说undefined,即使我在节点控制台中手动检查它。

如果我是从终端手动设置的,例如set NODE_ENV=productionset适用于Windows),那么无处不在回报值production,就像我希望的那样。

2 个答案:

答案 0 :(得分:0)

您的测试无效,因为grunt-shell运行child_process并且您的回调在结束后并在主进程下运行。
cross-env会发生同样的事情。

如果您想将环境变量传递给grunt-shell,则应根据options使用documentation配置。
例如:

grunt.initConfig({
    shell: {
        dev: {
            command : 'echo %NODE_ENV%', //windows syntax
            options: {
                execOptions: {
                    env: {
                        'NODE_ENV': 'dev'
                    }
                },
                callback: log
            }
        }
    }
});

这仍然会为undefined打印process.env.NODE_ENV,但由于NODE_ENVstdout的值echo会显示{/ 1}}。

在旁注中,听起来您正在尝试运行一个流程(grunt-shell),该流程运行流程(cross-env),该流程运行流程(webpackgrunt-webpack)。
为什么不使用cross-env example usage?它看起来非常接近你需要的东西 或者您可以在任务config本身中定义变量并丢失所有这些包装器。

答案 1 :(得分:0)

LifeQuery的答案帮助我找到了问题的真正含义。我首先在webpack.DefinePlugin()上意识到process.env.NODE_ENV实际上是doesn't change anything(无论如何都会为时已晚,因为它会在所有加载器之后转换由webpack解析的代码)。

在此之后我创建了一个解决方案,它可以满足我的需求。这就是我定制的Gruntfile.js的开始:

'use strict';

const path = require('path');
const webpack = require('webpack');

module.exports = function (grunt) {

    // Setting the node environment based on the tasks's name or target
    let set_NODE_ENV = function () {
        const devTasks = ['webpack-dev-server', 'dev', 'hmr', 'watch'],
            devTargets = [':dev'],
            task = grunt.cli.tasks[0], // The name of the (first) task we initialized grunt with ('webpack-dev-server' if started 'grunt webpack-dev-server)
            target = ':'+grunt.option('target'),
            devEnv = (devTasks.indexOf(task) > -1 || devTargets.indexOf(target) > -1);

        process.env.NODE_ENV = devEnv ? 'development' : 'production';
    }();

    const webpackConfig = require('../assets/webpack.config');

    grunt.initConfig({
        // ...usual Gruntfile content
    });

};

我在设置process.env.NODE_ENV时创建了一个由grunt任务名称和目标组成的白名单。当它放在grunt.initConfig()之前时,配置对象可以使用具有所需状态的process.env.NODE_ENV

如果明确启动NODE_ENVwebpack-dev-serverdevhmr任务,或watch的任何其他任务,它会将:dev设置为“开发” {1}}目标。

相关问题