检查 node.js 模块是否可用。

28
我正在寻找一种方法来确定模块是否可用。例如,我想以编程方式检查是否可用mongodb模块。同时,如果未找到模块,程序不应该停止,我希望自己处理这个问题。
注:我添加了这个问题是因为谷歌没有提供有用的结果。
6个回答

30

如果你只想检查一个模块是否可用(但不需要在其未加载时加载它),有一种更巧妙的方法:

如果你只想检查一个模块是否可用(但不需要在其未加载时加载它),有一种更巧妙的方法:

function moduleAvailable(name) {
    try {
        require.resolve(name);
        return true;
    } catch(e){}
    return false;
}

if (moduleAvailable('mongodb')) {
    // yeah we've got it!
}

17
这是我发现的最聪明的方法来做到这一点。如果有更好的方法,请指出。
var mongodb;
try {
    mongodb = require( 'mongodb' );
}
catch( e ) {
    if ( e.code === 'MODULE_NOT_FOUND' ) {
        // The module hasn't been found
    }
}

5
使用这个的时候要小心自己的模块。如果一个嵌套的 require 失败了,就会调用 MODULE_NOT_FOUND。为了避免这种情况,可以在消息上使用正则表达式来检查哪个模块没有找到。最好将实际的错误信息打印到控制台上。首先使用 require.resolve 可以避免这种情况。 - vaughan
如果不是MODULE_NOT_FOUND,重新抛出错误会更好,不是吗? - Jasper

1

对于 ECMAScript 模块(ESM),自从 Node 12 版本以来,import 关键字也可以被用作函数返回一个 Promise

import("mongodb")
  .then(mongodb => {
    // use module
  })
  .catch(e => console.error(e)) // The module hasn't been found

或者

async main() {
  const mongodb = import("mongodb")
  // use module
}

main().catch(e => console.error(e)) // module hasn't been found or other error

0

也许类似于resolve的模块会对这里有所帮助?

在npm上存在大量的模块:

我首先写了async-resolve,例如:

var Resolver = require('async-resolve');
var resolver_obj = new Resolver();
resolver_obj.resolve('module', __dirname, function(err, filename) {
  return console.log(filename);
});

它使用node模块路径解析规则,但不像node那样阻塞主循环。结果你会得到文件名,因此可以用来决定它是本地模块还是全局模块以及其他事情。


0

使用一行代码的ES6简单解决方案:

const path = require('path');
const fs = require('fs');

function hasDependency(dep) {
        return module.paths.some(modulesPath => fs.existsSync(path.join(modulesPath, dep)));
}

4
请在回答中添加一些代码注释或描述性文本来解释您的答案。许多技能水平的人都会看到这个,如果有解释会更容易理解。 - Brody

-9

使用ES6箭头函数

var modulePath = m => { try { return require.resolve(m) } catch(e) { return false } }

4
使用ES6箭头函数的优势是什么?值得为此回答一个三年前的问题吗? - Florian Margaine
1
@Florian Margaine 箭头函数的优点在于所有工作都可以在一行代码中完成。 - pravdomil
4
当您在单行中使用try/catch时,那并不是一个优势。千万不要这样做。认真对待此事。 - Florian Margaine
@Florian Margaine 现在怎么样? - pravdomil
5
如果没有优势可言,那么就没有使用箭头函数的必要。 - Florian Margaine

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