Node.js:如何将全局变量传递到通过 require() 插入的文件中?

Posted

技术标签:

【中文标题】Node.js:如何将全局变量传递到通过 require() 插入的文件中?【英文标题】:Node.js: how do I pass global variable into a file being inserted through require()? 【发布时间】:2015-01-16 09:59:37 【问题描述】:

我已将gulpfile.js 拆分为/gulp 文件夹中的多个文件,以便更好地组织代码。但现在我想将变量debug (boolean) 传递到将切换包含的 gulp 命令的行为的文件中(最终我将使用命令行参数,但现在我只想让它与变量一起使用)。

我使用我在 yeoman angular/gulp 包中看到的方法进行此设置的方式是使用名为 require-dir 的 npm 模块(它将所有 *.js 文件加载到 /gulp 文件夹中,其中每个都有一组设置的 gulp 任务)。

gulpfile.js:

var gulp = require('gulp'),
  run = require('run-sequence'),
  debug = true;

require('require-dir')('./gulp');

gulp.task('default', ['build', 'server', 'watch', '...']);

这会加载类似...

gulp/build.js:

var gulp = require('gulp'), 
  plumber = require('gulp-plumber'),
  ...;

gulp.task('build', function () 
  console.log(debug);
);

所以当我运行命令gulp,它运行default 任务时,它将加载build.js,然后执行build gulp 任务。但不幸的是,debug 似乎返回 undefined。

我怎样才能让它工作?

我正在考虑只使用module.exports() 和节点的require() 方法,但我不知道如何在包含的文件中声明 gulp 任务,以便它可以从主 @ 运行987654334@ 文件(按所需顺序)。

谁能提供一些帮助?谢谢

【问题讨论】:

【参考方案1】:

Node.js 提供了一个名为 global 的全局变量,事实上,它在所有模块中都是相同的实例(不像 module 在每个模块中都不同)。通过在global 上设置值,它们变得真正全球化。作为额外的好处,您不需要使用global. 访问全局变量的前缀。只要在范围内没有另一个名为 foo 的变量,global.foofoo 都是等效的。

【讨论】:

这是一个非常糟糕的主意,尤其是当任何其他模块进入全局状态时。您永远不应该污染全局状态,只需让您的模块返回一个您将参数传递到其中的生成器函数,以获得您实际需要运行的完全限定函数。 虽然我当然同意您通常希望尽可能避免使用全局变量,但有时它们既有用又合适。也就是说,知道如何在 Node 中这样做很方便。 这不是这样的时代。 它们在某些情况下非常合适,例如在运行时可能会或可能不会更改但在整个应用程序中使用的变量。并非所有应用程序都是 Web 应用程序,有时它们是特定要求可能与正常意识形态不同的工作人员。因此,这是正确的答案,而不是上面 Mike 基于他的“全局是邪恶的”理论的教条式答案。如果您很懒惰并将所有内容都放在全局范围内,那么全局变量是邪恶的,但它们的存在是有原因的,而且有时需要它们的原因有很多。【参考方案2】:

正常的模块方式,真的。只需将 gulp/build.js 文件从不实际导出任何内容更改为适当的必需模块即可:

module.exports = function(debug) 
  "use strict";

  var gulp = require('gulp'), 
      plumber = require('gulp-plumber'),
      ...;

  gulp.task('build', function () 
    console.log(debug);
  );
;

然后在你的主文件中调用它:

...
var loadGulp = require('require-dir/gulp');
...
var debug = true;
loadGulp(debug);

【讨论】:

所以理论上运行loadGulp()方法后应该注册gulp任务,那么我应该可以运行gulp.start('build')并且它会可用...? 正确。 require('require-dir/gulp') 操作现在加载一个函数,并且运行该函数现在注册 gulp 任务,之后它可以像任何其他任务一样被调用。 有没有办法让 require 文件在导入时自行初始化,所以我不必调用该函数? IE。 require('gulp/build.js'); 而不是 var build = require('gulp/build.js')? ...它仍然是 javascriptrequire('./gulp/build')(debug); 工作得很好,但看起来很奇怪,所以你可能想要更改 module.exports 以返回一个对象 loadTask: function(debug) ... ; ,这样你的主代码调用看起来像 require('./gulp/build').loadTask(debug); 。眼睛更漂亮,作为代码调用更明智。 酷,require('./gulp/build').loadTask(debug); 看起来不错!感谢您的所有帮助!【参考方案3】:

我只创建了一个包含所有变量的对象,并将其导出为一个模块,这样我就可以在我的所有任务文件中使用它。例如

js/tasks/variables.js

module.exports = 
    myBool: true
;

js/tasks/sass.js

var gulp = require('gulp'),
    $ = require('gulp-load-plugins')(),
    log = $.util.log,
    vars = require('./variables');

gulp.task('sass', function () 
    log('myBool: ' + vars.myBool); // logs "myBool: true"
    vars.myBool = false;
);

js/tasks/build.js

var gulp = require('gulp'),
    $ = require('gulp-load-plugins')(),
    log = $.util.log,
    vars = require('./variables');

gulp.task('build', function () 
    log('myBool: ' + vars.myBool); // logs "myBool: false"
);

/gulpfile.js

然后你可以从任何地方获取/设置这些变量:

var gulp = require('gulp'),
    $ = require('gulp-load-plugins')(),
    runSequence = require('run-sequence'),
    vars = require('./js/tasks/variables'),
    requireDir = require('require-dir')('./js/tasks');

gulp.task('production', function()
    runSequence('sass', 'build');
);

【讨论】:

以上是关于Node.js:如何将全局变量传递到通过 require() 插入的文件中?的主要内容,如果未能解决你的问题,请参考以下文章

从 Node.js 中设置全局环境变量

如何将 node.js 变量传递/访问到 html 文件/模板

Node. js 有哪些全局对象?

如何将 node.js 服务器变量传递到我的 angular/html 视图中?

如何从回调函数中修改全局变量。在 node.js 中

Socket.io、Node.js:如何在 javascript.js 中将 javascript 变量传递给 mysql 查询?