打字稿名称生成机制

Typescript name generation mechanism

我们正在尝试组织一个旧包。为此我们开始将原来的“export = module”形式改为“export default module”。此更改破坏了使用 eval() 的代码的另一部分,因为“import module from 'module'”正在被编译为 "module_1"。提供给 eval() 的代码来自外部源,而我们想使用模块,而不是 "module_1.default" 形式。

这种命名约定实际上是如何工作的?你能告诉我们这个概念吗?我们如何使用原始模块名称而不是编译后的模块名称?或者有没有编译后获取模块实际名称的函数?

谢谢, 亚当

使用编译器生成的名称是不安全的。它可以改变。

解决方法

但你可以这样做:

import myModule from 'module'
const module = myModule

第二行将编译为:

var module = module_1.default;

然后,您可以使用变量module

为什么要使用 export default 而不是 export =

在不久的将来,export default的使用将成为常态。此功能由 ECMAScript 设计,用于替换当前的 CommonJS 用例。成员 default 更好,更通用。

这是一个例子。您需要导出一个对象:

const myConfigObject = Object.freeze({
    dbHost: "",
    dbUser: "",
    // ...
})
export = myConfigObject

然后,您可以导入它:

import * as myConfigObject from "./myConfigObject"

随后,您想导出一个小的辅助函数 toDSN 来帮助模块用户执行与导出对象相关的操作。怎么做?您可以将助手添加为配置的成员。但这并不优雅。

这是 ES6 的方式:

export default Object.freeze({
    dbHost: "",
    dbUser: "",
    // ...
})
export function toDSN(configObj) {
    return // ...
}

然后,您可以导入默认对象:

import myConfigObject from "./myConfigObject"

... 或导入 toDSN:

import { toDSN } from "./myConfigObject"

...或同时导入:

import myConfigObject, { toDSN } from "./myConfigObject"

唯一的小陷阱是当前 Node.js 用户代码:必须使用成员 default。当Node.js将实现ES6模块时,陷阱将不再存在。

为什么TS编译器会生成中间变量用于导入?

因为ES6模块的一般情况需要它。以下 ES6 代码:

import myConfigObject, { toDSN } from "./myConfigObject"

这里导入了两个变量。但是 CommonJS(或 AMD)require 只能导入单个变量。因此,编译器将这个单个变量作为中间变量导入myConfigObject_1。然后,对象 myConfigObject 可通过 myConfigObject_1.default 访问,而 toDSN 可通过 myConfigObject_1.toDSN.

访问

我建议 the article from Mozilla 介绍 ES6 模块。