我曾试着阅读几篇博客文章,但 TypeScript 模块仍然让我完全困惑。特别是,我使用了 3 种不同的模块(都通过 npm 安装),每个模块似乎展现出完全不同的行为:
(1) 我可以像这样在我的 .ts 文件中从 npm 导入并使用 Angular 2:
``` import {bootstrap, Component, Directive, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2'; ```
然后在我的 html 中添加:
``` ```
这会产生以下结果:
- TypeScript 编译器知道要在 node_modules 下查找 angular2.d.ts 文件,即使我只是说了 "angular2/angular2" - TypeScript 编译器将 `var angular2_1 = require('angular2/angular2');` 添加到输出的 JavaScript 中 - 浏览器不会尝试再次加载 angular2 的 JavaScript,尽管有 `require`,它以某种方式知道已经通过 script 标签中的 "angular2.dev.js" 加载过它
(2) npm D3 模块没有类型定义,但我可以从 DefinitelyTyped 下载一个类型定义文件,并通过在我的 .ts 文件顶部添加以下内容来使用它:
``` /// ```
在我的 html 文件中添加以下代码:
``` ```
看起来由于它是一种旧式模块,它不需要 import 语句,只要我把它留在这里,输出的 JavaScript 就可以正常工作。如果我尝试在引用行之后立即使用 import 语句:
``` import * as d3 from 'd3'; ```
那么就像 Angular2 一样,它现在会添加以下代码:
``` var d3 = require('d3'); ```
到输出的 JavaScript 中。然而,与 Angular 的情况不同的是,它没有意识到已经通过 script 标签加载了 JavaScript,因此浏览器会尝试并失败地从与 html 文件相同的目录中加载名为 "d3" 的文件。
(3) npm Phaser 模块包括一个 .d.ts 文件,在 npm 模块的 "typescript" 子目录中。这是一种旧式模块("declare module Phaser"),所以似乎我不需要使用 "import.." 语法,而只需在我的 .ts 文件顶部添加以下内容,就像 D3 示例一样:
``` /// ```
TypeScript 编译器很高兴,但与 D3 示例不同的是,在某些情况下(我还没有完全弄清楚是什么情况,似乎不总是发生),它会输出以下内容:
为了完整起见,如果我尝试在引用行后添加一个导入语句:
我有很多问题:
1)什么决定了TypeScript编译器是否在输出JavaScript中包含"require(...)"行?
2)在使用"import"时,在哪些情况下TypeScript编译器知道在"npm_modules"中找到外部模块,是否需要在文件顶部需要引用行?
3)在使用"import"时,在哪些情况下TypeScript编译器知道在"typings"中找到环境模块,是否需要在文件顶部需要"reference"行?
4)在使用"import"时,在哪些情况下TypeScript编译器知道在"npm_modules"中找到环境模块,是否需要在文件顶部需要"reference"行?
5)也许这是一个commonjs/requirejs问题,而不是一个typescript问题,但是如果TypeScript编译器在JavaScript中输出"require"行,如果JavaScript模块的源没有设置ES6模块导出,该怎么办?
(1) 我可以像这样在我的 .ts 文件中从 npm 导入并使用 Angular 2:
``` import {bootstrap, Component, Directive, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2'; ```
然后在我的 html 中添加:
``` ```
这会产生以下结果:
- TypeScript 编译器知道要在 node_modules 下查找 angular2.d.ts 文件,即使我只是说了 "angular2/angular2" - TypeScript 编译器将 `var angular2_1 = require('angular2/angular2');` 添加到输出的 JavaScript 中 - 浏览器不会尝试再次加载 angular2 的 JavaScript,尽管有 `require`,它以某种方式知道已经通过 script 标签中的 "angular2.dev.js" 加载过它
(2) npm D3 模块没有类型定义,但我可以从 DefinitelyTyped 下载一个类型定义文件,并通过在我的 .ts 文件顶部添加以下内容来使用它:
``` /// ```
在我的 html 文件中添加以下代码:
``` ```
看起来由于它是一种旧式模块,它不需要 import 语句,只要我把它留在这里,输出的 JavaScript 就可以正常工作。如果我尝试在引用行之后立即使用 import 语句:
``` import * as d3 from 'd3'; ```
那么就像 Angular2 一样,它现在会添加以下代码:
``` var d3 = require('d3'); ```
到输出的 JavaScript 中。然而,与 Angular 的情况不同的是,它没有意识到已经通过 script 标签加载了 JavaScript,因此浏览器会尝试并失败地从与 html 文件相同的目录中加载名为 "d3" 的文件。
(3) npm Phaser 模块包括一个 .d.ts 文件,在 npm 模块的 "typescript" 子目录中。这是一种旧式模块("declare module Phaser"),所以似乎我不需要使用 "import.." 语法,而只需在我的 .ts 文件顶部添加以下内容,就像 D3 示例一样:
``` /// ```
TypeScript 编译器很高兴,但与 D3 示例不同的是,在某些情况下(我还没有完全弄清楚是什么情况,似乎不总是发生),它会输出以下内容:
var phaser_1 = require('phaser');
为了完整起见,如果我尝试在引用行后添加一个导入语句:
import * as Phaser from 'Phaser';
我有很多问题:
1)什么决定了TypeScript编译器是否在输出JavaScript中包含"require(...)"行?
2)在使用"import"时,在哪些情况下TypeScript编译器知道在"npm_modules"中找到外部模块,是否需要在文件顶部需要引用行?
3)在使用"import"时,在哪些情况下TypeScript编译器知道在"typings"中找到环境模块,是否需要在文件顶部需要"reference"行?
4)在使用"import"时,在哪些情况下TypeScript编译器知道在"npm_modules"中找到环境模块,是否需要在文件顶部需要"reference"行?
5)也许这是一个commonjs/requirejs问题,而不是一个typescript问题,但是如果TypeScript编译器在JavaScript中输出"require"行,如果JavaScript模块的源没有设置ES6模块导出,该怎么办?