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.mfbz.cn/a/887574.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《深度学习》OpenCV 图像拼接 原理、参数解析、案例实现

目录 一、图像拼接 1、直接看案例 图1与图2展示&#xff1a; 合并完结果&#xff1a; 2、什么是图像拼接 3、图像拼接步骤 1&#xff09;加载图像 2&#xff09;特征点检测与描述 3&#xff09;特征点匹配 4&#xff09;图像配准 5&#xff09;图像变换和拼接 6&am…

实验3 选择结构

1、计算分段函数的值 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <math.h> int main() {double x,y0;scanf("%lf",&x);if(x<0){printf("error!\n");return 0;}if(0<x&&x<1){ylog10(x);}else if(1<…

缓存数据减轻服务器压力

问题:不是所有的数据都需要请求后端的 不是所有的数据都需要请求后端的,有些数据是重复的、可以复用的解决方案:缓存 实现思路:每一个分类为一个key,一个可以下面可以有很多菜品 前端是按照分类查询的,所以我们需要通过分类来缓存缓存代码 /*** 根据分类id查询菜品** @pa…

Java | Leetcode Java题解之第459题重复的子字符串

题目&#xff1a; 题解&#xff1a; class Solution {public boolean repeatedSubstringPattern(String s) {return kmp(s s, s);}public boolean kmp(String query, String pattern) {int n query.length();int m pattern.length();int[] fail new int[m];Arrays.fill(fa…

54.二叉树的最大深度

迭代 class Solution {public int maxDepth(TreeNode root) {if(rootnull){return 0;}int de0;Queue<TreeNode> qunew LinkedList<>();TreeNode tn;int le;qu.offer(root);while(!qu.isEmpty()){lequ.size();while(le>0){tnqu.poll();if(tn.left!null){qu.offe…

学会这几个简单的bat代码,轻松在朋友面前装一波13[通俗易懂]

大家好&#xff0c;又见面了&#xff0c;我是你们的朋友全栈君。 这个标题是干什么用的? 最近看晚上某些人耍cmd耍的十分开心&#xff0c;还自称为“黑客”&#xff0c;着实比较搞笑.他们那些花里胡哨的东西在外行看来十分nb,但只要略懂一些&#xff0c;就会发现他们的那些十…

论文阅读笔记-A Comparative Study on Transformer vs RNN in Speech Applications

前言 介绍 序列到序列模型已广泛用于端到端语音处理中,例如自动语音识别(ASR),语音翻译(ST)和文本到语音(TTS)。本文着重介绍把Transformer应用在语音领域上并与RNN进行对比。与传统的基于RNN的模型相比,将Transformer应用于语音的主要困难之一是,它需要更复杂的配…

JavaScript 数组方法

数组(array)是按次序排列的一组值。每个值的位置都有编号(从0开始)&#xff0c;整个数组用方括号表示。两端的方括号是数组的标志。 var a["a","b","c"]; 除了在定义时赋值&#xff0c;数组也可以先定义后赋值。 var arr[];arr[1]"a"…

Qt_绘图

目录 1、绘图核心类 2、QPainter类的使用 2.1 绘制线段 2.2 绘制矩形 2.3 绘制圆形 2.4 绘制文本 3、QPen类的使用 3.1 使用画笔 4、QBrush类的使用 4.1 使用画刷 5、绘制图片 5.1 测试QPixmap 5.1.1 图片移动 5.1.2 图标缩小 5.1.3 旋转图片 5.1.4 将…

windows10或11家庭版实现远程桌面连接控制

远程协助是一种Windows工具&#xff0c;允许控制者使用鼠标和键盘远程控制接受者的计算机&#xff0c;从某种程度上讲&#xff0c;这也是Win10家庭版无法远程桌面的一个有效替代方案。 步骤1. 在使用Windows远程协助之前&#xff0c;您需要先更改某些设置&#xff0c;右键单击…

封装el-upload组件,用于上传图片和视频

使用环境 vue3element-ui plus 需要根据后端返回结构修改的函数&#xff1a;onPreview onRemove onSuccess 组件使用 基本使用 源代码&#xff1a; <script setup> import AutoUploadFile from /components/auto-upload-file/index.vue function change(urls){console.…

金智维KRPA之Excel自动化

Excel自动化操作概述 Excel自动化主要用于帮助各种类型的企业用户实现Excel数据处理自动化&#xff0c;Excel自动化是可以从单元格、列、行或范围中读取数据&#xff0c;向其他电子表格或工作簿写入数据等活动。 通过相关命令&#xff0c;还可以对数据进行排序、进行格式…

javaScript数组(16个案例+代码+效果图)

目录 1.数组的概念 2.创建数组 1.通过数组字面量创建数组 1.代码 2.效果 2.通过new Array()创建数组 1.代码 2.效果 3.数组的基本操作 1.获取数组的长度 案例:获取数组的长度 1.代码 2.效果 2.修改数组的长度 1.代码 2.效果 4.访问数组 案例:访问数组 1.代码 2.效果 5.遍历数组…

【EXCEL数据处理】000013 案例 EXCEL筛选与高级筛选。

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【EXCEL数据处理】000013 案例 EXCEL筛选与高级筛选。使用的软件&#…

一个真实可用的登录界面!

需要工具&#xff1a; MySQL数据库、vscode上的php插件PHP Server等 项目结构&#xff1a; login | --backend | --database.sql |--login.php |--welcome.php |--index.html |--script.js |--style.css 项目开展 index.html&#xff1a; 首先需要一个静态网页&#x…

【HTML5】html5开篇基础(4)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

React 解释常见的 hooks: useState / useRef / useContext / useReducer

前言 如果对 re-render 概念还不清楚&#xff0c;建议先看 React & 理解 re-render 的作用、概念&#xff0c;并提供详细的例子解释 再回头看本文。 如果对 React 基础语法还不熟练&#xff0c;建议先看 React & JSX 日常用法与基本原则 再回头看本文。 useState useS…

虚拟机 VMware 安装 macOS

macOS 界面 MAC OS IOS下载&#xff1a; amacOS Monterey by Techrechard.comwmacOS Monterey by Techrechard.com 下载&#xff1a;Unlocker-v2.0.1-x64 Mac OS X 虚拟机中更改屏幕分辨率 终端输入命令&#xff1a; sudo defaults write /Library/Preferences/com.apple.w…

[图形学]在半球面上均匀采样和cos加权采样

一、简介 本文介绍了如何在半球表面上进行半球面均匀采样、半球面cos加权采样采样。 给出了相关公式推导和python代码实现。 二、在半球上采样 0.预备知识 1).球面坐标系与笛卡尔坐标系 在半球面上采样时&#xff0c;常使用球面坐标系。先采样球面坐标系下的坐标参数 ( θ…

如何使用 Python 读取数据量庞大的 excel 文件

使用 pandas.read_excel 读取大文件时&#xff0c;的确会遇到性能瓶颈&#xff0c;特别是对于10万行20列这种规模的 .xlsx 文件&#xff0c;常规的 pandas 方法可能会比较慢。 要提高读取速度&#xff0c;关键是找到更高效的方式处理 Excel 文件&#xff0c;特别是在 Python 的…