TypeScript中“require(...)”的用法让你感到困惑了吗?

3
我曾试着阅读几篇博客文章,但 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 示例不同的是,在某些情况下(我还没有完全弄清楚是什么情况,似乎不总是发生),它会输出以下内容:

var phaser_1 = require('phaser');

在JavaScript中,即使我没有使用import语句,也可以看到上述代码。在我的phaser项目中,我甚至没有使用commonjs/requirejs,所以"require"甚至没有被定义,导致失败。
为了完整起见,如果我尝试在引用行后添加一个导入语句:

import * as Phaser from 'Phaser';

即使TypeScript编译器也不满意。也许在D3示例中,TypeScript编译器正在以特殊方式处理tsd.json或DefinitelyTyped中的typings文件夹,或者可能有其他原因导致导入编译为D3而不是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模块导出,该怎么办?
1个回答

3

1 ) 我可以像这样在我的 .ts 文件中从 npm 导入并使用 Angular 2:

这是因为:

  • angular2 随附其 .d.ts 文件。

  • 浏览器不会尝试读取 require,因为在 angular2.dev.js 中有魔法。

npm 的 D3 模块失败了,Phaser 模块在运行时也失败了。

它们没有你从 angular2.dev.js 获取的魔法。使用类似于 webpackbrowserify 来提供这种魔法。

与 Angular 或 D3 示例不同的是,如果我尝试在引用行之后放置一个 import 语句:import * as Phaser from 'Phaser';

这是因为 Phaser 定义的声明方式不同。显然,它缺少 d3 提供的 declare module "Phaser"(请参见此处)和 Angular。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接