【发布时间】:2014-10-09 13:07:46
【问题描述】:
我在我的项目中使用npm 模块grunt env 和load-grunt-config。 grunt env 为您处理环境变量,而load-grunt-config 处理,好吧,为您加载grunt 配置。您可以将您的任务放入其他文件,然后load-grunt-config 将它们捆绑起来并让grunt 为您加载和使用它们。您还可以创建一个aliases.js 文件,其中包含您想要组合成一个任务的任务,一个接一个地运行。它类似于原始Gruntfile.js 中的grunt.registerTask 任务。正如 Github 上的 load-grunt-config README.md 所建议的,我将所有 grunt 任务放在根文件夹下的一个单独的 grunt/ 文件夹中,主文件夹 Gruntfile 没有额外的子文件夹。这是我瘦身后的Gruntfile:
module.exports = function(grunt) {
'use strict';
require('time-grunt')(grunt);
// function & property declarations
grunt.initConfig({
pkg: grunt.file.readJSON('package.json')
});
require('load-grunt-config')(grunt, {
init: true,
loadGruntConfig: {
scope: 'devDependencies',
pattern: ['grunt-*', 'time-grunt']
}
});
};
理论上,将所有这些文件设置为load-grunt-config 加载的正确方式应该与仅使用Gruntfile.js 完全相同。然而,我似乎遇到了一些障碍。在env 任务下设置的环境变量似乎不会为后续的grunt 任务设置,而是在node 处理其任务时设置,在本例中是express 服务器。
grunt env任务:
module.exports = {
// environment variable values for developers
// creating/maintaining site
dev: {
options: {
add: {
NODE_ENV: 'dev',
MONGO_PORT: 27017,
SERVER_PORT: 3000
}
}
}
};
// shell command tasks
module.exports = {
// starts up MongoDB server/daemon
mongod: {
command: 'mongod --bind_ip konneka.org --port ' + (process.env.MONGO_PORT || 27017) + ' --dbpath C:/MongoDB/data/db --ipv6',
options: {
async: true, // makes this command asynchronous
stdout: false, // does not print to the console
stderr: true, // prints errors to the console
failOnError: true, // fails this task when it encounters errors
execOptions: {
cwd: '.'
}
}
}
};
module.exports = {
// default options
options: {
hostname: '127.0.0.1', // allow connections from localhost
port: (process.env.SERVER_PORT || 3000), // default port
},
prod: {
options: {
livereload: true, // automatically reload server when express pages change
// serverreload: true, // run forever-running server (do not close when finished)
server: path.resolve(__dirname, '../backend/page.js'), // express server file
bases: 'dist/' // watch files in app folder for changes
}
}
};
aliases.js 文件(grunt-load-config 组合任务的方式,使它们一个接一个地运行):
module.exports = {
// starts forever-running server with "production" environment
server: ['env:prod', 'shell:mongod', 'express:prod', 'express-keepalive']
};
backend/env/prod.js 的一部分(特定于环境的 Express 配置,如果 NODE_ENV 设置为“prod”则加载,模仿 MEAN.JS):
'use strict';
module.exports = {
port: process.env.SERVER_PORT || 3001,
dbUrl: process.env.MONGOHQ_URL || process.env.MONGOLAB_URI || 'mongodb://konneka.org:' + (process.env.MONGO_PORT || 27018) + '/mean'
};
backend/env/dev.js 的一部分(dev 环境的特定环境 Express 配置,如果 `NODE_ENV 变量未设置或设置为“dev”,则加载):
module.exports = {
port: process.env.SERVER_PORT || 3000,
dbUrl: 'mongodb://konneka.org:' + (process.env.MONGO_PORT || 27017) + '/mean-dev'
};
backend/page.js 的一部分(我的 Express 配置页面,也是仿照 MEAN.JS):
'use strict';
var session = require('express-session');
var mongoStore = require('connect-mongo')(session);
var express = require('express');
var server = express();
...
// create the database object
var monServer = mongoose.connect(environ.dbUrl);
// create a client-server session, using a MongoDB collection/table to store its info
server.use(session({
resave: true,
saveUninitialized: true,
secret: environ.sessionSecret,
store: new mongoStore({
db: monServer.connections[0].db, // specify the database these sessions will be saved into
auto_reconnect: true
})
}));
...
// listen on port related to environment variable
server.listen(process.env.SERVER_PORT || 3000);
module.exports = server;
当我运行grunt server 时,我得到:
$ cd /c/repos/konneka/ && grunt server
Running "env:prod" (env) task
Running "shell:mongod" (shell) task
Running "express:prod" (express) task
Running "express-server:prod" (express-server) task
Web server started on port:3000, hostname: 127.0.0.1 [pid: 3996]
Running "express-keepalive" task
Fatal error: failed to connect to [konneka.org:27018]
Execution Time (2014-08-15 18:05:31 UTC)
loading tasks 38.3s █████████████████████████████████ 79%
express-server:prod 8.7s ████████ 18%
express-keepalive 1.2s ██ 2%
Total 48.3s
现在,我一开始似乎无法连接数据库,但暂时忽略它。请注意,服务器在端口 3000 上启动,这意味着在执行 grunt express:prod 任务期间,未设置 SERVER_PORT,因此端口设置为 3000。还有许多其他类似的示例,其中未设置环境变量所以我的应用程序使用默认值。但是,请注意 session 尝试连接到端口 27018 上的数据库(并且失败),因此 MONGO_PORT 最终会被设置。
如果我刚刚尝试了 grunt server 任务,我可以将其归结为 load-grunt-config 并行运行任务,而不是一个接一个地运行任务或其他错误,但即使我一个接一个地尝试任务一个,例如运行grunt env:prod shell:mongod express-server:prod express-keepalive,我得到类似(不正确)的结果,所以grunt 或grunt env 也并行运行任务,或者正在发生其他事情。
这里发生了什么?为什么没有为后面的grunt 任务正确设置环境变量?它们最终是在什么时候设置的,为什么然后而不是其他时间?假设甚至有办法,我怎样才能让他们自己为grunt 任务而不是之后设置?
【问题讨论】:
-
我正在为此编写一个完整的测试用例,但我最初的想法是
grunt env只是在 grunt 执行完所有任务后才设置环境变量。可能的解决方案是将 env 任务合并到其他任务中。 -
我正在尝试合并这些任务。这就是为什么我使用
load-grunt-config和grunt自己的方法,如registerTask。但我知道你的意思,我想我稍后会尝试。 -
我们能否得到
tree的输出(或了解图片中的文件和文件夹)? -
我在 Windows 上使用 mSysGit。还有其他方法吗?根据
load-grunt-config的建议,我将grunt任务放入单独的grunt/文件夹中。没有子文件夹,只有grunt/文件夹。 -
@Whymarrh,我刚刚将它添加到问题中。我道歉,我想我认为这对这个问题并不重要,或者“每个人都这样做”。我会学习吗?我还认为这会给问题增加太多内容。
标签: javascript node.js express gruntjs environment-variables