您的位置:首页 > 文旅 > 美景 > 怎么设置域名_少儿编程机构_厉害的seo顾问_在线识别图片百度识图

怎么设置域名_少儿编程机构_厉害的seo顾问_在线识别图片百度识图

2024/10/10 0:12:41 来源:https://blog.csdn.net/SaRAku/article/details/142443526  浏览:    关键词:怎么设置域名_少儿编程机构_厉害的seo顾问_在线识别图片百度识图
怎么设置域名_少儿编程机构_厉害的seo顾问_在线识别图片百度识图

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: '',});
});

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com