当前位置: 首页 > 后端技术 > Node.js

TypeScript中的各种导入解释

时间:2023-04-03 13:24:56 Node.js

JavaScript有多种导出方法,TypeScript针对这种情况有多种导入语法,最常见的是import*aspathfrom'path'。本文主要解释TypeScript中不同的imports是什么意思。原文首发于我的个人网站:Hearing-https://tasaid.com,更多技术文章推荐阅读我的网站。前端开发QQ群:377786580说到export,很多朋友问我TypeScript中不同import的含义。最典型的是以下导入语法:import*aspathfrom'path'。什么意思呢,这里要从js的导出说起。首先,JavaScript的模块化方案,在历史演进中,导出模块的方式有很多种:exports、module.exports、export、exportdefault。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模块源码:ECMAScript6中新语法export和exportdefault:exportdefaultfunction(){}exportconstsite='https://tasaid.com'exportconstname='linkFly'在这里很正常,著名的JavaScript转码编译器babel为新的导出默认语法创建了一个babel-plugin-transform-es2015-modules-commonjsECMAScript6Conversion插件,用于将ECMAScript6转码为CommonJs规范语法:源代码:exportdefault42;编译:Object.defineProperty(exports,"__esModule",{value:true});exports.default=42;到这里,我们看到exportdefaultvalues有三种语法://commonjsmodule.exports=function(){}//babeltranscodingexports.default=function(){}//es6exportdefaultfunction(){}importinTypeScript在TypeScript中,导入的方式也有很多种。//commonjs模块import*asxxfrom'xx'//es6模块importxxfrom'xx'//commonjs模块,类型声明为export=xximportxx=require('xx')//没有类型声明,默认导入anyTypeconstxx=require('xx')在tsconfig.json中,allowSyntheticDefaultImports会影响import语法的类型检查规则,下面会讲到。import*asxxfrom'xx'import*asxxfrom'xx'的语法通常用于导入使用module.exports导出的模块。import*aspathfrom'path'因为nodejs中的大部分模块都是通过module.exports,exports.xx语法导出的。importxxfrom'xx'默认情况下,importxxfrom'xx'的语法只适用于ECMAScript6的exportdefaultexport:modulefoo:exportdefaultfunction(){console.log('https://tasaid.com')}ES6模块导入:importfoofrom'./foo'foo()而我们前面说过,babel会将es6模块的exportdefault语法编译成exports.default语法。但是,默认情况下,TypeScript不识别这种语法。如果一个模块的导出是通过exports.default导出的,使用importxxfrom'xx'语法导入会报错。所以在tsconfig.json中,有一个allowSyntheticDefaultImports选项,它是兼容这种语法的。如果allowSyntheticDefaultImports设置为true,则检查导入的模块是否是ES6模块,如果不是,则检查模块中是否有exports.defaultexport。从而实现与exports.default的兼容。效果看这个动图:allowSyntheticDefaultImports选项,一般我采取的方式是重命名deafult:import{defaultasfoo}from'foo'importxx=require('xx')importxx=require('xx')它是一个用于导入commonjs模块的库。特别的是这个库的类型声明是通过export=xx:foo.js的方式导出的源码:module.exports=()=>{console.log('https://tasaid.com')}foo.d.ts类型声明文件源码:declarefunctionfoo():void;export=foobar.ts参考:importfoo=require('./foo')foo()我在《[JavaScript 和 TypeScript 交叉口 —— 类型定义文件(*.d.ts)](https://tasaid.com/blog/20171...》描述了影响导入和导出时的TypeScript类型声明文件。constxx=require('xx')当模块没有类型声明文件时,可以使用commonjs原有的require()方法导入模块,默认模块为any。总结最后总结一下,在TypeScript中,有多种导入方式,分别对应JavaScript中不同的导出方式。//commonjs模块import*asxxfrom'xx'//标准es6模块importxxfrom'xx'//commonjs模块,类型声明为export=xximportxx=require('xx')//没有类型声明,默认importanytypeconstxx=require('xx')对于babel编译出来的exports.default语法,ts提供了allowSyntheticDefaultImports选项支持,个人不推荐。就个人而言,我建议重命名默认值。import{defaultasfoo}from'foo'关于TypeScript中类型声明文件(*.d.ts)对导入导出的影响,可以参考我之前写的《[JavaScript 和 TypeScript 交叉口 —— 类型定义文件](https://tasaid.com/blog/20171...》。原文首发于我的个人网站:Hearing-https://tasaid.com,更多技术文章推荐阅读我的网站。前端开发QQ群:377786580引用参考Github-allowSyntheticDefaultImports应该是默认的吧?exports,module.exportsandexport,exportdefault是怎么回事