Node.js 列出文件中所需的所有模块

4

我可能漏掉了什么。我有一个mocha测试文件,像这样设置:

require('globals');
var library1 = require('library1'),
  library2 = require('library2');

it('tests stuff', function() {
  ...
});

这里的 globals 文件只包含一个 beforeafterEach 块,因此它们适用于我所有的测试文件。

我的目标是在 beforeafterEach 块内确定当前正在运行的测试文件中我所 require 的哪些文件。所以在我给出的示例测试文件中,我需要 afterEach 输出一个列表,其中包含 globalslibrary1library2

我尝试使用 Node.js 的 module.children 属性,但由于某种原因它仅返回 globals,并排除了 library1library2

编辑:我错过了什么导致 module.children 没有返回 library1library2


你尝试过使用 require.cache 吗?https://nodejs.org/docs/latest/api/globals.html#globals_require_cache - Rax Wunter
我确实尝试过那个,但它给了我一个所有已经被require的列表,而不仅仅是针对那个特定文件,所以对我来说并不是很有用。 - Ryan McDonald
你可以解析文件并查找 require 语句,并复制括号内的内容。 - Gabs00
你还有其他需要知道已经被引用的文件的操作吗? - Gabs00
我有一些自定义库,它们被包含在我的测试中。根据哪些测试文件包含哪个库,我想执行某些清理操作。 - Ryan McDonald
2个回答

2
这是一个解析文件中所需内容的脚本示例。
var fs = require('fs');

function parseRequires(absPath){
    var requiredFiles = [];
    var contents = fs.readFileSync(absPath, 'utf8').split('\n');

    contents.forEach(function(line){
        var re = /(?:require\('?"?)(.*?)(?:'?"?\))/;
        var matches = re.exec(line);

        if(matches){
            requiredFiles.push(matches[1]);
        }

    });

    return requiredFiles;

}

module.exports = parseRequires;

我在同一目录下创建了一个测试脚本

var fs = require('fs');
var os = require('os');

function A(){}

var http = require("http");

var parseRequires = require("./parseRequires");

console.log( parseRequires( __dirname + '/testRequires.js') );

控制台输出结果:[ 'fs', 'os', 'http', './parseRequires' ]

这是其中一种解决方法,尽管我相信使用nodejs内置功能应该有更简单的方式。


谢谢!我可能不得不采用这种方法,但我更好奇的是为什么module.children没有包括我放入变量中的require - Ryan McDonald
@RJMcdonald,这个最终对你有帮助了吗?还是你找到了更好的解决方案?如果是,请发布出来。 - Gabs00
我一直找不到更好的解决方案。module.children 应该返回所有的 requires,但出于某种原因,它不喜欢那些被设置为变量的 requires,所以我希望有人能告诉我我错过了什么。 - Ryan McDonald
@RJMcDonald 我似乎只能看到非 Node.js 内置模块。这些是必需的吗? - Gabs00
我对Node.js内置模块不感兴趣。 - Ryan McDonald

2

我想分享另一种使用require.cache的解决方案。它涉及解析require.cache以查找已经被引用的文件,并提供最终被引用的文件名称。

var someModule = require('./someModule');
var path = require('path');
for( var p in require.cache){
  console.log( trim( p ) );
}

function trim(p){
  var re = /(.*?).js/;
  var basename = path.basename( p );
  var moduleName = re.exec( basename )[1];
  return moduleName; 
}

测试文件:

someModule.js

var fs = require('fs');
var os = require('os');
var _ = require('lodash');
var test = require('./test');

test.js

var a = require('lodash'),
jQuery = require('jquery');

运行getRequires.js会得到以下结果:

getRequires
someModule
index
test
jquery

请注意,它包含了自身,因此还需要有一些东西将其修剪掉。

同时注意到index,这来自于lodash库。

下面是一个修改示例,可以显示文件路径。

var someModule = require('./someModule');
var path = require('path');
for( var p in require.cache){
  console.log( trim( p ) );
}

function trim(p){
  var re = /(.*?).js/;
  var basename = path.basename( p );
  var moduleName = re.exec( basename )[1];
  return [ moduleName, p ]; 
}

这使我们得到了:
[ 'getRequires',
  '/<myroot>/require/getRequires.js' ]

[ 'someModule',
  '/<myroot>/require/someModule.js' ]

[ 'index',
  '/<myroot>/require/node_modules/lodash/index.js' ]

[ 'test', '/<myroot>/require/test.js' ]

[ 'jquery',
  '/<myroot>/require/node_modules/jquery/dist/jquery.js' ]

require是我编写代码的目录。

请告诉我您对此解决方案的想法。还有更多工作要做,但我认为这可以让您开始。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接