从 Grunt 任务设置 NODE_ENV
Set NODE_ENV from Grunt task
我想在一个Grunt任务开始时设置NODE_ENV变量为development
或production
,但看起来并没有我想的那么简单。
我喜欢这个的原因是我使用 grunt-webpack,它期望 NODE_ENV 正确设置为 "development" 或 "production"。但如果可能的话,我也想专门从 grunt 初始化我的任务。
我使用 grunt-shell and cross-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
,正如我希望的那样到.
您的测试将无法运行,因为 grunt-shell runs a child_process 和您的回调 运行 在它结束后并在主进程下。
cross-env.
也会发生同样的事情
如果你想传递一个环境变量给grunt-shell
,你应该使用options configuration according to the documentation.
例如:
grunt.initConfig({
shell: {
dev: {
command : 'echo %NODE_ENV%', //windows syntax
options: {
execOptions: {
env: {
'NODE_ENV': 'dev'
}
},
callback: log
}
}
}
});
这仍然会为 process.env.NODE_ENV
打印 undefined
,但是 NODE_ENV
的值将在 stdout
中可用,因为 echo
。
附带说明一下,听起来您正在尝试 运行 一个进程 (grunt-shell
),而 运行 是一个进程 (cross-env
),这运行是一个进程(webpack
或 grunt-webpack
)。
为什么不直接使用 cross-env
example usage?它看起来非常接近您的需要。
或者您可以只在任务 config 本身中定义变量并丢失所有这些包装器。
LifeQuery 的回答对我找出问题所在有很大帮助。我首先意识到 webpack.DefinePlugin()
实际上 doesn't change anything 在 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 任务名称和目标的白名单。由于它位于 grunt.initConfig()
之前,配置对象可以使用具有所需状态的 process.env.NODE_ENV
。
如果确定开始 webpack-dev-server
、dev
、hmr
或 watch
任务或任何其他任务,它将 NODE_ENV
设置为 "development" :dev
目标的任务。
我想在一个Grunt任务开始时设置NODE_ENV变量为development
或production
,但看起来并没有我想的那么简单。
我喜欢这个的原因是我使用 grunt-webpack,它期望 NODE_ENV 正确设置为 "development" 或 "production"。但如果可能的话,我也想专门从 grunt 初始化我的任务。
我使用 grunt-shell and cross-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
,正如我希望的那样到.
您的测试将无法运行,因为 grunt-shell runs a child_process 和您的回调 运行 在它结束后并在主进程下。
cross-env.
如果你想传递一个环境变量给grunt-shell
,你应该使用options configuration according to the documentation.
例如:
grunt.initConfig({
shell: {
dev: {
command : 'echo %NODE_ENV%', //windows syntax
options: {
execOptions: {
env: {
'NODE_ENV': 'dev'
}
},
callback: log
}
}
}
});
这仍然会为 process.env.NODE_ENV
打印 undefined
,但是 NODE_ENV
的值将在 stdout
中可用,因为 echo
。
附带说明一下,听起来您正在尝试 运行 一个进程 (grunt-shell
),而 运行 是一个进程 (cross-env
),这运行是一个进程(webpack
或 grunt-webpack
)。
为什么不直接使用 cross-env
example usage?它看起来非常接近您的需要。
或者您可以只在任务 config 本身中定义变量并丢失所有这些包装器。
LifeQuery 的回答对我找出问题所在有很大帮助。我首先意识到 webpack.DefinePlugin()
实际上 doesn't change anything 在 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 任务名称和目标的白名单。由于它位于 grunt.initConfig()
之前,配置对象可以使用具有所需状态的 process.env.NODE_ENV
。
如果确定开始 webpack-dev-server
、dev
、hmr
或 watch
任务或任何其他任务,它将 NODE_ENV
设置为 "development" :dev
目标的任务。