前言
现在 Node.js 的生态越来越成熟, 有好多公司直接使用 Node 构建其后端应用, 放在线上跑 TypeScript 是微软的编程语言, 近年来受到的关注也是越来越多
作为一个常年写后端接口的人, 便想: 能不能利用这两者, 来给自己的工作流, 带来一点不一样的感觉 (由于这不是写客户端 JS, 所以我们并不需要 webpack 等工具)
步骤
初始化项目
假设项目目录是 project
- cd project
- mkdir src && touch README.md
- cd src
- npm init
- tsc --init
根据惯例, 弄一个主入口 main (注: 这里没有使用 index.js 这种设定 )
touch main.ts
初始化完成的项目是这样的:
- project/
- README.md
- src/
- package.json
- tsconfig.json
- main.ts
安装必备的包
目前暂时只想到了如下的这些包:
- npm install --save lodash @types/lodash
- npm install --save @types/node
- npm install --save-dev typescript
之后项目变成这样子:
- project/
- README.md
- src/
- package.json
- tsconfig.json
- main.ts
- node_modules/
配置 tsconfig.json
这一步最为重要官网有一节专门讲这个: http://www.typescriptlang.org/docs/handbook/tsconfig-json.html 要看懂还是需要花点时间的
总而言之, 需要告诉 tsc 如下几件事情:
项目的根目录在哪? (以 tsconfig.json 所在的目录为根目录, 即项目根目录 )
输入在哪? (即: 项目的哪些 ts 文件是需要关心的, 标准库 / 第三方库去哪里找)
输出在哪?(由于不是前端项目, 所以我们只需要每一个 ts 输出对应的 js 文件即可)
这里是一个示例配置, 有详细的注释说明, 初始化 ts 项目时, 可以直接拷贝之, 以节约时间成本
- {
- // tsconfig 所在的根目录, 则是一个 project
- "compilerOptions": {
- "module": "commonjs", // 模块系统
- "target": "es2015", // 生成目标, 一般选择 ES6, 因为不是客户端环境, 没必要还编译成 ES5
- // 一组严苛的编译选项
- "noImplicitAny": false,
- "strictNullChecks": true,
- "strict": true,
- "alwaysStrict": true,
- "sourceMap": false,
- "noImplicitReturns": true,
- "noImplicitThis": true,
- "pretty": true,
- "listFiles": true, // 包含了哪些库, 这个必要的时候还是很有用的
- "listEmittedFiles": true,
- "lib": [ // 要那些 lib, 按需选择即可
- "es2016"
- ],
- // "noUnusedLocals": true,
- // "noUnusedParameters": true,
- // "noFallthroughCasesInSwitch": true,
- // 指定库的搜索路径, 这个比较有用, 一般会指定 @types, 还可以按需添加
- "typeRoots": [
- "./node_modules/@types"
- ]
- // 库搜索路径下, 仅使用哪些库, 一般没啥用
- // "types": [
- // ]
- },
- // file include 会算出一个交集, 指明哪些是项目的 ts 文件
- "include": [
- "./**/*"
- ],
- // 排除项目下面不符合要求的文件, 这个按需设定即可, 可以放心排除乱七八糟的文件
- "exclude": [
- "node_modules",
- "**/*.spec.ts",
- "*.js"
- ]
- }
设计项目的目录结构 为了模拟真实的场景, 我们的 main.ts 有如下内容:
- function main() {
- }
- main();
写一个 utils.ts, 放入 src/core/utils.ts 中
- import * as path from 'path'; // 测试能否正常使用 Node 的内置模块
- /**
- * 一个正常的 class
- *
- * 不得不说, TS 使用起来真是舒服, 各种该有的东西都替你考虑到了
- * 很舒心
- */
- export class NodeModuleTester {
- public static readonly STATIC_VAR = 'STATIC'; // 测试 static 变量
- constructor( // 测试构造方法
- private readonly f1: string,
- private readonly f2: number) {
- }
- public static testPath() { // 测试静态方法
- const curdir = './';
- console.log(path.resolve(curdir));
- }
- }
由于需要使用对应的 class, 所以 main.ts 内容变成了这样:
- import {NodeModuleTester} from './core/utils';
- /**
- * main 入口
- *
- * 测试!
- */
- function main() {
- const tester = new NodeModuleTester("s1", 1);
- console.log(NodeModuleTester.STATIC_VAR);
- console.log(NodeModuleTester.testPath());
- }
- main();
运行 由于 Node 是不认识 ts 的, 我们的 ts 代码需要先转译成 js 代码
不过别担心, 我们使用的是微软的产品, 一切都不是问题 (意思就是: 微软设计的东西, 既有品味, 又是异常简单好用, 历来如此)
我们只需要
cd src/ && tsc && node main.js
即可, 简直不要太简单如果还嫌麻烦, 我们可以写到 npm script 中去, 如下:
- {
- "name": "src",
- "version": "1.0.0",
- "description": "","main":"index.js","scripts": {"test":"echo \"Error: no test specified\" && exit 1","runmain":"./node_modules/.bin/tsc && node main.js" // 就是这个脚本!
- },
- "author": "","license":"ISC","devDependencies": {"@types/node":"^9.4.6","typescript":"^2.7.2"
- }
- }
然后我们只需要
cd src/ && npm run runmain
即可, 更加地简单
我的感悟
TypeScript 代码, 既美观又优雅, 加上微软强大的工程能力 (造工具的能力),Node.js + TypeScript 几乎是一对完美的组合
附
有人可能比较担忧有的库没有对应 d.ts 其实这完全不用担心, 常用的库要么自带 d.ts (侧面验证了 TS 已经越来越被大家接受), 要么社区已经有维护好的 d.ts (@types 下面的库), 实在没办法, 自己写 d.ts 也不过是分分钟的事情, 并没有什么难度
来源: https://juejin.im/post/5a8fff275188257a5a4cc7d9