【问题标题】:Typescript - How to resolve internal modules at run-timeTypescript - 如何在运行时解析内部模块
【发布时间】:2013-01-21 00:53:39
【问题描述】:

从 main.ts 入口点运行的 bootstrapper.ts 看起来像这样(减去引用标题):

import Dialogs = App.Widgets.Dialogs;
declare var $ : JQueryStatic;


export class Bootstrapper { 
    static SiteLoad() { 
       var dialog = new Dialogs.LoginDialog();
       ...
    }
}

但是,当 main.ts 尝试加载此文件时,第一行会立即引发引用错误。那时我意识到导入内部模块不会向生成的 .js 文件的 define 包装器添加任何依赖项。

那么我该如何在运行时解析内部模块呢?是不是 AMD 只兼容外部模块,而我必须在 main.ts 的入口点加载内部模块以及外部库?

我更喜欢内部模块的别名语法而不是外部模块。我上面的代码看起来比使用外部模块语法时干净得多:

import Dialogs = module("Modules/App.Widgets.Dialogs");
declare var $ : JQueryStatic;


export class Bootstrapper { 
    static SiteLoad() { 
       var dialog = Dialogs.App.Widgets.Dialogs.LoginDialog(); //Seriously?
       ...
    }
}

这太丑了。怎么办?

更新:

史蒂夫,您建议的方法有局限性。在我使用内部模块的原始方法中,我可以执行以下操作:

import Dialogs = App.Widgets.Dialogs;

declare var $ : JQueryStatic;

export class Bootstrapper { 
    static SiteLoad() { 

        var loginDialog1 = new Dialogs.LoginDialog();  //Instantiation      -OK
        var loginDialog2: Dialogs.LoginDialog;         //Type-Declaration   -OK
    }
}

在您建议的方法中,我失去了使用别名进行类型声明的能力:

import DialogsModule =  module("Modules/App.Widgets.Dialogs");

var Dialogs : DialogsModule.App.Widgets.Dialogs;

declare var $ : JQueryStatic;

export class Bootstrapper { 
    static SiteLoad() { 

        var loginDialog1 = new Dialogs.LoginDialog();   //Instantiation  -OK        
        var loginDialog2: Dialogs.LoginDialog;  //Type-Declaration -ERROR: The name "Dialogs" does not exist in the current context  
        var loginDialog3: DialogsModule.App.Widgets.Dialogs.LoginDialog;  //Must use full name instead
    }
}

【问题讨论】:

    标签: requirejs typescript amd


    【解决方案1】:

    您可以像这样为长模块路径起别名:

    import DialogModule = module("Modules/App.Widgets.Dialogs");
    var dialogs = DialogModule.App.Widgets.Dialogs;
    declare var $ : JQueryStatic;
    
    export class Bootstrapper { 
        static SiteLoad() { 
           var dialog = dialogs.LoginDialog();
           ...
        }
    }
    

    您可以通过自己包含适当的文件来将 AMD 与纯 JavaScript 混合使用 - 但我建议您选择一种模式在您的程序中使用以使事情更易于理解。

    【讨论】:

    • 编辑过的 OP 描述了为什么这种方法不适合。不确定您所说的“将 AMD 与纯 Javascript 混合......您的意思是在 ts 文件中明确编写 define 包装器并完全避免 TS module("") 语法吗?这就是更清洁的解决方案的原因吗? ?
    • 是的 - 不是最清楚的解释。我的意思是混合使用模块加载器和手动添加额外的script 标签,所以你有一些静态脚本和一些由模块加载器加载。
    • 我明白了。好的,似乎没有与类型声明一致的别名的干净解决方案。我最终会使用混合模式或使用甚至没有任何意义的长模块名称(例如“Dialogs.App.Widgets.Dialogs”)。所以我决定放弃使用模块定义语法,因为它不像我最初想象的 C# 命名空间那样工作。
    • 相反,我使用文件夹组织了我的“命名空间结构”(例如:上面对话框模块的“/Scripts/App/Widgets/Dialogs.ts”)并将文件本身视为模块(将我的模块导出直接写入全局范围)。这是我可以获得适用于类型声明的干净别名的唯一方法。例如:import Dialogs = module("App/Widgets/Dialogs"); var loginDialog1 = Dialogs.LoginDialog(); //GOOD var loginDialog2: Dialogs.LoginDialog; //也不错。
    • 回到这里我已经放弃了上面所说的方法,并重构了我的代码以使用此处描述的 Steve 方法:stevefenton.co.uk/Content/Blog/Date/201301/Blog/… 加上此处描述的其他组织:stackoverflow.com/a/13850286/1267778 每个文件编译的单类到单个文件中绝对是要走的路。
    猜你喜欢
    • 1970-01-01
    • 2020-08-02
    • 2018-11-10
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 2017-03-30
    • 2017-09-21
    相关资源
    最近更新 更多