简体   繁体   English

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

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

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 模块语法中实现相同的正确方法是什么。

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.新的导入语法仅适用于 ES 模块,旧的导入语法适用于 ES6 之前的模块。 The two are distinct, intentionally so.两者是不同的,故意如此。 import * as foo from 'foo' imports all the properties of the module 'foo', it does not import the default value as foo . 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.导出默认声明始终声明一个名为 default 的导出成员,并且始终作为对exports.default 的赋值发出。 In other words, export default consistently has ES module semantics.换句话说, export default始终具有 ES 模块语义。 For compatibility with Babel we could optionally emit an __esModule marker when a module has a default export, but we wouldn't actually use that marker for anything.为了与 Babel 兼容,当模块具有默认导出时,我们可以选择发出__esModule标记,但我们实际上不会将该标记用于任何事情。
  • 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 .一个export =声明,它替换一个不同的实体来代替模块本身,总是作为对module.exports的赋值module.exports It is an error to have other exports in a module that uses export = .在使用export =的模块中有其他导出是错误的。 This is the existing TypeScript behavior.这是现有的 TypeScript 行为。
  • A module that uses export = to export another module (be that an internal or external module) can be imported using the new ES6 constructs.使用export =导出另一个模块(内部或外部模块)的模块可以使用新的 ES6 结构导入。 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 (eg angular.d.ts).使用export =导出另一个模块的模式在 .d.ts 文件中很常见,这些文件提供内部模块的 CommonJS/AMD 视图(例如 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.使用export =导出非模块实体代替模块本身的模块必须使用现有的import x = require("foo")语法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. 2016 年更新: TypeScript 编译器在某个时候开始允许import * as foo from 'legacy-module-foo'在某些情况下获取旧模块的默认导入。 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 .” ).这违反了 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 foo imports are supposed to be importing namespace objects ), which may be extremely confusing if you don't know that doing this is a TypeScript/SystemJS hack.当您以这种方式导入的遗留模块更新为 ES6 模块时,这些模块的“默认”导入将停止工作(因为* as foo导入应该导入命名空间对象),如果您不这样做,这可能会非常混乱知道这样做是 TypeScript/SystemJS hack。 It is also possible that a future TypeScript realignment to the ES specification will cause them to break.未来 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 命名空间导入的工作方式感到困惑,并避免混淆破坏性更改。

The corresponding syntax for ES6 module syntax is: ES6 模块语法对应的语法是:

import * as foo from 'foo';

Basically import everything from the foo module into a local variable by the name of foo .基本上将foo模块中的所有内容导入到名为foo的局部变量中。

As of TypeScript 2.7 , there is a new esModuleInterop flag that can be used to enable default imports with CommonJS/AMD/UMD.TypeScript 2.7 开始,有一个新的esModuleInterop标志可用于启用 CommonJS/AMD/UMD 的默认导入。 By setting that flag to true in your tsconfig.json , this should work as expected:通过在您的tsconfig.json将该标志设置为true ,这应该可以按预期工作:

import foo from 'foo';

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 模块实际上是具有新语法的 TypeScript 外部模块:ES6 模块是单独加载的源文件,可能会导入其他模块并提供许多外部可访问的导出。 ES6 modules feature several new export and import declarations. ES6 模块具有几个新的导出和导入声明。 It is recommended that TypeScript libraries and applications be updated to use the new syntax, but this is not a requirement.建议更新 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 模块。

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");

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. TypeScript 和 Babel 都同意如何处理这个问题。 Also, if you're compiling down to ES5 or less anyway, then this won't be too far off from its final form.此外,如果您无论如何要编译到 ES5 或更少,那么这与最终形式不会相差太远。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM