简体   繁体   English

要求JS / AMD外部模块分辨率

[英]RequireJS/AMD external module resolution

In any module I create for my app, I can put the following: 在为我的应用创建的任何模块中,我可以输入以下内容:

import ko = require("knockout");

I then have a ko object I can use. 然后,我有一个可以使用的ko对象。

If I write my own module, say /app/services/I18n.js , I have to import it using the path: 如果我编写自己的模块,例如/app/services/I18n.js ,则必须使用以下路径导入它:

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

I'd like to know what the Knockout module has done to make that possible so I can do the same. 我想知道Knockout模块做了什么才能使之成为可能,所以我可以这样做。 I'm expecting it to be something about the Knockout.d.ts that comes with Knockout.TypeScript.DefinitelyTyped , I just don't know what. 我期待它是一些有关Knockout.d.ts附带Knockout.TypeScript.DefinitelyTyped ,我只是不知道是什么。

I've tried adding a configuration item to my RequireJS config in my main.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"
    }
});

But that isn't "noticed" by Visual Studio or ReSharper, so has no effect (I'm unclear whether it work at runtime). 但这不是Visual Studio或ReSharper所“注意到”的,因此没有任何效果(我不清楚它是否在运行时起作用)。

The long and the short of it is that I'm unclear how modules are found. 其长短之处在于我不清楚如何找到模块。 Is it always by filename? 总是按文件名吗? Does the path mean anything? 路径有什么意思吗? Are there special rules for *.d.ts ? *.d.ts是否有特殊规定? It feels like there's magic going on. 感觉就像魔术在继续。

The TypeScript module resolution is a bit fishy. TypeScript模块的分辨率有点混乱。 Brocco is right in his answer regarding to local modules in *.ts files. Brocco对*.ts文件中的本地模块的回答是正确的。 TS doesn't read the require config - there is a new tsconfig.json file (as of v1.5 I think) where you can provide configuration for the compiler. TS不会读取require tsconfig.json有一个新的tsconfig.json文件(我认为从v1.5开始),您可以在其中为编译器提供配置。 If you want your i18n module to be recognized like eg the knockout module by say Visual Studio you need to declare these in a *.d.ts file - in TS lingo this is an ambient declaration. 如果您希望像说Visual Studio这样的knockout模块那样识别i18n模块,则需要在*.d.ts文件中声明它们-在TS语言中,这是环境声明。 The declaration files are special in that you have to take care not to export anything from the top-level within these files or else TS will bombard you with nonsense error messages - so no top-level export s are allowed but instead you just declare what TS should take for granted. 声明文件的特殊之处在于,您必须注意不要从这些文件中的顶层导出任何内容,否则TS会用无意义的错误消息轰炸您-因此不允许顶层export ,而是您只声明什么TS应该理所当然。 This is an example file for this use case: 这是此用例的示例文件:

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

declare var i18n: I18n;

declare module "i18n" {
    export = i18n;
}

This will tell the TS compiler that there is a top-level module called i18n that will be present after compilation with the specified interface. 这将告诉TS编译器,存在一个名为i18n的顶级模块,该模块将在使用指定接口进行编译后出现。 After compilation to AMD modules you need to provide the information where to find this module at runtime in the configuration: 编译为AMD模块后,您需要提供以下信息,以在配置中的运行时找到该模块:

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

This is the setup I'm working with, hope it helps. 这是我正在使用的设置,希望对您有所帮助。

It isn't really something special that has been done by ko itself, it is more related to how packages are resolved/found. ko本身并没有完成什么特别的事情,它与如何解析/找到包有关。 When you reference a local/internal module you should preface it with a ./ so the module resolution knows where to look. 引用本地/内部模块时,应在其./加上./以便模块解析知道在哪里查找。

As for ko (and other npm packages) it will traverse up the folder structure until a package.json file is found, and from there it will traverse through the dependencies. 至于ko(和其他npm软件包),它将遍历文件夹结构,直到找到package.json文件,然后从那里遍历所有依赖项。 And within each dependency it will look in its package.json main field/property to determine which file/module is loaded. 并且在每个依赖项中,它将查看其package.json主字段/属性以确定要加载的文件/模块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM