2017-10-02 18 views
11

Câu hỏi:

Tôi có một dự án trong TypeScript sử dụng một số API mà tôi không có quyền truy cập vào máy tính (chúng tồn tại trên web). Mã sẽ biên dịch tốt tại địa phương vì tôi có tất cả các API trong các tệp foo.d.ts và do đó hệ thống biết chúng tồn tại ở đâu đó.Đăng ký Mô-đun Nút Thủ công

Tuy nhiên, tôi muốn đơn vị kiểm tra các phần của mã bằng ứng dụng NodeJS. Tôi có thể nhập mã vào nút tốt, nhưng bất cứ khi nào tôi đạt được code mà nhập khẩu một mô-đun từ một tập tin định nghĩa, tôi nhận được lỗi sau:

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) 
... 

này có ý nghĩa, vì mã mà chỉ được định nghĩa tại địa phương, và không tồn tại.

Tôi có thể tự đăng ký mô-đun để NodeJS, như

Registry.register('messages',() => {...}); 

vì vậy mà tôi có thể biên dịch và thử nghiệm với polyfills?


Dưới đây là một ứng dụng ví dụ

package.json

{ 
    "name": "sample_typescript_declare_issue", 
    "version": "1.0.0", 
    "description": "", 
    "main": "index.ts", 
    "scripts": { 
    "start": "ts-node index.ts" 
    }, 
    "author": "", 
    "license": "MIT" 
} 

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"); 

App.ts

import {MessageSender} from "messages"; 

export class App { 
    constructor() { 
     let messageSender: MessageSender = new MessageSender(); 
     messageSender.sendMessage("foo!"); 
    } 
} 

node_modules/@types/messages/index.d.ts

export = Messages; 
export as namespace Messages; 

declare module Messages { 

    class MessageSender { 
     constructor(); 
     sendMessage(message: any): void; 
    } 

} 

Chạy Ví dụ App

Chạy với npm start cung cấp cho các thông báo lỗi trên.

Chạy tsc *.tsc biên dịch tốt.

điều

khác tôi đã cố gắng

  1. Đang cập nhật package.json để bao gồm một thùng:

    { 
        "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" 
        } 
    } 
    

Trả lời

2

Như bạn nói, biên soạn công trình tốt - đây chỉ là một câu hỏi về tính sẵn có của .d.ts tệp.

Những gì bạn muốn làm là ALTER nhập khẩu mô-đun trong thời gian chạy, nói cách khác thay đổi hành vi của nodejs require chức năng từ

import {MessageSender} from "messages"; 

sẽ được transpiled trong javascript (ES6) để một cái gì đó giống như

const messages_1 = require("messages"); 
... 
messages_1.MessageSender 

Để sửa đổi hành vi đó, điều đầu tiên cần lưu ý là sử dụng không được dùng nữa - nhưng vẫn có sẵn - đối tượng require.extensions.

Khi chạy cục bộ trước tiên bạn phải tiêm cái gì đó như

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) 
    } 
}; 

Các doc nói có lựa chọn thay thế tốt hơn nhưng không đề cập rõ ràng bất kỳ.

Một khả năng khác là nhìn vào các dự án như sandboxed-module mà nên giúp (tôi đã không kiểm tra nó)

+0

tôi đã cố gắng cả hai giải pháp, nhưng không có vẻ làm việc. Các phần mở rộng sẽ không cho phép tôi gọi "siêu", và mô-đun sandbox không bao giờ làm việc cho tôi. Nó không tiêm bất cứ thứ gì. – Jason

Các vấn đề liên quan