美文网首页
如何将 ts 集成到 node 项目中

如何将 ts 集成到 node 项目中

作者: 一蓑烟雨任平生_cui | 来源:发表于2022-07-25 14:54 被阅读0次

    为什么使用 TypeScript?

    TypeScript 为 JavaScript 提供了可选的静态类型。静态类型的主要好处是在构建时检查和发现类型错误,所以代码部署到生产环境后运行更稳定。

    环境准备

    Node 版本 >= 16

    初始化项目

    mkdir node-ts
    cd node-ts
    npm init -y
    

    安装 typescript

    npm i typescript -D
    

    初始化 ts 配置文件

    npx tsc --init
    

    安装 @tsconfig/node16

    npm i @tsconfig/node16 -D
    

    @tsconfig/node16 为 TypeScript 团队为 Node.js v16 提供的基本配置。

    tsconfig.json 中增加一下配置

    {
      "extends": "@tsconfig/node16/tsconfig.json",
      "include": ["src"],
      "exclude": ["node_modules"]
    }
    

    编写 ts 文件

    src 下新建 index.ts 文件

    const bar = 'bar'
    
    console.log(bar)
    

    通过 npx tsc 运行。js 文件是编译出来了,但是控制台报出错误:

    TS2584: Cannot find name 'console'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'.
    

    发生此错误是因为在 tsconfig.json 配置文件和 @tsconfig/node16 的配置中 compilerOptions 没有设置 lib 选项。该选项包含对象的类型定义和其他特定于浏览器的 API。将 "dom", "ESNext" 添加到 lib 中解决。但这不是 Node.js 项目的正确解决方案。正确的方式是安装 Node API 的类型定义,使 TypeScript 编译器可以理解和验证所有内置的 Node.js API。

    安装 @types/node

    npm i @types/node -D
    

    安装完成后再次运行 npx tsc 错误消失。

    如果要更改 js 文件的输出位置,可以在文件中 tsconfig.json 中指定 outDir 选项,编译后 js 文件将输出到 dist 目录下。

    创建一个 http 服务感受下 ts 的类型检查和提示:

    // index.ts
    import http from 'http'
    
    const server = http.createServer((req, res) => {
      res.statusCode = 200
      res.setHeader('Content-Type', 'text/plain')
      res.end('hello ts node!')
    })
    
    server.listen(3000, () => {
      console.log('runing...')
    })
    

    因为 node 运行时不能直接 ts 文件,所以需要将 ts 文件编译成 js 执行。运行 npx tsc 然后 node dist/index.js,就可以访问 http://localhost:3000/了。

    这种方式每次改动代码都要编译,然后执行 js 文件。

    可以通过 tsc -w 监听文件的变化,然后使用nodemon工具监听js文件的变化。有点繁琐。

    使用 ts-node 直接执行 ts 文件

    通过 ts-node CLI 在直接执行 ts 文件。安装 ts-node

    npm i ts-node -D
    

    执行 npx ts-node src/index.ts,完全可行。

    ts-node 作为 ts 源码 和 node 运行时之间的中间者。在执行生成的 js 代码之前转译源代码。这种执行速度更快。

    另外 ts-node 启用的功能是将现代 esm 语法转换为 CommonJS 语法。这意味着在使用时 ts-node,您可以在代码中通 import 而不是 require 使用 node 模块。

    package.json 中新增脚本:

    {
      "scripts": {
        "dev": "ts-node src/index.ts"
      }
    }
    

    使用 tsc-node-dev 可以监听文件的变化,当文件内容变化后重新编译并运行。

    {
      "scripts": {
        "dev": "ts-node-dev src/index.ts"
      }
    }
    

    ts 与第三方 npm 集成

    当使用 npm 上的 node 模块时,可能需要额外的配置才能编译项目。

    因为我们遇到的大多数模块都是用 js 编写的,因此 ts 无法确定方法的类型。模块中的所有内容都隐式为 any。

    以 express 为例:

    安装 express

    npm i express
    
    import express from 'express'
    
    const app = express()
    
    app.get('/', function (req, res) {
      res.send('Hello World')
    })
    
    app.listen(3000)
    

    会抛出错误: 无法找到模块“express”的声明文件,而且由于 tsconfig.json 的 strict 选项为 true,因此也启用了 noImplicitAny 编译器选项。使得 ts 在无法确定值的类型时会报错而不是进行推断类型。 所以 req 和 res 报错。

    可以为模块提供类型声明文件来修复此错误。DefinitiveTyped GitHub 上提供了许多流行的 npm 包的类型定义。通过 @types 作用域安装包的类型定义。安装 express 的类型定义文件:

    npm install @types/express -D
    

    再次运行 npx ts-node src/index.ts 就成功了。

    这种方式无法实时监听文件的变化,可以使用 nodemon,通过 tsc -w 监听 ts 文件,变化后重新编译成 js,nodemon 监听到 js 变化后重新执行 js。

    使用 ESLint 对 ts 进行检查

    安装 ESLint

    npm i eslint -D
    

    要 eslint 对 ts 的检验,需要 eslint 的 ts 插件,@typescript-eslint/parser @typescript-eslint/eslint-plugin

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

    根目录创建 .eslintrc.js 配置文件,配置内容为:

    module.exports = {
      env: {
        node: true,
        es2021: true
      },
      extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
      parser: '@typescript-eslint/parser',
      parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module'
      },
      plugins: ['@typescript-eslint']
    }
    

    package.json 中添加 lint 脚本:

    {
      "scripts": {
        "lint": "eslint . --fix"
      }
    }
    

    代码中新增:

    let bar = 'bar'
    
    console.log(bar)
    

    执行 npm run lint,let 改成 const,eslint 生效。

    为了防止 ESLint dist 下的 js 文件检查,创建 .eslintignore 文件,并将 dist 添加进去。因为 node_modules 文件夹中的所有内容以及以点字符开头的文件或文件夹(eslint 配置文件除外)都会被自动忽略,因此无需在 .eslintignore 文件中设置。

    部署到生产环境

    虽然 ts-node 在生产环境中使用也是是安全的。但为了减少服务器的启动时间以及减少额外的内存使用,最好预先编译源文件。将编译后的 js 部署到生产环境。

    相关文章

      网友评论

          本文标题:如何将 ts 集成到 node 项目中

          本文链接:https://www.haomeiwen.com/subject/xkfpirtx.html