将requireJS与打字稿一起使用的正确方法是什么?

问题描述 投票:27回答:4

我发现的示例herehere说使用module()。但是,当我编译时,得到“警告TS7021:不建议使用'module(...)'。请改用'require(...)'。“

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

  1. 使用打字稿和requireJS时,如何在一个类中访问一个类来自其他.ts文件的.ts文件,其中requireJS将加载第二个文件,并在第一个文件中给我班?
  2. 是否有一种方法可以对两个.ts文件执行标准的requireJS方法,其中顶部的define()加载第二个ts文件并返回其最后构建的对象?
  3. 与问题2相同。从java脚本文件中,我可以在type脚本文件上使用define()构造来获取实例化的对象吗?如果是这样,如何?

更新:下面给出了一个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 {
requirejs typescript
4个回答
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一样工作,但是我们在他的博客上进行的一次交流显示,如果我能使用他的方法(在文件底部使用export MyClass),那么我不需要将导入的标识符与类名加倍。我想它会导出感兴趣的类,而不是导出其定义的名称空间(隐式外部模块,即TypeScript文件名)。


6
投票

对于:

使用打字稿和requireJS时,如何在一个类中访问一个类来自其他.ts文件的.ts文件,其中requireJS将加载第二个文件,并在第一个文件中给我班?有没有办法做具有两个.ts文件的标准requireJS方法,其中define()位于顶部加载第二个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

时会得到的结果

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;

2
投票

我一直在玩打字稿,试图将其集成到我们现有的javascript / requirejs项目中。作为安装程序,我有Visual Studio 2013 with Typescript for vs v 0.9.1.1。 (在Visual Studio中)将Typescript配置为以amd格式编译模块。

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

  1. 使用amd-dependency告诉打字稿编译器将所需的模块添加到必须加载的组件列表中
  2. 在要导出的类的构造函数中,使用requirejs的require函数实际获取导入的模块(由于上一步,这是同步的)。为此,您必须reference require.d.ts

作为旁注,但是由于我认为打字稿必不可少,并且因为它让我有些头疼,因此在示例中,我展示了两种导出使用接口的类的方法。接口的问题在于它们用于类型检查,但它们不产生实际输出(生成的.js文件为空),并且会导致类型为“导出私有类”的问题我发现了两种导出实现接口的类的方法:

  1. 只需将amd依赖项添加到接口(如Logger.ts文件中所示)并导出包含类的新实例的类型化变量导出的类可以直接使用(即myClass.log('hello'));
  2. 不要将amd-依赖项添加到界面(与Import.ts文件中的一样)并导出一个函数(即Instantiate()),该函数返回类型为持有类的新实例的变量可以通过此函数使用导出的类(即myClass.instantiate()。log('hello'))

似乎第一种选择更好:您无需调用实例化函数,而且可以使用类型化的类。缺点是[empty]接口的javascript文件确实会传送到浏览器(但是无论如何它都缓存在该浏览器中,也许您甚至正在使用缩小,在这种情况下这根本没有关系)。

在接下来的代码块中,有2个打字稿模块加载了require(amd):记录器和导入。

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文件中使用Logger.ts(Import.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使用Import模块,请使用类似(抱歉,我没有尝试过,但是应该可以)

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

    ////approach 2
    //import.instantiate().init();
});
© www.soinside.com 2019 - 2024. All rights reserved.