使用 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
目录下。
在教程结尾,我们项目的目录结构看起来会是这样的:
我们通过添加 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
命令,将会看到同样的错误和警告:
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 源码上添加加断点、检测。
source-map 功能仅可以在 Node,js 8 或更高的版本下工作。
完整的 Node.js TypeScript 教程
您能在 GitHub 上获取到完整的教程和源码:Node.js TypeScript starter application
通过提 issues,或在下方评论以让我们知道您希望得到的改变!
Gergely Nemeth
Node.js 和微服务, @Oneshotbudapest @nodebp @jsconfbp 的组织者
阅读更多:
- Survey: Node.js Developers Struggle with Debugging & Downtimes
- Node.js Performance Monitoring with Prometheus
快人一步获取我们的文章
启用 JavaScript 以查看评论 评论功能由 Disqus 提供