2

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

之所以喜欢这个,是因为我使用了 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=production(set适用于 Windows ),任何地方production都会像我希望的那样回显 value 。

4

2 回答 2

0

您的测试将不起作用,因为grunt-shell运行child_process并且您的回调在它结束后运行并在主进程下运行。cross-env
也会发生同样的事情。

如果要将环境变量传递给grunt-shell,则应根据文档使用选项配置。 例如:

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

这仍将打印undefined为,process.env.NODE_ENV但由于.NODE_ENVstdoutecho

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

于 2017-07-21T15:55:36.873 回答
0

LifeQuery 的回答对我找出问题所在有很大帮助。我首先意识到这webpack.DefinePlugin()实际上并没有改变任何东西process.env.NODE_ENV无论如何都为时已晚,因为它会在所有加载程序之后转换由 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.initConfig(),因此配置对象可以使用process.env.NODE_ENV所需的状态。

如果明确启动、、或任务,或与目标的任何其他任务,它将设置NODE_ENV为“开发” 。webpack-dev-serverdevhmrwatch:dev

于 2017-07-26T10:38:37.693 回答