使用requireJS和打字稿的正确方法是什么?

时间:2013-11-19 18:40:18

标签: requirejs typescript

我发现herehere的例子说使用module()。但是,当我编译时,我得到“警告TS7021:'module(...)'已被弃用。请改用'require(...)'。”

所以有几个基本问​​题:

  1. 使用typescript和requireJS时,如何在一个类中访问一个类 来自另一个.ts文件的.ts文件,其中requireJS将加载第二个文件 文件,并在第一个文件中给我类?
  2. 有没有办法用两个.ts文件执行标准requireJS方法,其中top()顶部加载第二个ts文件并返回它最后构建的对象?
  3. 排序与问题#2相同。从 java 脚本文件,我可以在类型脚本文件上使用define()构造来获取实例化对象吗?如果是这样,怎么样?
  4. 更新:以下内容给出了一个tsc编译错误:

    ///<reference path='../../libs/ExtJS-4.2.0.d.ts' />
    ///<reference path='../../libs/require.d.ts' />
    
    import fdm = require("./file-definitions");
    require(["../../scripts/ribbon"], function () {
    
    export module Menu {
    
        export class MainMenu {
    

4 个答案:

答案 0 :(得分:12)

我会评论David对basarat的答案(关于模块和课程)的回复,但我没有声誉。我知道这个问题很陈旧,但我没有在其他地方找到答案。

我成功地使用了basarat的视频,结合其他一些资源,为David Thielen所需的课程找到了答案。请注意,我不再拥有ts源文件的条目,但我确实有amd-dependency和import语句。在使用palantir的TS插件的Eclipse中,我的代码完成以及从使用跳转到定义的能力仅适用于amd-dependency和import语句。头文件仍然需要语句,因为它们与部署无关,仅由TS编译器使用。另请注意,.ts文件扩展名用于引用语句,但不用于amd和import语句。

在Utils.ts中我有:

///<reference path="headers/require.d.ts" />

export function getTime(){
    var now = new Date();
    return now.getHours()+":"+now.getMinutes()+':'+now.getSeconds();
}

在OntologyRenderScaler中我有:

///<reference path="headers/require.d.ts" />

///<reference path="headers/d3.d.ts" />
///<reference path="headers/jquery.d.ts" />

///<amd-dependency path="Utils" />

import Utils = require('./Utils');

export class OntologyRenderScaler {
...
Utils.getTime();
...
}

在OntologyMappingOverview.ts中我有:

///<reference path="headers/require.d.ts" />

///<reference path="headers/d3.d.ts" />
///<reference path="headers/jquery.d.ts" />

///<amd-dependency path="Utils" />
///<amd-dependency path="OntologyGraph" />
///<amd-dependency path="OntologyFilterSliders" />
///<amd-dependency path="FetchFromApi" />
///<amd-dependency path="OntologyRenderScaler" />
///<amd-dependency path="GraphView" />

///<amd-dependency path="JQueryExtension" />

import Utils = require('./Utils');
import OntologyGraph = require('./OntologyGraph');
import OntologyRenderScaler = require('./OntologyRenderScaler');
import OntologyFilterSliders = require('./OntologyFilterSliders');
import GraphView = require('./GraphView');

export class OntologyMappingOverview extends GraphView.BaseGraphView implements GraphView.GraphView {
    ontologyGraph: OntologyGraph.OntologyGraph;
    renderScaler: OntologyRenderScaler.OntologyRenderScaler;
    filterSliders: OntologyFilterSliders.MappingRangeSliders;
...
this.renderScaler = new OntologyRenderScaler.OntologyRenderScaler(this.vis);
...
}

我没有管理(还有!)让事情像上面提到的codeBelt一样工作,但我们在他的博客上进行的交流显示,如果我让他的方法工作(在文件的底部导出MyClass),那么我不需要使用类名加倍导入的标识符。我想它会导出感兴趣的类而不是它定义的命名空间(隐式外部模块,即TypeScript文件名)。

答案 1 :(得分:6)

对于:

  

使用typescript和requireJS时,如何在一个类中访问一个类   来自另一个.ts文件的.ts文件,其中requireJS将加载第二个文件   文件并在第一个文件中给我类?有没有办法做到这一点   标准的requireJS方法有两个.ts文件,其中的是define()   top加载第二个ts文件并返回它构建的对象   最后?

简单地说:

// from file a.ts
export class Foo{

}

// from file b.ts
// import 
import aFile = require('a')
// use: 
var bar = new aFile.Foo();

并使用--module amd标志编译这两个文件。

对于:

  

排序与问题#2相同。从java脚本文件,我可以使用   在类型脚本文件上的define()构造以获得实例化   宾语?如果是这样,怎么样?

仅使用 b.js 中的a.ts:

// import as a dependency:
define(["require", "exports", 'a'], function(require, exports, aFile) {

    // use:
    var bar = new aFile.Foo();
});

这类似于编译 b.ts

时的结果

答案 2 :(得分:4)

您希望导出语句位于您正在创建的类下方。

// Base.ts
class Base {

    constructor() {
    }

    public createChildren():void {

    }
}

export = Base;

然后导入并使用到另一个类中:

// TestApp.ts
import Base = require("view/Base");

class TestApp extends Base {

    private _title:string = 'TypeScript AMD Boilerplate';

    constructor() {
        super();
    }

    public createChildren():void {

    }
}

export = TestApp;

您可以在http://www.codebelt.com/typescript/typescript-internal-and-external-modules/

查看示例代码

答案 3 :(得分:2)

我一直在玩打字稿,试图将它集成到我们现有的javascript / requirejs项目中。 作为设置,我使用带有Typescript for vs v 0.9.1.1的Visual Studio 2013。 Typescript被配置(在visual studio中)以amd格式编译模块。

这是我发现的对我有用(当然可能有更好的方法)

  1. 使用amd-dependency 告诉typescript编译器将所需模块添加到必须加载的组件列表中
  2. 在要导出的类的构造函数中,使用requirejs的require函数实际获取导入的模块(此时由于上一步,这是同步的)。为此,您必须引用require.d.ts
  3. 作为旁注,但由于它在我看来对打字稿至关重要,并且因为它让我有点头疼,在示例中我展示了两种导出使用接口的类的方法。接口的问题是它们用于类型检查,但它们不产生实际输出(生成的.js文件为空),并且它导致类型''导出私有类“的问题” 我找到了两种导出实现接口的类的方法:

    1. 只需在接口上添加amd-dependency(在Logger.ts文件中) 并导出一个包含该类的新实例的类型变量 导出的类可以直接使用(即myClass.log('hello'));
    2. 不要将amd-依赖项添加到接口(如Import.ts文件中所示) 并导出一个函数(即Instantiate()),它返回一个类型为any的变量,并保存一个新的类实例 导出的类可以通过此函数使用(即myClass.instantiate()。log('hello'))
    3. 似乎第一个选项更好:您不需要调用实例化函数,而且还需要一个可以使用的类型化类。缺点是[empty]接口javascript文件确实传到浏览器(但它仍然在那里缓存,也许你甚至使用缩小,在这种情况下这根本不重要)。

      在下一个代码块中,有2个typescript模块加载需求(amd):Logger和Import。

      ILogger.ts文件

      interface ILogger {
          log(what: string): void;
      }
      

      Logger.ts文件

      ///<reference path="./ILogger.ts"/>
      
      //this dependency required, otherwise compiler complaints of private type being exported
      ///<amd-dependency path="./ILogger"/>
      
      class Logger implements ILogger {
              formatOutput = function (text) {
                  return new Date() + '.' + new Date().getMilliseconds() + ': ' + text;
              };
      
              log = function (what) {
                  try {
                      window.console.log(this.formatOutput(what));
                  } catch (e) {
                      ;
                  }
              };
      }
      
      //this approach requires the amd-dependency above for the interafce
      var exportLogger: ILogger = new Logger();
      export = exportLogger;
      

      在另一个ts文件(Import.ts)中使用Logger.ts

      ///<reference path="../../../ext/definitions/require.d.ts"/>
      
      ///<amd-dependency path="Shared/Logger"/>
      ///<amd-dependency path="./IImport"/>
      
      class _Import implements IImport{
          ko: any;
          loggerClass: ILogger;
      
          constructor() {
              this.ko = require('knockout');//require coming from require.d.ts (in external_references.ts)
              this.loggerClass = require('Shared/Logger');
          }
      
          init(vm: any) {
              this.loggerClass.log('UMF import instantiated...');
          }
      }
      
      ////Alternative Approach:
      ////this approach does not require adding ///<amd-dependency path="./IImport"/>
      ////this can be consumed as <imported_module_name>.instantiate().init();
      //export function instantiate() {
      //    var r : any = new _Import();// :any  required to get around the private type export error
      //    return r;
      //}
      
      //this module can be consumed as <imported_module_name>.init();
      var exported: IImport = new _Import();
      export = exported;
      

      IImport.ts文件

      interface IImport {
          init(vm: any): void;
      }
      

      直接从javascript使用导入模块使用类似的东西(对不起,我没试过这个,但它应该工作)

      define (['Import'], function (import)
      {
          //approach 1
          import.init();
      
          ////approach 2
          //import.instantiate().init();
      });