前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TypeScript防脱发级入门——模块化

TypeScript防脱发级入门——模块化

作者头像
程序员法医
发布2022-08-11 16:48:15
4920
发布2022-08-11 16:48:15
举报
文章被收录于专栏:vue全家桶vue全家桶

嗨!大家好!我是法医,一只治疗系前端码猿🐒,与代码对话,倾听它们心底的呼声,期待着大家的点赞👍与关注➕。

TS模块化

1. TS中如何书写模块化

TS中,导入和导出模块,建议统一使用ES6的模块化标准

新建module.ts文件,导出变量name函数numRes

代码语言:javascript
复制
//导出变量name和函数numRes
export const name = "法医";

export function numRes(num1:number,num2:number) {
    return num1 + num2;
}

新建index.ts文件,用于导入namenumRes

代码语言:javascript
复制
import { name, numRes } from "./myModule";

console.log(name);//输出 “法医”
console.log(numRes(1,2));// 打印 3

在TS中使用模块化是比较简单的,并且我们在导入的时候是不需要自己写import的,可以利用TS的智能提示,如下:

想要利用TS的智能提示有个前提,那就是在导出文件的时候需要使用普通的导出方式,而不是默认的导出方式,默认导出是没有智能提示的

代码语言:javascript
复制
//普通导出有智能提示
export const name = "法医";

export function numRes(num1:number,num2:number) {
    return num1 + num2;
}

//默认导出没有智能提示
export default {
    name: "法医",
    numRes:function (num1:number,num2:number) {
        return num1 + num2;
    }
}

还有一个点需要注意,就是在导入模块的时候不要加后缀名tsimport { name, numRes } from "./myModule.ts";

之所以会报错,是因为导入模块文件会进行编译,如果存在ts后缀名,在编译后的js文件中找不到ts文件的,所以会报错

2. 编译结果的模块化

TS中使用模块化,有时会使用ES6模块化,有时使用CommonJS模块化,所以也是有必要了解编译后的JS使用的是哪种模块化标准。

首先我们应该清楚一点,关于编译结果中的到底使用哪种模块化是可配置的,配置文件是tsconfig.json中的module属性,它就是用来配置编译后的JS文件是使用哪种模块化标准的

代码语言:javascript
复制
{
  "compilerOptions": {//配置编译选项
    "target": "es2016",//编译时用的哪一套ES标准
    "module": "es6",//配置编译目标使用的模块化标准,commjs是node环境中的标准,es6也可以
    "lib": ["ES2016"],//默认是有dom环境的,但现在用不到,这里面是没有node环境配置的,需要安装第三方库
    "outDir": "./dist",//将编译的结果放在哪个目录下面
    "strictNullChecks": true,//表示更加严格的空类型检查
  },
}

使用ES6标准对比编译前和编译后

es6模块化导出:

由于在TS里面本身使用的是ES6的标准,而对编译结果配置的时候也是ES6的标准,所以从代码来看,两者没有任何区别的,编译结果只是取消了类型约束。

es6模块化导入:

从代码来看使用es6模块导入也是一模一样,没有任何区别的

👉 「小知识:」

从前后编译的结果来看,当TS代码中有注释的时候,编译后的JS文件也是会有注释的,如果不希望注释被编译到结果中,此时可以在tsconfig.json进行配置"removeComments": true,//表示移除注释,配置如下:

代码语言:javascript
复制
{
  "compilerOptions": {//配置编译选项
    "target": "es2016",//编译时用的哪一套ES标准
    "module": "es6",//配置编译目标使用的模块化标准,commjs是node环境中的标准,es6也可以
    "lib": ["ES2016"],//默认是有dom环境的,但现在用不到,这里面是没有node环境配置的,需要安装第三方库
    "outDir": "./dist",//将编译的结果放在哪个目录下面
    "strictNullChecks": true,//表示更加严格的空类型检查
    "removeComments": true,//表示移除注释
  },
}

使用CommonJS对比编译前和编译后

CommonJS模块化导出:

当我们使用commonJs模块化导出的时候,会发现编译后的结果跟编译前有很大差异,在JS文件中会发现第一行是use strict严格模式,其实use strict是没必要出现在编译结果中的,因为我们写的TS代码本身够严格了,因此我们可以进行配置:

代码语言:javascript
复制
{
  "compilerOptions": {//配置编译选项
    "target": "es2016",//编译时用的哪一套ES标准
    "module": "CommonJS",//配置编译目标使用的模块化标准,commjs是node环境中的标准,es6也可以
    "lib": ["ES2016"],//默认是有dom环境的,但现在用不到,这里面是没有node环境配置的,需要安装第三方库
    "outDir": "./dist",//将编译的结果放在哪个目录下面
    "strictNullChecks": true,//表示更加严格的空类型检查
    "removeComments": true,//表示移除注释
    "noImplicitUseStrict": true,//表示编译结果中不包含use strict
  },
}

接下来我们看这一行代码Object.defineProperty(exports, "__esModule", { value: true });这行代码圣骑士相当于exports._esModule = true;至于有什么作用这里先不说,一会说。

CommonJS模块化导入:

commonJs中是没有import..from..的,它只能通过require方式导入,在编译后的结果里它会自动声明一个变量,也就是上述代码中的myModule_1,这个变量是文件名 + "_" + 编号,如果有多次导入的话,编号会依次自增。

在开发过程中很多时候不需要关心导入导出编译的结果是什么,但是了解这个编译结果对处理细节问题上是有帮助的

总结:

有的时候我们会遇到比较特殊的情况,比如说我们想使用node里面的fs,此时会报错,比如说:

  • 如果编译结果的模块化标准是ES6:没有区别

3. 解决默认导入的错误

这部分研究在TS中使用默认导出时产生报错的问题,想要知道什么原因导致的,其实看看编译后的结果也就明白了

从代码中看,fs提示没有默认导出,这里报错的原因是fs不是通过TS写的,在fs模块里面它是通过module.exports = {}方式导出的,因此导入的时候加一个default,那肯定是不行的,这时候我们可以这么处理:

之所以会产生这么个问题,是因为有些模块不是我们自己写的,我们自己写直接统一使用ES6模块就可以了,不会有什么问题,但是以前有些模块使用module.exports = {}方式导出的,这就很尴尬,只能寻找其它解决办法,上述是其中一种办法,但是这种方式不太好,因为fs对象里面不仅仅只有一个函数,有很多,总不能挨个写一遍把,这肯定是太麻烦了,然而我们可以「导入所有内容,然后起个别名」这种方式处理:

但是对于有强迫症的人来说,我就不想用这种方式,那么还有最后一个办法,在tsconfig.json中配置"esModuleInterop":true,意思是启动es模块化交互非es模块导出

代码语言:javascript
复制
{
  "compilerOptions": {//配置编译选项
    "target": "es2016",//编译时用的哪一套ES标准
    "module": "CommonJS",//配置编译目标使用的模块化标准,commjs是node环境中的标准,es6也可以
    "lib": ["ES2016"],//默认是有dom环境的,但现在用不到,这里面是没有node环境配置的,需要安装第三方库
    "outDir": "./dist",//将编译的结果放在哪个目录下面
    "strictNullChecks": true,//表示更加严格的空类型检查
    "removeComments": true,//表示移除注释
    "noImplicitUseStrict": true,//表示编译结果中不包含use strict
    "esModuleInterop":true,//启动es模块化交互非es模块导出    
  },
}

配置之后,代码不会报错了

4. 在TS中如何使用CommonJs导入导出

导出:export = xxx;

代码语言:javascript
复制
//举个栗子
export = {
    name:"法医",
    sayHello(a:string,b:string){
        return a + b;
    }
}

导入:import xxx = require("xxx");

代码语言:javascript
复制
//举个栗子
import module = require("myModule");

最后

很感谢小伙伴看到最后😘,如果您觉得这篇文章有帮助到您的的话不妨关注➕+点赞👍+收藏📌+评论📜,您的支持就是我更新的最大动力。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端猎手 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • TS模块化
  • 1. TS中如何书写模块化
  • 2. 编译结果的模块化
  • 3. 解决默认导入的错误
  • 4. 在TS中如何使用CommonJs导入导出
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档