nextJS项目内引入TS的基础设施+使用ts书写express服务端(express+客户端)

Next本来就内置了ts的webpack配置、babel配置,想要引入的成本很低。
但是难点在于:我们的nextjs项目另外采用了express作为服务端服务器框架,如何将express内的Node代码也改造成使用ts呢?
还有最痛苦的问题就是不知道express怎么写ts啊啊啊,我原本的文件都是用CJS导入导出的,但是根本不支持导出type,导致我写个type到处都是报错😭

总之把一些步骤和解决措施放在下面。

react项目引入ts基础配置

参考:https://juejin.cn/post/7128929470618009608
Next typescript 文档

1. 安装新的依赖

1. 安装typescript

npm i -D typescript

安装完typescript后,其实ts内置了一个tsc命令,tsc命令可以生成配置文件、检查ts的类型错误。
使用tsc --init创建一个tsconfig.json文件,里面就是解析ts文件的各种配置。
一份可供参考的tsconfig文件如下:
🔗tsconfig官方文档文档链接

{// 编译选项"compilerOptions": {// 生成代码的语言版本:将我们写的 TS 代码编译成哪个版本的 JS 代码"target": "esnext",// 生成代码的模块化标准"module": "esnext",// 指定要包含在编译中的 library"lib": ["dom", "dom.iterable", "esnext"],// 允许 ts 编译器编译 js 文件"allowJs": true,// 跳过类型声明文件的类型检查"skipLibCheck": true,// es 模块 互操作,屏蔽 ESModule 和 CommonJS 之间的差异"esModuleInterop": true,// 允许通过 import x from 'y' 即使模块没有显式指定 default 导出"allowSyntheticDefaultImports": true,// 开启严格模式"strict": true,// 对文件名称强制区分大小写"forceConsistentCasingInFileNames": true,// 为 switch 语句启用错误报告"noFallthroughCasesInSwitch": true,// 模块解析(查找)策略"moduleResolution": "node",// 允许导入扩展名为.json的模块"resolveJsonModule": true,// 是否将没有 import/export 的文件视为旧(全局而非模块化)脚本文件"isolatedModules": true,// 编译时不生成任何文件(只进行类型检查)"noEmit": true,// 指定将 JSX 编译成什么形式"jsx": "react-jsx",// 如果指定,.ts文件将被输出到此目录中,否则留在源文件的目录结构中"outDir": "build/dist",// 当前的根目录"baseUrl": ".",// 不需要定义:所有可见的“node_modules@types/**”包都会被默认收集。但是如果被定义了那就不会默认收集了// "types": ["node"],},// 指定允许 ts 处理的目录"include": ["**/*.ts","**/*.tsx","next-env.d.ts"],// tsc排除的目录"exclude": ["node_modules", "build", "dist"]}

ts文件中存在的几个定义:

  • .ts 或 .tsx文件
    .ts ts 文件的后缀名 .tsx 是在 TS 中使用 React 组件时,需要使用该后缀
  • d.ts 文件
    .d.ts 类型声明文件,用来指定类型,可以定义全局type。
    不会生成 .js 文件,仅用于提供类型信息,在.d.ts文件中不允许出现可执行的代码,只用于提供类型

2. 引入ts的babel解析 & webpack的ts-loader(next/babel已经帮我们集成了这一步)

npm i -D @babel/preset-typescript ts-loader 

然后在.babelrc中配置preset。
webpack中配置ts-loader,进行编译过程中的类型校验,如果类型错误将中断校验。

babel编译和ts-loader编译的区别与互补说明:🔗https://juejin.cn/post/7127206384797483044

next.config中提供了编译中跳过tsc的方式:

 typescript: {ignoreBuildErrors: true, // 跳过build时的ts校验,交给eslint和husky拦截},

2. 引入常用的框架中的ts type

引入之后不用操作,tsc会自动找到@/types包下的文件的。

npm i -D @types/lodash @types/react @types/node @types/express

3. 完善ts的eslint配置

ts没有专门的tslint,它的创始人推荐使用eslint插件配置在eslint中。

TSLint is deprecated.
See this issue for more details: Roadmap: TSLint → ESLint. If you’re interested in helping with the TSLint/ESLint migration, please check out our OSS Fellowship program.

npm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser

同时在husky的命令中增加.ts / .tsx
eslintrc.js中配置:

  overrides: [{files: ['**/*.ts', '**/*.tsx'],extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],parserOptions: {project: './tsconfig.json',},parser: '@typescript-eslint/parser',rules: {// 不允许显式声明any'@typescript-eslint/no-explicit-any': 2,},},],

4. 编写tsx文件,.d.ts文件

测试类型校验、eslint校验是否可行。

express服务端引入ts

参考:
next-express-github-demo
使用TS来编写express服务器

我这边的express服务端文件都在/server文件夹下,项目目录结构大概如下:
.
├── build 编译文件
├── server 服务端
├── src 客户端
├── tsconfig.server.json
├── tsconfig.json
├── eslintrc.js
├── next.config.js
├── ……
└── src

配置服务端的类型校验

1. 安装新的依赖(上面已经安装过了)

npm i -D @types/node @types/express

2. 生成node端专用的tsconfig.json文件。

我取名为tsconfig.server.json

 {// 引入扩展"extends": "./tsconfig.json","compilerOptions": {"target": "ES6",  // 指定生成的JS代码的ECMAScript版本"module": "CommonJS", // 指定生成的JavaScript模块系统"strict": true,   // 开启所有严格类型检查选项"esModuleInterop": true,  // 启用esModuleInterop以兼容CommonJS和ES模块"skipLibCheck": true,  // 跳过定义文件的类型检查"outDir": "build/dist",  // 编译输出目录"rootDir": ".",  // 源码目录"resolveJsonModule": true,  // 允许导入JSON模块"sourceMap": true  // 生成source map文件"allowSyntheticDefaultImports":true, // babel转换时可配置:即使CJS模块本身没有default导出,仍然可以使用default导入。(兼容ECM / CJS)"moduleResolution":"Node", // 使用Nodejs方案解析},"include": ["server/**/*.ts"],  // 包含的TypeScript文件"exclude": ["node_modules"]  // 排除的目录
}
baseUrl
  • 作用: 决定非相对模块导入时的基准目录。
  • 使用场景: 在代码中使用非相对路径(例如,import { x } from 'myModule')时,TypeScript会根据baseUrl配置的路径作为起点寻找模块。
  • 默认值: 如果未指定,使用当前目录。
  • 示例: 如果设置了baseUrl"./src",然后在代码中使用import { x } from 'utils/helper',TypeScript将会在src/utils/helper.tssrc/utils/helper/index.ts中寻找模块。
rootDir
  • 作用: 用于控制编译器如何安排输出文件的目录结构。
  • 使用场景: 影响编译输出的目录结构,通常与outDir一起使用来规范地管理编译后的代码。
  • 默认值: 如果未指定,则TypeScript自动推断,通常为输入文件的共同上级路径。
  • 示例: 假设项目结构是src/utils/helper.ts,设定rootDir"src",而outDir"dist",那么编译时helper.ts会被输出为dist/utils/helper.js
allowSyntheticDefaultImports

可以影响模块的导入方式。启用这个选项后,即使模块本身没有default导出,仍然可以使用default导入。

  • 在CommonJS中,模块并没有默认的default,但Babel 转译会生成一个名为 default 的导出,使得ES6可以像导入默认导出那样导入CJS对象。

  • 如果项目使用了 Babel 来转译,可能会生成允许默认导入的代码形式,启用该选项可以使 TypeScript 和 Babel 的行为保持一致。

eslint配置

eslintrc记得增加tsconfig.server.json

parserOptions: {project: ['./tsconfig.json','./tsconfig.server.json']
},

检查是否可以编写服务端ts文件

如果还是没有ts提示,看看tsconfig的include有没有配置对,需要重启vscode。

配置nodemon运行时编译ts的命令

nodemon是express服务端开发的常用工具配置。
上面的ts类型校验完善后,这时候你会发现我们的项目启动不起来,因为服务器端没有babel给它编译成ts,我们想要在node端实时编译ts,通常需要结合使用 ts-node,它可以在运行时直接编译和执行 TypeScript 文件。

npm i -D ts-node

然后变更nodemon命令,原本是nodemon server/index.js,现在要加上指定命令行以ts-node的形式执行:

nodemon --exec ts-node server/index.js

配置ts文件的build命令

typescript带来的tsc命令可以把ts文件编译成js文件,所以你也可以看到有些demo的build命令直接就是一个tsc,但是因为商业项目中涉及到的其他文件太多,我们往往使用webpack+babel的方案将ts转化成js。

在上面的客户端引入ts中我们已经下载了ts-loader@babel/preset-typescript,也进行了配置,因此我们的build命令仍然正常使用webpack打包就可以了。

但是next的打包是专门提供了一个next build命令,这个命令只适用于next的代码,对于我们自行搭建的express服务器的代码没有办法执行,因此我们额外需要对ts的服务器端配置需要专门指定tsconfig。修改如下:

next build && tsc --project tsconfig.server.json

如何在express中书写ts文件?

不知道大家有没有遇到这个问题:原本的文件都是用CJS导入导出的,但是根本不支持导出type,写个type到处都是报错😭
参考:
利用typescript + express 开发一个nodejs服务端demo

看起来,CJS的type只能写.d.ts文件?
比如:我们可以定义一个custom.d.ts文件,在Request的接口中添加我们加入的属性,这样在使用的时候就会出现提示。custom.d.ts文件会和@types/express里面的类型文件进行合并。

// costom.d.ts
declare namespace Express {interface Request {teacherName: string}
}

但是使用ES6就可以直接导出type,不用声明import type xxx

🌰
// ErrorResponse.ts
export default interface ErrorResponse {message: string;stack?: string;
}// index.js
import MessageResponse from '../interfaces/MessageResponse';router.get<{}, MessageResponse>('/', (req, res) => {res.json({message: '',});
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/439916.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【S32K3 RTD MCAL 篇1】 K344 KEY 控制 EMIOS PWM

【S32K3 RTD MCAL 篇1】 K344 KEY 控制 EMIOS PWM 一&#xff0c;文档简介二&#xff0c; 功能实现2.1 软硬件平台2.2 软件控制流程2.3 资源分配概览2.4 EB 配置2.4.1 Dio module2.4.2 Icu module2.4.4 Mcu module2.4.5 Platform module2.4.6 Port module2.4.7 Pwm module 2.5 …

STM32+ADC+扫描模式

1 ADC简介 1 ADC(模拟到数字量的桥梁) 2 DAC(数字量到模拟的桥梁)&#xff0c;例如&#xff1a;PWM&#xff08;只有完全导通和断开的状态&#xff0c;无功率损耗的状态&#xff09; DAC主要用于波形生成&#xff08;信号发生器和音频解码器&#xff09; 3 模拟看门狗自动监…

Oracle架构之数据库备份和RAC介绍

文章目录 1 数据库备份1.1 数据库备份分类1.1.1 逻辑备份与物理备份1.1.2 完全备份/差异备份/增量备份 1.2 Oracle 逻辑备份1.2.1 EXP/IMP1.2.1.1 EXP导出1.2.1.2 EXP关键字说明1.2.1.3 导入1.2.1.4 IMP关键字说明 1.2.2 EXPDP/IMPDP1.2.2.1 数据泵介绍1.2.2.2 数据泵的使用 1.…

通过 Groovy 实现业务逻辑的动态变更

Groovy 1、需求的提出2、为什么是Groovy3、设计参考1_引入Maven依赖2_GroovyEngineUtils工具类3_GroovyScriptVar类4_脚本规则表设计5_对应的实体类6_数据库访问层7_GroovyExecService通用接口 4、测试5、其他的注意事项6、总结 1、需求的提出 在我们日常的开发过程中&#xf…

嵌入式知识点复习(一)

国庆倒数第二天&#xff0c;进行嵌入式课堂测试的复习&#xff1a; 第一章 绪论 1.1 嵌入式系统的概念 嵌入式系统定义 嵌入式系统定位 嵌入式系统形式 嵌入式系统三要素 嵌入式系统与桌面通用系统的区别 1.2 嵌入式系统的发展历程 微处理器的演进历史 单片机的演进历史 …

【易社保-注册安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

【Python】数据可视化之聚类图

目录 clustermap 主要参数 参考实现 clustermap sns.clustermap是Seaborn库中用于创建聚类热图的函数&#xff0c;该函数能够将数据集中的样本按照相似性进行聚类&#xff0c;并将聚类结果以矩阵的形式展示出来。 sns.clustermap主要用于绘制聚类热图&#xff0c;该热图通…

用manim实现Gram-Schmidt正交化过程

在线性代数中&#xff0c;正交基有许多美丽的性质。例如&#xff0c;由正交列向量组成的矩阵(又称正交矩阵)可以通过矩阵的转置很容易地进行反转。此外&#xff0c;例如&#xff1a;在由彼此正交的向量张成的子空间上投影向量也更容易。Gram-Schmidt过程是一个重要的算法&#…

Python Tips6 基于数据库和钉钉机器人的通知

说明 起因是我第一版quant程序的短信通知失效了。最初认为短信是比较即时且比较醒目的通知方式&#xff0c;现在看来完全不行。 列举三个主要问题&#xff1a; 1 延时。在早先还能收到消息的时候&#xff0c;迟滞就很严重&#xff0c;几分钟都算短的。2 完全丢失。我手机没有…

AI 时代:产品经理不“AI”就出局?

即便你没想去做“AI 产品经理”&#xff0c;那你也不能成为一个不会用 AI 的产品经理。 产品经理肯定是所有互联网从业者中&#xff0c;最先捕捉到 AI 趋势的岗位。 但只知道 AI、关注 AI 还不够&#xff0c;仔细审视一下&#xff1a;你自己的工作&#xff0c;被 AI 提效了么…

《Windows PE》4.1导入表

导入表顾名思义&#xff0c;就是记录外部导入函数信息的表。这些信息包括外部导入函数的序号、名称、地址和所属的DLL动态链接库的名称。Windows程序中使用的所有API接口函数都是从系统DLL中调用的。当然也可能是自定义的DLL动态链接库。对于调用方&#xff0c;我们称之为导入函…

安防监控/视频系统EasyCVR视频汇聚平台如何过滤134段的告警通道?

视频汇聚/集中存储EasyCVR安防监控视频系统采用先进的网络传输技术&#xff0c;支持高清视频的接入和传输&#xff0c;能够满足大规模、高并发的远程监控需求。平台支持国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为…

STM32定时器(TIM)

目录 一、概述 二、定时器的类型 三、时序 四、定时器中断基本结构 五、定时器定时中断代码 六、定时器外部时钟代码 一、概述 TIM(Timer)定时器 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断16位计数器、预分频器、自动重装寄存器的时基…

力扣刷题 | 两数之和

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 给定一个整数数组 nums 和…

网站建设完成后,切勿让公司官网成为摆设

在当今这个数字化时代&#xff0c;公司官网已经成为企业展示形象、传递信息、吸引客户的重要平台。然而&#xff0c;许多企业在网站建设完成后&#xff0c;往往忽视了对官网的持续运营和维护&#xff0c;导致官网逐渐沦为摆设&#xff0c;无法发挥其应有的作用。为了确保公司官…

15分钟学 Python 第40天:Python 爬虫入门(六)第一篇

Day40 &#xff1a;Python 爬取豆瓣网前一百的电影信息 1. 项目背景 在这个项目中&#xff0c;我们将学习如何利用 Python 爬虫技术从豆瓣网抓取前一百部电影的信息。通过这一练习&#xff0c;您将掌握网页抓取的基本流程&#xff0c;包括发送请求、解析HTML、存储数据等核心…

jvisualvm学习

系列文章目录 JavaSE基础知识、数据类型学习万年历项目代码逻辑训练习题代码逻辑训练习题方法、数组学习图书管理系统项目面向对象编程&#xff1a;封装、继承、多态学习封装继承多态习题常用类、包装类、异常处理机制学习集合学习IO流、多线程学习仓库管理系统JavaSE项目员工…

ssm服装店销售管理系统

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 摘 要 I Abstract II 第1章 绪论 1 1.1研究背景 1 1.2研究意义 1 1.3国内外研究现状 2 1.3.1国外研…

提高顾客满意度,餐饮业如何开展客户调研?

餐饮行业需明确调研目的&#xff0c;选择合适工具&#xff0c;设计问卷&#xff0c;收集并分析数据&#xff0c;持续追踪优化。通过客户调研&#xff0c;提升服务质量、顾客满意度和竞争力&#xff0c;利用ZohoSurvey等工具实现高效调研。 一、明确调研目的 进行客户调研前&am…

【hot100-java】【将有序数组转换为二叉搜索树】

二叉树篇 中序遍历实现 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right…