是否有任何通用的方法来识别Node.js中的本机函数?
例如,要在浏览器中测试本机功能,我会使用此功能 -
function isNative(fn) {
return (/{\s*[native code]\s*}/).test('' + fn);
}
我们可以使用类似的东西来检测本地Node.js函数,例如fs.readFile等等吗?
我想一种方法是在程序启动之前检查缓存GLOBAL变量中可用的函数,是否有更优雅的方法?
谢谢!
答案 0 :(得分:0)
问题是节点的内置函数在技术上是非本机的(对于v8)。唯一的方法是检查函数原始文件名:
var FunctionOrigin = require('function-origin');
var natives = process.binding('natives');
function isNative(fn) {
var file = FunctionOrigin(fn).file;
var noExt = file.slice(0, file.length - 3);
return natives.hasOwnProperty(noExt);
}
function Test(){}
console.log(isNative(require('fs').readFile));
console.log(isNative(Test));
答案 1 :(得分:-1)
解决方案的另一种可能的方法(并且绝对不是优雅'):检查所有标准Node.js包及其功能名称(我从Node准备了v0.10.35的标准模块列表。根据Node' s recomendations on Core Modules)的js github /lib
文件夹。
不幸的是,Node.js不会在require.cache
中保存有关已加载核心模块的信息,因此无法通过这种方式检测它们。
函数testNative()检测几乎所有本地的'函数,除了require()(可能还有一些其他函数在JavaScript上编写并位于Node.js模块之外)。
评论:
因此,仅当您始终对库变量使用标准变量名时,测试函数才有效:
var fs = require('fs'); // good
var myfs = require('fs'); // bad
更新: 这个丑陋的部分可以替换为 process.moduleList 的分析。
代码:
function testNative(fn) {
if(!!fn.toString().match(/{\s*\[native code\]\s*}/)) return true;
var std_modules = ['assert','buffer','child_process','cluster','console','constants',
'crypto','dgram','dns','domain','events','freelist','fs','http','https','module',
'net','os','path','punycode','querystring','readline','repl','smalloc','stream',
'string_decoder','sys','timers','tls','tracing','tty','url','util','vm','zlib',
'Math','JSON'];
var native_fns = [];
for(var i=0; i<std_modules.length;i++) {
try {
var module = eval(std_modules[i]);
native_fns.push(module);
if(module) {
for(var k in module) {
native_fns.push(module[k]);
}
}
} catch (err) {}
}
return native_fns.indexOf(fn) > -1;
}
// Test
function foo() {return 1};
var fs = require('fs');
console.log(testNative(fs.readFile)); // true
console.log(testNative(foo)); // false
console.log(testNative(JSON.stringify)); // true