Javascript 用于导入 commonjs / amd 模块的新 es6 语法,即`import foo = require('foo')`

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29596714/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:38:32  来源:igfitidea点击:

New es6 syntax for importing commonjs / amd modules i.e. `import foo = require('foo')`

javascripttypescriptecmascript-6

提问by basarat

Previously I could do:

以前我可以这样做:

import foo = require('foo');

But now that TypeScript (1.5) supports es6 module syntax, what is the correct way to achieve the same in ES6 module syntax.

但是现在 TypeScript (1.5) 支持 es6 模块语法,在 ES6 模块语法中实现相同的正确方法是什么。

回答by C Snover

The correct way is to continue using the old import syntax. The new import syntax is for ES modules only, the old import syntax is for pre-ES6 modules. The two are distinct, intentionally so. import * as foo from 'foo'imports all the propertiesof the module 'foo', it does not import the default value as foo.

正确的方法是继续使用旧的导入语法。新的导入语法仅适用于 ES 模块,旧的导入语法适用于 ES6 之前的模块。两者是不同的,故意如此。import * as foo from 'foo'导入模块 'foo' 的所有属性,它不会将默认值导入为foo.

From the designer of the feature:

来自该功能的设计师

  • An export default declaration always declares an exported member named default and is always emitted as an assignment to exports.default. In other words, export defaultconsistently has ES module semantics. For compatibility with Babel we could optionally emit an __esModulemarker when a module has a default export, but we wouldn't actually use that marker for anything.
  • An export =declaration, which substitutes a different entity to be exported in place of the module itself, is always emitted as an assignment to module.exports. It is an error to have other exports in a module that uses export =. This is the existing TypeScript behavior.
  • A module that uses export =to export another module (be that an internal or external module) can be imported using the new ES6 constructs. In particular, the convenient destructuring imports can be used with such modules. The pattern of using export =to export another module is common in .d.ts files that provide a CommonJS/AMD view of an internal module (e.g. angular.d.ts).
  • A module that uses export =to export a non-module entity in place of the module itself must be imported using the existing import x = require("foo")syntax as is the case today.
  • 导出默认声明始终声明一个名为 default 的导出成员,并且始终作为对exports.default 的赋值发出。换句话说,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 update:The TypeScript compiler at some point started allowing import * as foo from 'legacy-module-foo'to get the default import of a legacy module in certain circumstances. This is a violation of the ES6 specification(§15.2.1.16, “The value "*" indicates that the import request is for the target module's namespace object.”).

2016 年更新:TypeScript 编译器在某些时候开始允许import * as foo from 'legacy-module-foo'在某些情况下获取旧模块的默认导入。这违反了 ES6 规范(第15.2.1.16 节“值“*”表示导入请求是针对目标模块的命名空间对象。”)。

When legacy modules you import in this manner are updated to ES6 modules, the “default” imports for those modules will stop working (because * as fooimports are supposedto be importing namespace objects), which may be extremely confusing if you don't know that doing this is a TypeScript/SystemJS hack. It is also possible that a future TypeScript realignment to the ES specification will cause them to break.

当您以这种方式导入的遗留模块更新为 ES6 模块时,这些模块的“默认”导入将停止工作(因为* as foo导入应该是导入命名空间对象),如果您不知道这样做,这可能会非常混乱这是一个 TypeScript/SystemJS hack。未来 TypeScript 对 ES 规范的重新调整也有可能导致它们崩溃。

As such, you should probably prefer to continue to use the legacy import syntax described above to load legacy modules to avoid confusing yourself and other developers working on your code about how ES6 namespace imports work, and to avoid confusing breaking changes.

因此,您可能更愿意继续使用上述的遗留导入语法来加载遗留模块,以避免让您自己和其他开发人员对 ES6 命名空间导入的工作方式感到困惑,并避免混淆破坏性更改。

回答by basarat

The corresponding syntax for ES6 module syntax is:

ES6 模块语法对应的语法是:

import * as foo from 'foo';

Basically import everything from the foomodule into a local variable by the name of foo.

基本上将foo模块中的所有内容导入到名为foo.

回答by Danny Guo

As of TypeScript 2.7, there is a new esModuleInteropflag that can be used to enable default imports with CommonJS/AMD/UMD. By setting that flag to truein your tsconfig.json, this should work as expected:

TypeScript 2.7 开始,有一个新esModuleInterop标志可用于启用 CommonJS/AMD/UMD 的默认导入。通过true在您的 中将该标志设置为tsconfig.json,这应该可以按预期工作:

import foo from 'foo';

回答by cubuspl42

ES6 modules are effectively TypeScript external modules with a new syntax: ES6 modules are separately loaded source files that possibly import other modules and provide a number of externally accessible exports. ES6 modules feature several new export and import declarations. It is recommended that TypeScript libraries and applications be updated to use the new syntax, but this is not a requirement.

ES6 模块实际上是具有新语法的 TypeScript 外部模块:ES6 模块是单独加载的源文件,可能会导入其他模块并提供许多可从外部访问的导出。ES6 模块具有几个新的导出和导入声明。建议更新 TypeScript 库和应用程序以使用新语法,但这不是必需的。

Source

来源

As far as I understand, that means that you are encouraged to migrate your own TypeScript modules to the new syntax, but keep using import foo = require('foo')for importing actual AMD/CommonJS modules.

据我了解,这意味着鼓励您将自己的 TypeScript 模块迁移到新语法,但继续import foo = require('foo')用于导入实际的 AMD/CommonJS 模块。

回答by johnnyodonnell

Another option is to import it using CommonJS syntax:

另一种选择是使用 CommonJS 语法导入它:

const foo = require("foo");

TypeScript and Babel both agree on what to do with this. Also, if you're compiling down to ES5 or less anyway, then this won't be too far off from its final form.

TypeScript 和 Babel 都同意如何处理这个问题。此外,如果您无论如何要编译到 ES5 或更少,那么这与最终形式不会相差太远。

回答by Mohideen bin Mohammed

to import all ,

全部导入,

const foo = require("foo");

this will import all instance from package "foo" if its a file then

如果它是一个文件,这将从包“foo”中导入所有实例

const foo = require("./foo");

so you can access each instance by calling, foo.InstanceName

所以你可以通过调用访问每个实例, foo.InstanceName

if you want to import specific instance,

如果要导入特定实例,

import MyInstance from "foo";

so this will import specific instance (Myinstance) from "foo" you can still import all using above method,

所以这将从“foo”导入特定实例(Myinstance),您仍然可以使用上述方法导入所有实例,

import * as ReferenceName from "foo";

its equivalent to,

它相当于,

const ReferenceName = require("foo");