节点模块的映射路径,用于单元测试

时间:2016-06-02 15:17:58

标签: javascript node.js mocha proxyquire

客户端我使用SystemJS存储模块的路径,就像这样

var systemJsConfig = {
    baseURL: "./",
    defaultJSExtensions: true,
    map: {
        'root-components': 'applicationRoot/rootComponents'
    }
};

所以require('root-components/foo');会映射到applicationRoot/rootComponents/foo

问题是,如果我在Mocha中运行带有require('root-components/foo');的模块,Node就不知道该路径的含义。是否有一种理智的方法来在Node中完成此路径映射?

Proxyquire能胜任吗?我仔细阅读了他们的文档,但没有发现任何迹象表明它是。

这仅适用于单元测试,因此我对使用任何类型的派对实用程序的任何解决方案感到满意。

3 个答案:

答案 0 :(得分:5)

如果您的唯一要求如此简单,您可以创建一个覆盖require的实用程序功能。

new require将映射应用于path参数,在新路径中查找模块,并且您可以选择回退映射路径中不存在的模块。代码应如下所示

const oldRequire = require;
require = (path) => {
    try {
        const mapped = oldRequire(path.replace('root-components/foo', 'applicationRoot/rootComponents/foo'));
        if (!mapped) {
            throw new Error('module not found in mapped directory');
        }
        console.log('module resolved with mapping', path);
        return mapped;
    } catch (e) {
        console.log('using old require without mapped path', path);
        return oldRequire(path);
    }
};

答案 1 :(得分:2)

选项1 - 修改NODE_PATH(不推荐):

修改NODE_PATH以在启动node.js之前在shell中包含模块路径。

exports NODE_PATH=./path/to/module:$NODE_PATH

这不是一个很好的选择,因为它需要一个预启动步骤 - 由于NODE_PATH包含许多路径 - 并不总是清楚模块的加载位置,并且可能存在名称冲突

选项2 - 将模块移动到外部仓库

让我们假设您将组件移动到GitHub配置文件中可用的单独“rootcomponents”存储库中。

然后您可以通过以下方式直接安装:

npm install --save github:arackaf/rootcomponents

然后,您应该能够将项目源映射到System.js别名。

var systemJsConfig = {
    baseURL: "./",
    defaultJSExtensions: true,
    map: {
        'root-components': 'github:arackaf/rootcomponents'
    }
};

从那里它应该按照你的预期工作:

require('root-components/foo');

选项3 - 通过相对路径加载模块:

config.map选项仅用于将外部依赖项映射到别名。

一个简单的替代方案是提供相对路径。亲属路径基于baseURL。

例如,如果您尝试加载:

src/rootComponents/foo.js

要求是:

require('./src/rootComponents/foo')

注意:这都假定require()语句遵循System.js模式/规则。

另一个可能的选择是提供System.paths[]选项,为本地路径创建别名。我无法验证这是否有效(即我从未尝试过),但可以找到具体信息here

答案 2 :(得分:1)

您可以通过许多不同的方式as described in this gist执行模块别名,但更简单的方法是将起始根路径设置为NODE_PATH,然后从那里开始:

这里有NODE_PATH环境变量的样子:

NODE_PATH=./src node src/server/index.js

然后在所有文件中,无论它们在层次结构中的哪个位置,都将从./src目录中解析。这消除了对您描述的别名的需求,但我意识到在您的情况下,可能需要移动/重命名许多文件。

示例:require('root-components/foo'); => ./src/root-components/foo.js