Jas*_*son 11 module node.js typescript ts-node
我在TypeScript中有一个项目,它使用了我在计算机上无法访问的几个API(它们存在于Web上).代码将在本地编译良好,因为我在foo.d.ts文件中有所有API ,因此系统知道它们存在于某处.
但是,我想用NodeJS应用程序对代码的部分单元进行单元测试.我可以很好地将代码导入节点,但每当我到达从定义文件导入模块的代码时,我都会收到以下错误:
Error: Cannot find module 'messages'
at Function.Module._resolveFilename (module.js:527:15)
at Function.Module._load (module.js:476:23)
at Module.require (module.js:568:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (~/dev/repos/sample_typescript_fail/App.js:3:18)
at Module._compile (module.js:624:30)
at Object.Module._extensions..js (module.js:635:10)
at Module.load (module.js:545:32)
at tryModuleLoad (module.js:508:12)
at Function.Module._load (module.js:500:3)
...
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为该代码仅在本地定义,并且不存在.
我可以手动将模块注册到NodeJS,比如
Registry.register('messages', () => {...});
Run Code Online (Sandbox Code Playgroud)
这样我就可以用polyfill进行编译和测试?
package.json
{
"name": "sample_typescript_declare_issue",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"scripts": {
"start": "ts-node index.ts"
},
"author": "",
"license": "MIT"
}
Run Code Online (Sandbox Code Playgroud)
index.ts
import {App} from "./App";
console.log("Starting program");
// How do I fake "import {MessageSender} from "messages";"
// here so that I can run this node app as a test?
let app: App = new App();
console.log("Ending program");
Run Code Online (Sandbox Code Playgroud)
App.ts
import {MessageSender} from "messages";
export class App {
constructor() {
let messageSender: MessageSender = new MessageSender();
messageSender.sendMessage("foo!");
}
}
Run Code Online (Sandbox Code Playgroud)
node_modules/@types/messages/index.d.ts
export = Messages;
export as namespace Messages;
declare module Messages {
class MessageSender {
constructor();
sendMessage(message: any): void;
}
}
Run Code Online (Sandbox Code Playgroud)
运行with npm start会给出上面的错误消息.
运行tsc *.tsc编译就好了.
更新package.json以包含bin:
{
"name": "sample_typescript_declare_issue",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"scripts": {
"start": "ts-node index.ts"
},
"author": "",
"license": "MIT",
"bin": {
"messages": "./polyfills/messages/index.ts"
}
}
Run Code Online (Sandbox Code Playgroud)正如您所提到的,编译工作正常 - 这只是.d.ts文件可用性的问题。
你想要做的是在运行时改变模块导入,换句话说,改变nodejsrequire函数的行为,因为
import {MessageSender} from "messages";
Run Code Online (Sandbox Code Playgroud)
将在 javascript (ES6) 中转译为类似的内容
const messages_1 = require("messages");
...
messages_1.MessageSender
Run Code Online (Sandbox Code Playgroud)
要修改该行为,首先想到的是使用已弃用但仍然可用的 require.extensions对象。
在本地运行时,您必须首先注入类似的东西
require.extensions['.js'] = (module, filename) => {
if (filename === 'messages') {
// then load mock module/polyfill using the passed module object
// see (https://nodejs.org/api/modules.html#modules_the_module_object)
}
};
Run Code Online (Sandbox Code Playgroud)
医生说有更好的替代方案,但没有明确提及。
另一种可能性是查看像sandboxed-module这样的项目,这应该会有所帮助(我还没有测试过)
| 归档时间: |
|
| 查看次数: |
806 次 |
| 最近记录: |