节点模块的映射路径,用于单元测试
Map paths for Node modules, for unit testing
客户端我用 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 有这个能力吗?我通读了他们的文档,但没有发现任何迹象。
这仅用于单元测试,因此我对使用任何类型的派对实用程序的任何解决方案都很满意。
您可以使用多种不同的方式为模块设置别名 as described in this gist,但更简单的方法是使用 NODE_PATH
设置起始根路径,然后从那里开始:
下面是 NODE_PATH
环境变量的样子:
NODE_PATH=./src node src/server/index.js
那么在你的所有文件中,无论它们在层次结构中的什么位置,都将从 ./src
目录中解析。这消除了对您描述的别名的需要,但我意识到在您的情况下,可能需要 moving/renaming 许多文件。
示例:require('root-components/foo');
=> ./src/root-components/foo.js
选项 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 patterns/rules.
之后
另一种可能的选择是提供一个 System.paths[]
选项来创建本地路径的别名。我无法验证 how/whether 这是否有效(即我从未尝试过)但可以找到具体细节 here
如果您的唯一要求很简单,您可以创建一个实用函数来覆盖 require
。
新要求将映射应用于路径参数,在新路径中查找模块,您可以选择回退映射路径中不存在的模块。代码应该是这样的
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);
}
};
客户端我用 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 有这个能力吗?我通读了他们的文档,但没有发现任何迹象。
这仅用于单元测试,因此我对使用任何类型的派对实用程序的任何解决方案都很满意。
您可以使用多种不同的方式为模块设置别名 as described in this gist,但更简单的方法是使用 NODE_PATH
设置起始根路径,然后从那里开始:
下面是 NODE_PATH
环境变量的样子:
NODE_PATH=./src node src/server/index.js
那么在你的所有文件中,无论它们在层次结构中的什么位置,都将从 ./src
目录中解析。这消除了对您描述的别名的需要,但我意识到在您的情况下,可能需要 moving/renaming 许多文件。
示例:require('root-components/foo');
=> ./src/root-components/foo.js
选项 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 patterns/rules.
另一种可能的选择是提供一个 System.paths[]
选项来创建本地路径的别名。我无法验证 how/whether 这是否有效(即我从未尝试过)但可以找到具体细节 here
如果您的唯一要求很简单,您可以创建一个实用函数来覆盖 require
。
新要求将映射应用于路径参数,在新路径中查找模块,您可以选择回退映射路径中不存在的模块。代码应该是这样的
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);
}
};