要求/AMD外部模块分辨率

RequireJS/AMD external module resolution

本文关键字:模块 分辨率 外部 AMD 要求      更新时间:2023-09-26

在我为我的应用程序创建的任何模块中,我可以放入以下内容:

import ko = require("knockout");

我就有了一个可以使用的ko对象。

如果我编写自己的模块,例如/app/services/I18n.js,我必须使用路径导入它:

import i18m = require("services/I18n");

我想知道Knockout模块做了什么使这成为可能,以便我可以做同样的事情。我希望它是关于Knockout.TypeScript.DefinitelyTyped附带的Knockout.d.ts的东西,我只是不知道是什么。

我已经尝试在我的main.ts中添加一个配置项到我的RequireJS配置:

requirejs.config({
    baseUrl          : "/app",
    urlArgs          : "bust=" + (new Date()).getTime(),
    paths            : {
        "text"       : "lib/requirejs-text/text",
        "durandal"   : "lib/durandal/js",
        "plugins"    : "lib/durandal/js/plugins",
        "transitions": "lib/durandal/js/transitions",
        "knockout"   : "lib/knockout.js/knockout",
        "jquery"     : "lib/jquery/jquery",
        "uuid"       : "lib/node-uuid/uuid",
        "bootstrap"  : "lib/bootstrap-sass-official/javascript/bootstrap",
        "I18n"       : "services/I18n"
    }
});

但这并没有被Visual Studio或ReSharper"注意到",所以没有效果(我不清楚它是否在运行时工作)。

它的长和短是,我不清楚模块是如何被发现的。总是按文件名吗?这条路有什么意义吗?*.d.ts有特殊的规则吗?

TypeScript模块解析有点可疑。Brocco关于*.ts文件中的本地模块的回答是正确的。TS不读取需要的配置-有一个新的tsconfig.json文件(作为v1.5我认为),你可以为编译器提供配置。如果你想让你的i18n模块像knockout模块一样被Visual Studio识别,你需要在*.d.ts文件中声明这些-在TS术语中这是一个环境声明。声明文件的特殊之处在于,您必须注意不要从这些文件中的顶层导出任何内容,否则TS将用无意义的错误消息轰轰地轰轰您-因此不允许使用顶层export,而是只需声明TS应该认为理所当然的内容。下面是这个用例的示例文件:

// i18n.d.ts
interface I18n {
    // Your module's TS interface
    translate(key: string): string;
}
declare var i18n: I18n;
declare module "i18n" {
    export = i18n;
}

这将告诉TS编译器有一个称为i18n的顶级模块,该模块将在编译后使用指定的接口出现。编译成AMD模块后,您需要在配置中提供在运行时找到该模块的信息:

// require.config.js
requirejs.config({
    // ...
    paths            : {
        // ...
        // Tell require.js where to find your module
        "I18n"       : "services/I18n"
    }
});

这是我正在使用的设置,希望它有帮助。

这并不是ko本身所做的什么特别的事情,它更多地与如何解析/找到包有关。当你引用一个本地/内部模块时,你应该用一个./开头,这样模块解析就知道去哪里找了。

对于ko(和其他npm包),它将遍历文件夹结构,直到找到一个包。找到Json文件,然后从那里遍历依赖项。在每个依赖项中,它将查看其包。