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

news2024/10/7 5:16:50

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.coloradmin.cn/o/2193560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sublime Text 下载地址分享

Sublime Text官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘123云盘为您提供Sublime Text最新版正式版官方版绿色版下载,Sublime Text安卓版手机版apk免费下载安装到手机,支持电脑端一键快捷安装https://www.123684.com/s/kPxoTd-dCnxHSublime Text官方版下载丨最新版下…

双十一可以买什么物品?重磅推荐五款好用品牌!

距离今年的双十一盛典仅剩数十日&#xff0c;您是否已将心爱商品添加至购物车中了呢&#xff1f;还在犹豫未满载的朋友也无需焦虑&#xff0c;特意为您精选了五款好用的宝贝推荐&#xff0c;旨在为您的购物清单增添几分灵感与便捷&#xff0c;期待能为您的双十一购物之旅增添一…

GPU 是否有朝一日可以取代 CPU?

讨论 GPU 是否能够取代 CPU&#xff0c;需要从两者的基本架构、设计目的、性能表现、应用领域等多个方面进行分析。虽然你提到的4060显卡的核心频率接近服务器 CPU 的频率&#xff0c;这看起来似乎有一些相似性&#xff0c;但 GPU 和 CPU 的设计思路和适用场景差异显著&#xf…

18448 最小生成树

### 思路 使用Kruskal算法求解图的最小生成树。Kruskal算法通过对所有边按权值排序&#xff0c;然后逐步选择最小权值的边&#xff0c;确保不会形成环&#xff0c;直到构建出最小生成树。 ### 伪代码 1. 读取输入的结点数n和边数m。 2. 读取每条边的信息&#xff0c;存储在边列…

羊城杯2024WP

羊城杯-2024 web web2 进题信息搜集一下&#xff0c;dirsearch发现了login路由可访问&#xff0c;先随便点一下&#xff0c;发现了一个文件读取&#xff1a; http://139.155.126.78:30148/lyrics?lyricsRain.txt 我尝试了一下&#xff1a; http://139.155.126.78:30148/lyrics…

【教学类-77-02】20241007青花瓷纹理纸(手工)

背景需求&#xff1a; 大班《我是中国人》主题下&#xff0c;有一个“青花瓷”的主题&#xff0c;各种平面绘画 这些青花瓷花瓶、盘子都是平面的&#xff0c;我想能不能做个立体的&#xff0c;所以前期设计了“青花瓷立体卡”【教学类-77-01】20241005青花瓷立体书-CSDN博客文…

构建 10 万卡 GPU 集群的技术挑战

构建 10 万卡 GPU 集群的技术挑战 摘要 揭示AI训练集群关键基础设施挑战&#xff0c;探讨突破现有AI瓶颈的必要性与10万GPU集群&#xff08;如OpenAI、Meta&#xff09;建设所面临挑战与需求。 构建网络拓扑&#xff0c;需权衡多层交换机成本、带宽与维护。本文对比Ethernet与…

JDBC 快速入门

JDBC 快速入门 搭建步骤代码实现数据库java 代码 搭建步骤 准备数据库官网下载数据库连接驱动jar 包。https://downloads.mysql.com/archives/c-j/创建 java 项目&#xff0c;在项目下创建 lib 文件夹&#xff0c;将下载的驱动 jar 包复制到文件夹里选中 lib 文件夹右键 ->…

通信工程学习:什么是ICP网络内容服务商

ICP&#xff1a;网络内容服务商 ICP&#xff0c;全称Internet Content Provider&#xff0c;即网络内容服务商&#xff0c;是指那些通过互联网向用户提供各种类型内容服务的组织或个人。ICP在数字化时代扮演着至关重要的角色&#xff0c;它们不仅是信息的传播者&#xff0c;更是…

微服务获取用户信息和OpenFeign传递用户

问题一&#xff1a; 网关已经完成登录校验并获取登录用户身份信息。但是当网关将请求转发到微服务时&#xff0c;微服务又该如何获取用户身份呢&#xff1f; 由于网关发送请求到微服务依然采用的是Http请求&#xff0c;因此我们可以将用户信息以请求头的方式传递到下游微服务…

机器人技术基础(1-3章坐标变换)

位置矢量的意思是B坐标系的原点O相对于A坐标系的平移变换后的矩阵&#xff1a; 齐次坐标最后一个数表示缩放倍数&#xff1a; 左边的是T形变换矩阵&#xff0c;右边的是需要被变换的矩阵&#xff1a;T形变换矩阵的左上角表示旋转&#xff0c;右上角表示平移&#xff0c;左下角最…

使用 NVIDIA H100 上的 Azure 机密计算释放隐私保护 AI 的潜力

通过 NVIDIA H100 上的 Azure 机密计算释放隐私保护 AI 的潜力 文章目录 前言一、机密计算二、使用 NVIDIA H100 Tensor Core GPU 的 Azure 机密计算1. 安全功能2. 可扩展性和可编程性三、场景1. 模型机密性2. 推理/提示机密性3. 使用私有数据进行微调4. 多方培训结论前言 这是…

71.【C语言】动态内存管理(重点)(4)

本文为数据结构打下基础 备注:数据结构需要掌握指针,结构体和动态内存管理 目录 6.常见的动态内存的错误 1.对空指针解引用 2.对动态空间的越界访问 3.对非动态内存空间进行free释放 4.使用free只释放开辟的内存空间的一部分 5.对同一块动态内存多次释放 6.动态开辟的…

多线程编程-定时器

定时器相当于一个“闹钟”&#xff0c;在日常生活中&#xff0c;我们需要闹钟的辅佐&#xff0c;在代码中&#xff0c;也经常需要“闹钟”机制&#xff08;网络通信中经常需设定一个超时时间&#xff09;。 一.定时器的使用 在Java标准库中&#xff0c;也停供了定时器的实现。…

华为OD机试 - 约瑟夫问题(Python/JS/C/C++ 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

日语发音

这里写目录标题 一个视频教你搞懂日语音调&#xff01;【日语入门课】小白入门轻松学&#xff01;最全的日语零基础教程合集&#xff01;唱儿歌学日语&#xff5e;&#xff08;已完结&#xff09; 一个视频教你搞懂日语音调&#xff01; 中文 阴平&#xff08;第一声&#xff…

【d61】【Java】【力扣】【递归】3304. 找出第 K 个字符 I

思路 递归考虑&#xff1a;就像正常一样想出来思路&#xff0c;然后递归调用的地方&#xff0c;当作一个已经确定的量&#xff08;可直接说一个值&#xff0c;这样就不会一直向下层想&#xff09; 注意绝对不要在递归调用的地方一直往下层想&#xff0c;绝对不要&#xff0c;…

C++面试速通宝典——7

150. 数据库连接池的作用 数据库连接池的作用包括以下几个方面&#xff1a; 资源重用&#xff1a;连接池允许多个客户端共享有限的数据库连接&#xff0c;减少频繁创建和销毁连接的开销&#xff0c;从而提高资源的利用率。 统一的连接管理&#xff1a;连接池集中管理数据库连…

传感器模块编程实践(一)AS608指纹模块简介及驱动源码

文章目录 一.概要二.AS608模块主要技术指标三.AS608模块接线说明四.AS608模块通讯协议介绍五.AS608模块指纹录入与刷指纹流程六.STM32单片机与AS608模块指纹录入与刷指纹实验1.硬件准备2.软件工程3.软件主要代码4.实验效果 七.CubeMX工程源代码下载八.小结 一.概要 AS608 指纹…

打印机驱动安装教程-共享打印机修复工具-打印机扫描教程

金舟打印机驱动修复软件是驱动下载软件&#xff0c;无法解决打印机报错、打印异常、打印机无法连接等问题。 Part 1&#xff1a;打印机驱动安装教程 第一步&#xff1a;确定电脑上的打印机服务已启动 1.1右击桌面的“此电脑”然后点击“管理”。 1.2点击左侧任务栏中的“服务…