本文详细记录了在Node.js项目中引入TypeScript进行开发的完整环境搭建过程。从基础环境准备、项目目录结构建立,到tsconfig.json核心配置项(如module、target、rootDir)的深入解析,涵盖了编译错误处理、类型声明文件(@types/node)的安装以及模块导入方法。此外,文章还介绍了通过npm scripts、supervisor和Gulp实现代码自动编译与服务器自动重启的高效开发工作流,旨在帮助开发者快速上手TS+Node.js的开发模式。
TypeScript开发Node.js环境搭建概述
最近在探索TypeScript的学习路径时,萌生了使用TS来构建Node.js项目的想法。经过网络检索发现,已有不少开发者进行了相关实践。本文旨在梳理并记录本人搭建该开发环境的具体步骤。
采用TypeScript进行开发的显著优势包括:
- 具备更为严格的类型检查与语法校验机制。
- 对ES6、ES2015以及部分ES7特性提供了良好的支持。
- 编译生成的JavaScript代码结构清晰,且兼容多种代码规范。
- 更多优势请参阅官方文档说明。
开发环境准备与项目初始化
开发前需完成以下准备工作:
- Node.js版本建议为v6.9.1或更高版本,旧版本尚未进行测试验证。
- 安装TypeScript编译器tsc,通过npm全局安装:npm install -g typescript,当前版本为v2.0.10。
- 推荐使用VS Code作为代码编辑器。
- 命令行终端使用Windows系统的cmd。
接下来开始构建Node.js项目基础结构:
在项目指定目录下,通过执行npm init命令初始化项目目录。
此处展示一种个人偏好的项目目录组织结构:
testTS
|---build //编译后的js文件目录
|---src //ts文件目录
|---static //客户端静态文件
| |---scripts
| | |---main.js
| |----styles
| | |---style.css
| |----assets
|---views //html文件目录
| |---index.html
|---package.json
|---tsconfig.jsontsconfig.json配置详解与路径处理
随后需编辑tsconfig.json配置文件。
在上述目录结构中,tsconfig.json文件用于设定TypeScript的编译选项。
获取该配置文件的方法是在项目根目录下运行tsc --init命令,系统将自动生成一份.tsconfig.json文件。
接下来编写必要的配置参数。
默认情况下,tsc会依据默认配置编译目录下的所有.ts文件。通过编写tsconfig.json,可以自定义tsc的编译行为,从而达成预期的编译效果:
{
"compilerOptions": {
"module": "commonjs", //指定生成哪个模块系统代码
"target": "es6", //目标代码类型
"noImplicitAny": false, //在表达式和声明上有隐含的'any'类型时报错。
"sourceMap": false, //用于debug
"rootDir":"./src", //仅用来控制输出的目录结构--outDir。
"outDir":"./build", //重定向输出目录。
"watch":true //在监视模式下运行编译器。会监视输出文件,在它们改变时重新编译。
},
"include":[
"./src/**/*"
],
"exclude":[
"views",
"static"
]
}
配置文件中需注意的关键点如下:
"compilerOptions"用于定义编译选项,具体参数详情可参考:
中文文档 英文文档
"module"参数用于指定编译后JS代码所采用的模块规范。鉴于开发的是Node.js项目,此处选择commonjs。(若感兴趣,可尝试所有module的可能取值,观察编译后JS文件的差异,你会发现生成的代码非常整洁。)
"target"参数用于指定编译后JS代码遵循的规范标准,可选es3、es5、es6等。为了对比TS 2.0代码与ES6代码的差异,此处设置为"es6"。
"rootDir"是一个需要特别注意的配置项,它指示编译器该目录下的文件需参与编译。若设置了此选项,却在外部(如根目录)放置了.ts文件,将会发生什么情况?tsc会报出如下错误:
错误代码如下:
"error TS6059: File 'D:/workplace/nodeWP/testTS/index.ts' is not under 'rootDir' 'D:/workplace/nodeWP/testTS/src'. 'rootDir' is expected to contain all source files."
同时,build目录下的输出目录结构也会随之改变:

这显然并非我们期望的结果。
解决方案是引入include和exclude属性。根据文档说明,"include"和"exclude"属性用于指定文件glob匹配模式列表,明确需要包含的文件目录或文件,以及需要排除的文件或目录(也可使用"files"配置项,但需逐个录入文件;"files"属性明确指定的文件始终会被包含,无论"exclude"如何设置)。详见官方文档说明。
因此,在"include"数组中添加"./src/**/*",即可指定仅编译./src下的所有文件,其他目录将被排除。
"outDir"指向编译后JS代码的输出位置。文档中还提供"outFile"选项,可将所有ts文件按特定顺序规则打包成单一文件,具体可参考文档。此处优先使用outDir。
代码编译测试与类型声明文件处理
接下来进行实际测试。
完成两个配置文件的编写后,即可开始撰写代码并执行编译。我们进行如下试验:
在./src/server.ts文件中,编写一段简单代码:
interface ICache{
useCache:boolean;
[propName:string]:any;
}
const cache:ICache = {useCache:true};随后在终端中输入以下命令:
D:\workplace\nodeWP\testTS>tsc
编译完成后,server.js文件将生成至build目录中:
//server.js
const cache = { useCache: true };关于使用.d.ts声明文件。
既然要开发一个完整项目,显然不会仅包含上述代码。项目中必然涉及内建模块和第三方模块。然而,直接在.ts文件中导入模块是行不通的。例如:

这是由于TypeScript自身的机制所致,需要一份xx.d.ts声明文件来说明模块对外公开的方法和属性的类型及内容。虽然略显繁琐,但官方及社区已提供解决方案来解决此问题。
在TypeScript 2.0及以上版本中,获取类型声明文件只需使用npm。在项目目录下执行安装命令:
npm install --save-dev @types/node
即可获取有关Node.js v6.x的API类型说明文件。之后,便可顺利导入所需模块:
import * as http from 'http';完成上述步骤后,不仅可以正常使用http模块中的方法,还能在VS Code中获得相应的代码提示。
对于内建模块,安装@types/node模块即可整体解决模块的声明文件问题。那么,面对海量的第三方模块,该如何处理呢?官方和社区提供了查找和安装的渠道:
- typings
- DefinitelyTyped
- TypeSearch
自动化编译与服务器重启工作流优化
实现自动编译与自动重启服务。
解决了声明文件问题后,我们已能使用TypeScript进行简单的Node.js项目开发。然而,每次编写或修改代码后都需要手动编译并启动服务,虽非大错,却相当繁琐。为提高效率,我们应优化这一流程。
首先,使.ts文件能够被自动编译。这在上文的tsconfig.json文件中已设置好,即"watch":true。此时在命令行执行tsc命令后,编译器将实时监控目录中.ts文件的变化,并自动执行编译。
至于Node服务器的自动重启,我们可以使用supervisor模块解决,或采用任何具备类似功能的解决方案。
全局安装supervisor模块:npm install -g supervisor,随后即可在终端中使用supervisor ./build/server.js启动服务器。当服务器端代码发生改变时,服务器将自动重启。
简化启动服务的命令。
由于上述两个命令在启动时可能需要附加一些参数,每次手动输入颇为麻烦。
我们可以利用npm script来解决此问题。在package.json文件的"scripts"中,进行如下设置:
{
"scripts":{
"dev": "supervisor -w build ./build/server.js",
"build": "tsc",
}
}执行npm run dev后,若./build目录中的.js文件发生改变,服务器将自动重启。
执行npm run build时,则仅负责编译ts文件并监控ts文件的变更。
通过具体示例进行试验。
import * as http from 'http';
//====================
const server = http.createServer(function(request:http.IncomingMessage,response:http.ServerResponse):void{
console.log("create a server...");
response.writeHead(200,{'Content-Type':'text/plain'});
response.write('Hello world,we use typescript to develop.');
response.end();
});
server.listen(3000,function(){
console.log("Server listening on port 3000");
console.log("test...");
});
基于Gulp的高效开发流程整合
补充:一个命令实现tsc编译和重启服务器。
2017.5.3更新:
感谢大家对本文的支持。有朋友(@Ajaxyz)提出,是否存在将ts编译监视和重启服务器合并为一个命令的方法?
此处提供一种较为简易的方法,即使用gulp来管理这两个流程。(关于如何使用gulp工作,请参考Gulp API)。
1. 使用gulp的watch()来监控ts文件的变化并重启服务器。
这种方式需要使用gulp和gulp-typescript插件(需安装)。
需要注意的是:gulp-typescript可能需要在项目目录中安装typescript,因此可以在项目目录中运行命令行:
npm install typescript准备好gulp和插件之后,需要书写一份gulpfile.js作为gulp项目需要执行的任务文件,例子如下:
//gulpfile.js
let gulp = require('gulp');
let ts = require('gulp-typescript');
let tsp = ts.createProject('tsconfig.json'); //使用tsconfig.json文件配置tsc
let exec = require('child_process').exec;
let child;
//目录常量
const PATHS = {
scripts:['./src/**/*.ts'],
output:'./build',
};
//编译ts文件
gulp.task('build-ts',['restart'],function(){
return gulp.src(PATHS.scripts)
.pipe(tsp())
.pipe(gulp.dest(PATHS.output));
});
//监视ts文件变化
gulp.task('watch-ts',['build-ts'],function(){
gulp.watch(PATHS.scripts,['build-ts']);
});
//自动重启服务器
gulp.task('restart',function(){
child = exec('supervisor -w build ./build/server.js',(error,stdout,stderr)=>{
console.log(`stdout: ${stdout}`);
console.log(`stderr: ${stderr}`);
if (error !== null) {
console.log(`exec error: ${error}`);
}
});
});
//开发任务
gulp.task('dev',['build-ts','restart','watch-ts']);
这样,在开发时,直接在项目目录运行gulp dev,就可以启动编译和服务器了。此后,gulp会监视ts文件的改动,然后编译ts文件并重启服务器。刷新页面,就可以看到新结果已经输出在浏览器页面中了。
还有一点需要留意的是,由于gulp负责监视ts文件的变化,因此请在tsconfig.json将"watch"设置为false或者删掉这个属性。
2. 使用tsconfig.json监控ts文件变化并重启服务器
用这种方式,首先打开tsconfig.json对ts文件的监视,然后修改gulpfile.js文件,如下:
//...requier部分同上面例子,这里省略
let tsChild, //监视ts文件修改子进程
serverChild; //重启服务器子进程
//编译ts文件
gulp.task('build-ts',function(){
tsChild = exec('tsc',(error,stdout,stderr)=>{
console.log(`tsc====>stdout: ${stdout}`);
console.log(`tsc====>stderr: ${stderr}`);
if (error !== null) {
console.log(`exec error: ${error}`);
}
});
});
//自动重启服务器
gulp.task('restart',function(){
serverChild = exec('supervisor -w build ./build/server.js',(error,stdout,stderr)=>{
console.log(`restart=====>stdout: ${stdout}`);
console.log(`restart=====>stderr: ${stderr}`);
if (error !== null) {
console.log(`exec error: ${error}`);
}
});
});
//开发任务
gulp.task('dev2',['build-ts','restart']);
运行gulp dev2,效果和上一个例子一样。
以上,提供一种解决办法的方式和思路,仅供参考,如果用在实际环境中,还需要进一步完善功能。
总结与建议
结语
本文仅对搭建typescript开发node.js项目的环境做一个简单研究和记录。
最初这样想,也只是好奇可不可以这么做。实际上在node.js稳定版本v6.9.1中已经支持了90%的ES6。因此,直接使用ES6开发node.js项目,是很好的选择。
不完善的地方,请见谅,后面会慢慢补充。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。