摘要:中有多种的方式,而中针对这种情况做了多种语法,最常见的就是这种。这篇文章主要来讲解中不同的具有什么意义。因为中的模块大部分都是通过语法进行导出的。从而达到针对的兼容。个人建议将重命名。
JavaScript 中有多种 export 的方式,而 TypeScript 中针对这种情况做了多种 import 语法,最常见的就是 import * as path from "path" 这种。这篇文章主要来讲解 TypeScript 中不同的 import 具有什么意义。
原文首发于我的个人网站:听说 - https://tasaid.com,推荐在我的网站阅读更多技术文章。
前端开发 QQ 群:377786580从 export 说起
有很多朋友都问过我关于 TypeScript 中不同 import 的含义,最典型的就是下面的 import 语法:
import * as path from "path"
不少人疑问这句代码究竟是什么意思,这里我们要先从 js 的 export 开始说。
首先,JavaScript 的模块化方案,在历史的演进中,有多种导出模块的方式:exports、module.exports、export、export default。
在 nodejs 中内置的模块遵循的都是 CommonJS 规范,语法为 module.exports 和 exports。
// 模块中的 exports 变量指向 module.exports // 这篇文章不会深入讲解 module.exports 和 exports 的关系 module.exports = function () { } exports.site = "https://tasaid.com" module.exports.name = "linkFly"
例如 nodejs 内置的 events 模块的源码:
在 ECMAScript 6 中又新增了语法 export 和 export default:
export default function () { } export const site = "https://tasaid.com" export const name = "linkFly"
到这里画风还比较正常,而大名鼎鼎的 JavaScript 转码编译器 babel 针对 ECMAScript 6 新增的 export default 语法,搞了个 babel-plugin-transform-es2015-modules-commonjs 的转换插件,用于将 ECMAScript 6 转码为 CommonJs 规范的语法:
源码:
export default 42;
编译后:
Object.defineProperty(exports, "__esModule", { value: true }); exports.default = 42;
到这里,我们看到有三种 export 默认值的语法:
// commonjs module.exports = function () {} // babel 转码 exports.default = function () {} // es6 export default function () {}TypeScript 中的 import
在 TypeScript 中,也有多种 import 的方式。
// commonjs 模块 import * as xx from "xx" // es6 模块 import xx from "xx" // commonjs 模块,类型声明为 export = xx import xx = require("xx") // 没有类型声明,默认导入 any 类型 const xx = require("xx")
在 tsconfig.json 中,allowSyntheticDefaultImports 会影响到 import 语法的类型检查规则,这个下面再说。
import * as xx from "xx"import * as xx from "xx" 的语法来一般都是用来导入使用 module.exports 导出的模块。
import * as path from "path"
因为 nodejs 中的模块大部分都是通过 module.exports、exports.xx 语法进行导出的。
import xx from "xx"默认情况下,import xx from "xx" 的语法只适用于 ECMAScript 6 的 export default 导出:
模块 foo:
export default function () { console.log("https://tasaid.com") }
ES6 模块的导入:
import foo from "./foo" foo()
而前面我们说了,babel 会将 es6 的模块的 export default 语法编译为 exports.default 语法。
而 TypeScript 默认是不识别这种语法的,如果一个模块的导出是 exports.default 导出,如果使用 import xx from "xx" 的语法导入是会报错的。
所以在 tsconfig.json 中,有个 allowSyntheticDefaultImports 选项,就是针对这种语法做兼容。
如果设定 allowSyntheticDefaultImports 为 true,则检测导入的模块是否是 ES6 模块,如果不是,则查找模块中是否有 exports.default 导出。
从而达到针对 exports.default 的兼容。
效果参见这个动画:
allowSyntheticDefaultImports 选项的,一般情况下我采取的方式是将 deafult 重新命名:
import { default as foo } from "foo"import xx = require("xx")
import xx = require("xx") 是用来导入 commonjs 模块的库,特殊的地方在于这个库的类型声明是 export = xx 这种方式导出的:
foo.js 源码:
module.exports = () => { console.log("https://tasaid.com") }
foo.d.ts 类型声明文件源码:
declare function foo(): void; export = foo
bar.ts 引用:
import foo = require("./foo") foo()
我在 《[JavaScript 和 TypeScript 交叉口 —— 类型定义文件(*.d.ts)
](https://tasaid.com/blog/20171...》中讲述过 TypeScript 类型声明文件对导入导出的影响。
当一个模块没有类型声明文件的时候,可以使用 commonjs 原始的 require() 方式来导入模块,这样会默认该模块为 any。
总结最后我们整体总结下,在 TypeScript 中,有多种 import 的方式,分别对应了 JavaScript 中不同的 export。
// commonjs 模块 import * as xx from "xx" // 标准 es6 模块 import xx from "xx" // commonjs 模块,类型声明为 export = xx import xx = require("xx") // 没有类型声明,默认导入 any 类型 const xx = require("xx")
针对 babel 编译出来的 exports.default 语法,ts 提供了 allowSyntheticDefaultImports 选项可以支持,只不过个人不太推荐。
个人建议将 default 重命名。
import { default as foo } from "foo"
关于 TypeScript 中类型声明文件(*.d.ts) 对 import 和 export 的影响,可以参考我之前写的 《[JavaScript 和 TypeScript 交叉口 —— 类型定义文件
](https://tasaid.com/blog/20171...》。
原文首发于我的个人网站:听说 - https://tasaid.com,推荐在我的网站阅读更多技术文章。
前端开发 QQ 群:377786580引用和参考
Github - allowSyntheticDefaultImports should be the default?
exports、module.exports和export、export default到底是咋回事
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/101995.html
摘要:逻辑学的语义学着眼点在于逻辑系统的语义解释,是一个理想化的模型系统,不直接涉及自然语言。例如,通过帮助临床研究中的决策,语义技术将跨机构桥接多种形式的生物和医学信息。 showImg(https://segmentfault.com/img/bVbrJYw?w=758&h=420); 前端工程师的招聘中,经常有这样的要求:对Web 语义化有深刻理解。那么到底什么才是深刻理解Web语义化...
摘要:调用通过注册表调用到实例,透过的,调用到中的,最后通过,调用,根据参数相应模块执行。京东的,多端解决方案是一套遵循语法规范的多端开发解决方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 对于一项技术,我们不能停留在五分钟状态,特别喜欢一句话,用什么方式绘制UI界面一点不重要,重要的是底层的思维,解决问题和优化...
摘要:调用通过注册表调用到实例,透过的,调用到中的,最后通过,调用,根据参数相应模块执行。京东的,多端解决方案是一套遵循语法规范的多端开发解决方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 对于一项技术,我们不能停留在五分钟状态,特别喜欢一句话,用什么方式绘制UI界面一点不重要,重要的是底层的思维,解决问题和优化...
摘要:调用通过注册表调用到实例,透过的,调用到中的,最后通过,调用,根据参数相应模块执行。京东的,多端解决方案是一套遵循语法规范的多端开发解决方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 对于一项技术,我们不能停留在五分钟状态,特别喜欢一句话,用什么方式绘制UI界面一点不重要,重要的是底层的思维,解决问题和优化...
阅读 3522·2021-10-09 09:43
阅读 6116·2021-09-07 10:15
阅读 2729·2019-08-30 14:03
阅读 3055·2019-08-29 11:01
阅读 1686·2019-08-29 10:56
阅读 1056·2019-08-28 17:52
阅读 3480·2019-08-26 11:42
阅读 2529·2019-08-26 10:33