typescript 在打字稿中使用 requireJS 的正确方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20079464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the correct way to use requireJS with typescript?
提问by David Thielen
The examples I have found hereand heresay to use module(). However, when I compile I get "warning TS7021: 'module(...)' is deprecated. Use 'require(...)' instead."
我在此处和此处找到的示例说要使用 module()。但是,当我编译时,我收到“警告 TS7021: 'module(...)' 已被弃用。使用 'require(...)' 代替。”
So a couple of basic questions:
所以有几个基本问题:
- When using typescript and requireJS, how do I access a class in one .ts file from another .ts file where requireJS will load the second file and give me the class in the first file?
- Is there a way to do the standard requireJS approach with two .ts files where the define() at the top loads the second ts file and returns back the object it builds at the end?
- Sort-of the same as question #2. From a javascript file, can I use the define() construct on a typescript file to get the instantiated object? If so, how?
- 使用 typescript 和 requireJS 时,如何从另一个 .ts 文件访问一个 .ts 文件中的类,其中 requireJS 将加载第二个文件并在第一个文件中为我提供类?
- 有没有办法用两个 .ts 文件执行标准的 requireJS 方法,其中顶部的 define() 加载第二个 ts 文件并返回它在最后构建的对象?
- 与问题#2 类似。从java脚本文件中,我可以在类型脚本文件上使用define()构造来获取实例化对象吗?如果是这样,如何?
Update:The following gives me a tsc compile error:
更新:以下给了我一个 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 {
回答by Eric
I would have commented on David's reply to basarat's answer (regarding modules and classes), but I don't have the reputation. I know this question is stale, but I didn't find an answer elsewhere.
我会评论大卫对 basarat 的回答(关于模块和课程)的回复,但我没有声誉。我知道这个问题已经过时了,但我没有在其他地方找到答案。
I succeeded by using basarat's videos, combined with some other resources, to figure it out for classes like David Thielen needed. Note that I no longer have entries for my ts source files, but I do have amd-dependency and import statements. In Eclipse with palantir's TS plugin, my code completion and ability to jump from usage to definition is working with just the amd-dependency and import statements. The header files still need statements since they have nothing to do with deployment and are only used by the TS compiler. Note also that the .ts file extensions are used for reference statements but not the amd and import statements.
我成功地使用了 basarat 的视频,并结合了其他一些资源,为 David Thielen 等需要的课程找到了答案。请注意,我的 ts 源文件不再有条目,但我确实有 amd-dependency 和 import 语句。在带有 palantir TS 插件的 Eclipse 中,我的代码完成和从用法跳转到定义的能力仅使用 amd-dependency 和 import 语句。头文件仍然需要语句,因为它们与部署无关,仅供 TS 编译器使用。另请注意,.ts 文件扩展名用于引用语句,但不用于 amd 和 import 语句。
In Utils.ts I have:
在 Utils.ts 我有:
///<reference path="headers/require.d.ts" />
export function getTime(){
var now = new Date();
return now.getHours()+":"+now.getMinutes()+':'+now.getSeconds();
}
In OntologyRenderScaler I have:
在 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();
...
}
In OntologyMappingOverview.ts I have:
在 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);
...
}
I didn't manage (yet!) to get things working like codeBelt suggested above, but an exchange we had on his blog revealed that if I get his approach working (with export MyClass at the bottom of the file), then I would not need to double up the imported identifer with the class name. I suppose it would export the class of interest rather than the namespace it is defined in (the implicit external module, i.e. the TypeScript file name).
我没有设法(还!)让事情像上面建议的 codeBelt 那样工作,但是我们在他的博客上进行的交流表明,如果我让他的方法起作用(在文件底部使用 export MyClass),那么我不会需要将导入的标识符与类名加倍。我想它会导出感兴趣的类而不是它定义的命名空间(隐式外部模块,即 TypeScript 文件名)。
回答by basarat
For :
为了 :
When using typescript and requireJS, how do I access a class in one .ts file from another .ts file where requireJS will load the second file and give me the class in the first file? Is there a way to do the standard requireJS approach with two .ts files where the define() at the top loads the second ts file and returns back the object it builds at the end?
使用 typescript 和 requireJS 时,如何从另一个 .ts 文件访问一个 .ts 文件中的类,其中 requireJS 将加载第二个文件并在第一个文件中为我提供类?有没有办法用两个 .ts 文件执行标准的 requireJS 方法,其中顶部的 define() 加载第二个 ts 文件并返回它在最后构建的对象?
simply :
简单地 :
// from file a.ts
export class Foo{
}
// from file b.ts
// import
import aFile = require('a')
// use:
var bar = new aFile.Foo();
and compile both files with --module amd
flag.
并用--module amd
标志编译这两个文件。
For :
为了 :
Sort-of the same as question #2. From a java script file, can I use the define() construct on a type script file to get the instantiated object? If so, how?
与问题#2 类似。从java脚本文件中,我可以在类型脚本文件上使用define()构造来获取实例化对象吗?如果是这样,如何?
To use a.ts from b.jssimply :
简单地使用 b.js 中的a.ts:
// import as a dependency:
define(["require", "exports", 'a'], function(require, exports, aFile) {
// use:
var bar = new aFile.Foo();
});
This is similar to what you would get if you compile b.ts
这与编译b.ts 时得到的结果类似
回答by codeBelt
You want the export statement below the class you are creating.
您需要正在创建的类下面的导出语句。
// Base.ts
class Base {
constructor() {
}
public createChildren():void {
}
}
export = Base;
Then to import and use into another class you would do:
然后导入并使用到另一个类中,您将执行以下操作:
// TestApp.ts
import Base = require("view/Base");
class TestApp extends Base {
private _title:string = 'TypeScript AMD Boilerplate';
constructor() {
super();
}
public createChildren():void {
}
}
export = TestApp;
You can check out example code at http://www.codebelt.com/typescript/typescript-internal-and-external-modules/
您可以在http://www.codebelt.com/typescript/typescript-internal-and-external-modules/查看示例代码
回答by Leo
I have been playing with typescript, trying to integrate it in our existing javascript/requirejs project. As setup, I have Visual Studio 2013 with Typescript for vs v 0.9.1.1. Typescript is configured (in visual studio) to compile modules in amd format.
我一直在玩打字稿,试图将它集成到我们现有的 javascript/requirejs 项目中。作为设置,我有 Visual Studio 2013 和 Typescript for vs v 0.9.1.1。Typescript 配置(在 Visual Studio 中)以 amd 格式编译模块。
This is what I have found works for me (there might be a better way of course)
这是我发现对我有用的方法(当然可能有更好的方法)
- Use amd-dependencyto tell the typescript compiler adds the required module to the list of components which must be loaded
- In the constructor of the class being exported, use requirejs's require function to actually fetch the imported module (at this point this is synchronous because of the previous step). To do this you must reference require.d.ts
- 使用 amd-dependency告诉打字稿编译器将所需的模块添加到必须加载的组件列表中
- 在被导出的类的构造函数中,使用requirejs的require函数来实际获取导入的模块(此时因为上一步是同步的)。为此,您必须参考 require.d.ts
As a side note, but since it is in my view essential to typescript, and because it gave me a bit of a headache, in the example I show two ways to export classes which use interfaces. The problem with interfaces is that they are used for type checking, but they produce no real output (the generated .js file is empty), and it causes problems of the type ‘'export of a private class” I have found 2 ways of exporting classes which implement an interface:
作为旁注,但由于我认为它对打字稿至关重要,并且因为它让我有点头疼,所以在示例中我展示了两种导出使用接口的类的方法。接口的问题在于它们用于类型检查,但它们没有产生真正的输出(生成的 .js 文件是空的),并且会导致“私有类的导出”类型的问题我找到了 2 种方法导出实现接口的类:
- Simply add an amd-dependency to the interface (as is in the Logger.ts file) And export a typed variable holding a new instance of the class The exported class can be consumed directly (ie myClass.log(‘hello'));
- Don't add the amd- dependency to the interface (as is in the Import.ts file) And export a function (ie Instantiate()) which returns a variable of type any holding a new instance of the class The exported class can be consumed via this function (ie myClass.instantiate().log(‘hello'))
- 只需向接口添加一个 amd 依赖项(就像在 Logger.ts 文件中一样)并导出一个包含类的新实例的类型化变量 导出的类可以直接使用(即 myClass.log('hello'));
- 不要将 amd- 依赖添加到接口中(就像在 Import.ts 文件中一样)并导出一个函数(即 Instantiate()),该函数返回一个类型为 any 的变量,该变量持有类的新实例 导出的类可以是通过这个函数消耗(即 myClass.instantiate().log('hello'))
It seems like the first option is better: you don't need to call the instantiate function, plus you get a typed class to work with. The downside is that the [empty] interface javascript file does travel to the browser (but it's cached there anyway, and maybe you are even using minification in which case this does not matter at all).
似乎第一个选项更好:您不需要调用实例化函数,而且您可以获得一个类型化的类来使用。缺点是 [empty] 界面 javascript 文件确实会传送到浏览器(但它无论如何都缓存在那里,也许您甚至在使用缩小,在这种情况下这根本无关紧要)。
In the next blocks of code there are 2 typescript modules loaded with requires (amd): Logger and Import.
在接下来的代码块中有 2 个加载了 requires (amd) 的 typescript 模块:Logger 和 Import。
ILogger.ts file
ILogger.ts 文件
interface ILogger {
log(what: string): void;
}
Logger.ts file
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;
Using Logger.ts in another ts file(Import.ts)
在另一个 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 file
Iimport.ts 文件
interface IImport {
init(vm: any): void;
}
To consume the Import module straight from javascript use something like (sorry I have not tried this one, but it should work)
要直接从 javascript 使用导入模块,请使用类似的东西(对不起,我没有尝试过这个,但它应该可以工作)
define (['Import'], function (import)
{
//approach 1
import.init();
////approach 2
//import.instantiate().init();
});