有一些第三方Javascript库具有一些我想在Node.js服务器中使用的功能。(具体地说,我想使用我找到的QuadTree javascript库。)但这些库只是简单的.js
文件,而不是"Node.js库“。
因此,这些库不遵循Node.js期望其模块使用的exports.var_name
语法。据我所知,这意味着当你做module = require('module_name');
或module = require('./path/to/file.js');
时,你最终会得到一个没有公开可访问函数的模块,等等。
我的问题是“如何将任意的javascript文件加载到Node.js中,这样我就可以利用它的功能,而不必重写它,这样它就可以执行exports
了?”
我是Node.js的新手,所以如果我对它的工作原理有什么明显的理解,请告诉我。
编辑:进一步研究,我现在发现Node.js使用的模块加载模式实际上是最近开发的用于加载CommonJS库的标准的一部分。它在module doc page for Node.js上显示了这一点,但直到现在我都没有看到。
结果可能是,我的问题的答案是“等你的库的作者抽出时间来编写CommonJS接口,或者自己来做。”
发布于 2012-01-11 02:05:05
有一种比使用eval
更好的方法:vm
模块。
例如,下面是我的execfile
模块,它在context
或全局上下文中评估path
上的脚本:
var vm = require("vm");
var fs = require("fs");
module.exports = function(path, context) {
context = context || {};
var data = fs.readFileSync(path);
vm.runInNewContext(data, context, path);
return context;
}
它可以像这样使用:
> var execfile = require("execfile");
> // `someGlobal` will be a global variable while the script runs
> var context = execfile("example.js", { someGlobal: 42 });
> // And `getSomeGlobal` defined in the script is available on `context`:
> context.getSomeGlobal()
42
> context.someGlobal = 16
> context.getSomeGlobal()
16
其中,example.js
包含:
function getSomeGlobal() {
return someGlobal;
}
这种方法的最大优点是,您可以完全控制执行脚本中的全局变量:您可以传入自定义全局变量(通过context
),并且脚本创建的所有全局变量都将添加到context
中。调试也更容易,因为将使用正确的文件名报告语法错误等。
发布于 2011-03-08 05:53:22
这是我认为对这种情况最“正确”的答案。
假设您有一个名为quadtree.js
的脚本文件。
您应该构建一个具有这种目录结构的自定义node_module
...
./node_modules/quadtree/quadtree-lib/
./node_modules/quadtree/quadtree-lib/quadtree.js
./node_modules/quadtree/quadtree-lib/README
./node_modules/quadtree/quadtree-lib/some-other-crap.js
./node_modules/quadtree/index.js
./node_modules/quadtree/quadtree-lib/
目录中的所有内容都是来自第三方库的文件。
然后,您的./node_modules/quadtree/index.js
文件将从文件系统中加载库,并完成正确导出内容的工作。
var fs = require('fs');
// Read and eval library
filedata = fs.readFileSync('./node_modules/quadtree/quadtree-lib/quadtree.js','utf8');
eval(filedata);
/* The quadtree.js file defines a class 'QuadTree' which is all we want to export */
exports.QuadTree = QuadTree
现在您可以像使用任何其他节点模块一样使用您的quadtree
模块……
var qt = require('quadtree');
qt.QuadTree();
我喜欢这种方法,因为它不需要去修改你的第三方库的任何源代码--所以它更容易维护。在升级时,您所需要做的就是查看它们的源代码,并确保您仍在导出正确的对象。
发布于 2012-03-22 21:31:12
最简单的方法是:eval(require('fs').readFileSync('./path/to/file.js', 'utf8'));
这非常适合在交互式外壳中进行测试。
https://stackoverflow.com/questions/5171213
复制相似问题