教程 - 使用 TypeScript 构建 Node.js 应用

9,981 阅读7分钟
原文链接: www.zcfy.cc

使用 TypeScript 开发 Node.js

3 个月前 2017 年 6 月 20 日

这篇文章将会告诉您,怎样编译、构建、测试以及调试使用 TypeScript 开发的 Node.js 应用。为此,我准备了一个示例工程, 您稍后可以查看源码。


管理大型 JavaScript 工程是很具有挑战性的,因为需要保证工程各个部分密切结合。可以采用单元测试、类型(JavaScript并不真正具备类型), 或者两者配合去解决这个问题。

这就是 TypeScript 的起源。TypeScript 是 JavaScript 类型的超集,最终会编译成纯 JavaScript。

在这篇文章中,您将会了解到:

  • TypeScript 是什么

  • 使用 TypeScript 有什么好处

  • 如何使用它来建立开发工程:

    • 怎样添加代码检查,

    • 怎样写单元测试,

    • 怎样在 TypeScript 里调试应用

本文不会详细的讲解 TypeScript 自身的语法,主要介绍怎样使用它去开发 Node.js 应用程序。如果您想更深一步的了解 TypeScript,建议查阅 TypeScript Gitbook

使用 TypeScript 的好处

我们之前说过,TypeScript 是 JavaScript 的超集。它将给您带来以下几个好处:

  • 可选的静态类型。重点是可选(它让 JavaScript 迁移至 TypeScript 变得很容易);

  • 作为开发者,您可以通过“构建版本”来使用一些尚未被 V8 引擎支持的 ECMAScript 特性;

  • 使用 “接口”(interfaces);

  • 如 IntelliSense 之类强大的工具集。

TypeScript & Node 起步

TypeScript 是 JavaScript 的静态类型检查器,这表示它可以利用不同类型的特征去检查您的代码。例如: String 类型拥有 toLowerCase 方法,但是没有 parseInt 方法。当然,TypeScript 的类型系统也能够通过您自己的定义来自由扩展。

由于 TypeScript 是 JavaScript 的超集,可以通过字面的重命名 .js 文件至 .ts 开始使用它。所以您可以逐步的将 TypeScript 带到自己团队中去。

: TypeScript 不会在运行时做任何事情, 它仅仅在编译的时候工作。您运行的将会是纯 JavaScript.


通过 npm 安装 TypeScript 开始使用它:

`$ npm install -g typescript`

让我们开始写咱们的第一个 TypeScript 文件吧!它将通过参数获取人名,并简单的打个招呼:

// greeter.ts
function greeter(person: string) {  
  return `Hello ${person}!`
}

const name = 'Node Hero'

console.log(greeter(name))

您可能注意到了,函数中有一个 string 类型的声明,它告诉 TypeScript 编译器:greeter 函数期望接收一个 string 类型的参数。

我们尝试一下去编译它!

`tsc greeter.ts`

首先,我们观察一下编译后的输出。如您所看到的那样,编译后的文件并没有太大的变化,只有类型的注释被去掉了:

function greeter(person) {  
    return "Hello " + person + "!";
}
var userName = 'Node Hero';  
console.log(greeter(userName));

当咱们将 userName 变量设置成 Number 类型会怎样?您可能也猜到了,这会引发一个编译错误:

`greeter.ts(10,21): error TS2345: Argument of type '3' is not assignable to parameter of type 'string'.`

教程:使用 TypeScript 开发 Node.js 应用

1. 安装开发环境

在开始使用 TypeScript 开发应用之前,请确保您已经安装了 Node.js 。本文中使用的是 Node.js 8 版本。

我们建议通过 nvm 来安装 Node.js,它是 Node.js 的版本管理器。利用这个实用的工具,您可以同时在系统中安装多个版本的 Node.js,并可以很方便的通过命令行来切换版本。

# install nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash

# install node 8
nvm install 8

# to make node 8 the default
nvm alias default 8

Node.js 8 安装完成后,需要新建一个项目目录,接着使用命令来创建 package.json

`npm init`

2. 建立项目结构

使用 TypeScript,建议采取的方式是把所有的文件都放在 src 目录下。

在教程结尾,我们项目的目录结构看起来会是这样的:

Node.js TypeScript Tutorial - Example Application Project Structure

我们通过添加 App.ts 文件开始 - 接下来即将实施的 web 服务逻辑就是在这个文件,使用了 express 框架。

在这个文件里,我们创建了一个名为 App 的类,用来封装 web 服务。它有一个私有方法:mountRoutes,用来挂载由 web 服务提供的路由。express 实例可以通过 express 属性来访问到。

import * as express from 'express'

class App {  
  public express

  constructor () {
    this.express = express()
    this.mountRoutes()
  }

  private mountRoutes (): void {
    const router = express.Router()
    router.get('/', (req, res) => {
      res.json({
        message: 'Hello World!'
      })
    })
    this.express.use('/', router)
  }
}

export default new App().express

我们还创建了一个 index.ts 文件,web 服务通过它来启动:

import app from './App'

const port = process.env.PORT || 3000

app.listen(port, (err) => {  
  if (err) {
    return console.log(err)
  }

  return console.log(`server is listening on ${port}`)
})

目前为止 - 理论上来说,我们实现了一个功能完备的 web 服务器。不过要让它真正能够工作,还需要把 TypeScript 代码编译至 JavaScript 。

阅读 Node.js project structuring 这篇文章,来进一步了解项目结构方面的知识

3. 配置 TypeScript

您可以通过客户端参数或 tsconfig.json 文件来配置 TypeScript。考虑到可能要在不同的任务中使用相同的设置,我们将通过 tsconfig.json 来配置。

通过配置文件,我们可以告诉 TypeScript 需要构建的版本(在写这篇文章为止,能使用的版本有:ES5,ES6,ES7),期望的模块系统,JavaScript 文件放到哪个目录、以及是否需要生成 source-maps 文件。

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "dist",
    "sourceMap": true
  },
  "files": [
    "./node_modules/@types/mocha/index.d.ts",
    "./node_modules/@types/node/index.d.ts"
  ],
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

建立完 TypeScript 配置文件之后,您就可以通过 tsc 命令来构建应用了。

如果您不想将 TypeScript 安装到全局,可以只把它作为项目的依赖来安装,同时创建一条 npm 命令:"tsc": "tsc".

这能正常的运行,因为 npm 命令会查找 ./node_modules/.bin 文件夹下的二进制文件,并在启动脚本的时候添加到 PATH 环境变量里,然后您可以通过使用 npm run tsc 调用 tsc。您可以使用 npm run tsc -- --all 来查看运行 tsc 时的配置项 (这条命令会列出所有 TypeScript 可用的配置项)。

需要企业级的开发帮助?雇佣来自 RisingStack 的专家!

4. 添加 ESLint

在大多数工程中,您都希望获得语法风格问题的代码检查。TypeScript 也不例外

要在 TypeScript 中使用 ESLint,您需要添加扩展包和 parser,让 ESLint 能明白 TypeScript 语法:typescript-eslint-parser,当安装完成后,还需要为 ESLint 配置 parser:

# .eslintrc.yaml
---
  extends: airbnb-base
  env:
    node: true
    mocha: true
    es6: true
  parser: typescript-eslint-parser
  parserOptions:
    sourceType: module
    ecmaFeatures: 
      modules: true

运行 eslint src --ext ts 命令,将会看到同样的错误和警告:

Node.js TypeScript 教程 - 错误日志

5. 测试应用

测试基于 TypeScript 的应用,基本上跟测试其它的 Node.js 应用差不多。

唯一有点不同的地方是,必须在运行测试之前先编译应用。实现起来也是非常简单的,您可以通过 tsc && mocha dist/**/*.spec.js 完成。

获取更多测试用例, 查看 Node.js 测试教程.

6. 建立 Docker 镜像

当您完成了应用开发,很有可能您想将它部署至 Docker 镜像。只需以下几个额外的步骤:

  • 构建应用 (编译 TypeScript 至 JavaScript)
  • 通过构建源码启动 Node.js 应用。

FROM risingstack/alpine:3.4-v6.9.4-4.2.0

ENV PORT 3001

EXPOSE 3001

COPY package.json package.json  
RUN npm install

COPY . .  
RUN npm run build

CMD ["node", "dist/"]

7. 使用 source-maps 调试

由于启用了 source-maps,我们能使用它来调试咱们的应用。为了查找问题,使用下面这种方式启动 Node.js 进程:

`node --inspect dist/`

将会看到如下所示的输出:

To start debugging, open the following URL in Chrome:  
    chrome-devtools://devtools/remote/serve_file/@60cd6e859b9f557d2312f5bf532f6aec5f284980/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/23cd0c34-3281-49d9-81c8-8bc3e0bc353a
server is listening on 3000

为了真正开启测试进程,打开 Chrome 浏览器,并跳转至 chrome://inspect。里面应该会有一个远程目标,点击 inspect 可以启用 Chrome 调试工具。

之后,您会马上看到源代码,然后可以在 TypeScript 源码上添加加断点、检测。

Node.js TypeScript 教程 - 在 Chrome 中调试

source-map 功能仅可以在 Node,js 8 或更高的版本下工作。

完整的 Node.js TypeScript 教程

您能在 GitHub 上获取到完整的教程和源码:Node.js TypeScript starter application

通过提 issues,或在下方评论以让我们知道您希望得到的改变!

Gergely Nemeth

Node.js 和微服务, @Oneshotbudapest @nodebp @jsconfbp 的组织者

On-premises Node.js and microservice monitoring

高级 Node.js 教程 JavaScript 教程

阅读更多:

快人一步获取我们的文章

关注 @RisingStack

启用 JavaScript 以查看评论 评论功能由 Disqus 提供