【发布时间】:2023-03-11 09:50:02
【问题描述】:
以前我可以这样做:
import foo = require('foo');
但是现在 TypeScript (1.5) 支持 es6 模块语法,在 ES6 模块语法中实现相同的正确方法是什么。
【问题讨论】:
标签: javascript typescript ecmascript-6
以前我可以这样做:
import foo = require('foo');
但是现在 TypeScript (1.5) 支持 es6 模块语法,在 ES6 模块语法中实现相同的正确方法是什么。
【问题讨论】:
标签: javascript typescript ecmascript-6
另一种选择是使用 CommonJS 语法导入它:
const foo = require("foo");
TypeScript 和 Babel 都同意如何处理这个问题。另外,如果你编译到 ES5 或更少,那么这与它的最终形式不会相差太远。
【讨论】:
全部导入,
const foo = require("foo");
如果它是一个文件,这将从包“foo”中导入所有实例
const foo = require("./foo");
这样您就可以通过调用foo.InstanceName来访问每个实例
如果你想导入特定的实例,
import MyInstance from "foo";
所以这将从“foo”导入特定实例(Myinstance) 您仍然可以使用上述方法导入所有内容,
import * as ReferenceName from "foo";
相当于,
const ReferenceName = require("foo");
【讨论】:
从 TypeScript 2.7 开始,有一个新的 esModuleInterop 标志可用于启用 CommonJS/AMD/UMD 的默认导入。通过在tsconfig.json 中将该标志设置为true,这应该可以按预期工作:
import foo from 'foo';
【讨论】:
正确的方法是继续使用旧的导入语法。新的导入语法仅适用于 ES 模块,旧的导入语法适用于 ES6 之前的模块。两者是不同的,故意的。 import * as foo from 'foo' 导入模块“foo”的所有属性,它不导入默认值作为foo。
From the designer of the feature:
export default 始终具有 ES 模块语义。为了与 Babel 兼容,我们可以选择在模块具有默认导出时发出 __esModule 标记,但我们实际上不会将该标记用于任何事情。export = 声明,它替换要导出的不同实体来代替模块本身,始终作为对 module.exports 的赋值发出。在使用export = 的模块中有其他导出是错误的。这是现有的 TypeScript 行为。export = 导出另一个模块(内部或外部模块)的模块可以使用新的 ES6 结构导入。特别是,这些模块可以使用方便的解构导入。使用 export = 导出另一个模块的模式在 .d.ts 文件中很常见,这些文件提供内部模块的 CommonJS/AMD 视图(例如 angular.d.ts)。export = 导出非模块实体代替模块本身的模块必须使用现有的import x = require("foo") 语法导入,就像今天一样。2016 年更新: TypeScript 编译器在某些时候开始允许 import * as foo from 'legacy-module-foo' 在某些情况下获取旧模块的默认导入。 这违反了 ES6 规范(§15.2.1.16,“值“*”表示导入请求是针对目标模块的namespace object。”)。
当您以这种方式导入的遗留模块更新为 ES6 模块时,这些模块的“默认”导入将停止工作(因为 * as foo 导入假定正在导入 命名空间objects),如果您不知道这样做是 TypeScript/SystemJS hack,这可能会非常令人困惑。未来 TypeScript 对 ES 规范的重新调整也有可能导致它们崩溃。
因此,您可能更愿意继续使用上述遗留导入语法来加载遗留模块,以避免让您自己和其他开发人员在处理您的代码时对 ES6 命名空间导入的工作方式感到困惑,并避免对重大更改造成混淆。
【讨论】:
import x = require('foo') 是不允许的
import 的非 ES6 模块的默认值。如果你想使用遗留模块,你不能以 ES6 环境为目标,因为在这种情况下,TypeScript 编译器会按原样发出 import 语句,并且 ES 规范没有为默认的 CJS/AMD 模块提供任何规定出口。
import * as <name> from <'module'> 语法仍然有效
ES6 模块实际上是 TypeScript 外部模块,具有新的 语法:ES6 模块是单独加载的源文件,可能 导入其他模块并提供一些外部可访问的 出口。 ES6 模块具有几个新的导出和导入 声明。建议使用 TypeScript 库和 应用程序被更新以使用新语法,但这不是 要求。
据我了解,这意味着我们鼓励您将自己的 TypeScript 模块迁移到新语法,但继续使用 import foo = require('foo') 来导入实际的 AMD/CommonJS 模块。
【讨论】:
ES6模块语法对应的语法是:
import * as foo from 'foo';
基本上将 foo 模块中的所有内容导入到名为 foo 的局部变量中。
【讨论】:
export {Output}; 替换 export = Output 时,我得到了 resolves to a non-module entity and cannot be imported using this construct