Brian F Love
Ad ·
Learn Angular the right way with Ultimate Courses

TypeScript + Express + node.js

该Express web application framework for Node.js is arguable one of the most popular solutions for creating web apps built on the async Node.js engine.

Getting started with Express is easy. In this tutorial I will walk through setting up Express + Node.js using the node package manager (npm). We'll wire up a server in JavaScript and then build the app using TypeScript.

TypeScript 2更新

如果您已准备好用于打字标记2,则在此文章上介绍TypeScript 2更新:TypeScript 2 + Node.js + Express

Why TypeScript?

I believe that TypeScript has been embraced as the choice language for building next generation web application using ECMAScript 6 (ES6) with strong typing. Strong typing doesn't necessarily improve the JavaScript that your Node.js server will execute, or the JavaScript that your browser might execute. However, it provides the developer more insight into public and 3rd party APIs as well as reducing the bugs (and development cycle to check for bugs) in the software we are developing.


Let's spin up our first Express + Node.js server using npm + Javascript.

  1. Download and Install Node.js
  2. Create a package.json file
  3. 安装Express.

After answering the prompts, a package.json file is created in


  1. Specify the node engine
  2. Create a start script
{"name":“myapp”,"description":"Just for fun",“版”:"1.0.0",“私人的”:true,"author":“yobet外围Brian Love”,"engines":{“节点”:"~5.6"},“脚本”:{“开始”:"node ./bin/www"}}

Note theenginesand脚本properties have been added to the configuration. Theenginesproperty is not necessary, but is helpful if you are deploying to the Google Cloud platform. The脚本属性是可以使用NPM执行的脚本地图。

In this example, we have created a script named开始that executes node and provides the initial JavaScript file to execute. In this case I have created a directory in my application calledbin,文件名为www(注意没有扩展名)。这个www文件是Node.js执行的JavaScript文件,即反过来将启动我们的Express Web应用程序。

Installing Express


$NPM.installexpress --save

运行此命令后,您应该看到一个node_modulesfolder in your application's root directory (where you are executing this command). This folder contains all of the node modules that express depends on, as well as the express module. As we build our Express + Node.js application this folder will contain all of the 3rd-party modules that we are using.

If you are using Git make sure you add thenode_modulesfolder to your.gitignore.file prior to committing.

设置Express + node.js

To get started with express we will create abin/wwwfile that theNPM.开始命令将执行。


From there, open Sublime Text or your favorite editor. We'll just be writing vanilla JavaScript to get our Express + Node.js web application up and running. Then, once we start coding our app we'll switch over to TypeScript.

Why not use TS for the server startup?Well, I figure that once I write this code, I'm done. Sounds optimistic, I know. But, in theory I'll spend the rest of my time working on my app.


#!/usr/bin/env节点'使用strict';//模块依赖项。'../app');var.调试=require('debug')('express:server');var.http=require('http');//get port from environment and store in Express.var.port=normalizePort(处理envPORT||8080.);appset('港口',port);//create http servervar.server=httpcreateServer(app);//listen on provided portsserver(port);//add error handlerserveron('错误',onError);//开始在港口收听serveron('listening',onListening);

该first thing that we are doing is requiring the module "../app". This refers to a file namedapp.js.that will live in our root folder (under myapp in this example). Theapp.js.file will be created from our TypeScript source file. So, for now, don't worry about creating this. Just keep in mind that we will be creating an app.js file that bootstrap's our application.

该app.js.file is in the myapp directory, while the www file is in the ./bin directory

Also, you might have noticed that I am calling a function calledunconizeport(),它接受从名为“端口”的环境变量检索的端口值。如果这是未定义的(valsey),那么端口默认为8080.您现在可能不需要担心它 - 但是当您将应用程序启动到野外时,它会有所帮助。该unconizeport()method was provided as part of the Google Cloud developer documentation, so I take no credit for it.

/** * Normalize a port into a number, string, or false. */functionnormalizePort(){var.port=释放(,10);if(isNaN(port)){// named pipereturn;}if(port> =0){// port numberreturnport;}returnfalse;}

Further, I also have anonError()抛出未捕获的异常时调用的函数。此外,它再次由Gathub的Google云平台样本提供。yobet英雄联盟

/** * Event listener for HTTP server "error" event. */functiononError(错误){if(错误SYSCALL.!=='听'){throw错误;}var.bind=typeofport==='串'?'Pipe '+port:'港口 '+port;//使用友好的消息处理特定的侦听错误switch(错误code){案件'EACCES':console错误(bind+' requires elevated privileges');处理exit(1);break;案件'EADDRINUSE':console错误(bind+' is already in use');处理exit(1);break;default:throw错误;}}

该re is also a callback function calledonListeningthat is executed once the server has successfully started.

***Event listenerforHTTPserver"listening"事件*/functiononListening(){var.addr.=serveraddr.ess();var.bind=typeofaddr.==="string"?“管道”+addr.:“港口 ”+addr.port;调试("Listening on "+bind);}

好的,我们完成了繁忙的工作。W E已将Express作为节点模块安装,我们创建了启动脚本。现在,让我们开始使用类型签字来编写我们的应用程序。

Install TypeScript Compiler & Linter


$NPM.installtypescript --save

要编译我们的类型,我们将使用Grunt Task Runner。所以,让我们再次使用NPM安装它。然后我们将创建gruntfile.js文件。

$NPM.installgrunt --save $NPM.installgrunt-cli --save $NPM.installGrunt-Ts  - 莎莎斯塔NPM.installgrunt-tslint --save $NPM.installGrunt-Contrib-Watch --Save $NPM.install司--save $touchgruntfile.js

Open up the gruntfile.js that is located in the root of your application (next to package.json). If you're unfamiliar with Grunt, check out their website to become familiar with it. I'm not going to dive into Grunt as that is beyond the scope of this tutorial.


让我们添加一个任务来编译代码打印稿。I'll also be adding a task to lint my TS code, as well as a watch task for automatically compiling and linting my TS after changes are saved. Here is the full gruntfile.js contents to get us started.

module出口=function(grunt){'使用strict';gruntinitconfig({ts:{app:{文件:[{src:['src/**/*.ts','!src / .basedir.ts','!src/_all.d.ts'],dest:'.',},],选择:{module:'commonjs',诺布:true,目标:'es6',sourceMap:false,},},},:{选择:{组态:'tslint.json',},文件:{src:['src/**/*.ts'],},},watch:{ts:{文件:['js/src/**/*.ts','src/**/*.ts'],tasks:['ts','tslint'],},},});gruntloadNpmTasks('Grunt-Contrip-Watch');gruntloadNpmTasks('grunt-ts');gruntloadNpmTasks('grunt-tslint');gruntregisterTask('默认',['ts','tslint']);};

该typescript compiler will look for all files with the.ts.file extension located in aSRC /directory that we will create. We are also ignoring some common files that might appear in our src folder, such as.Basedir.and_all.d.ts。_all.d.ts文件引用我项目中的所有类型键录声归档文件。

我们可以手动执行此操作node_modules/.bin/tscbinary executable, or we can create a script in ourpackage.jsonfile to do this for us. So, let's simply add the following script to package.json. Your package.json file should now look like this:

{"name":“myapp”,“版”:"1.0.0","description":"",“脚本”:{"grunt":"grunt",“开始”:"node ./bin/www"},。。。}

Ok - we're almost there. Next, we need to tell tslint what our lint rules are. Here is what my tslint.json file looks like.

{“规则”:{"class-name":true,“卷曲”:true,"eofline":false,"forin":true,"indent":false,"label-position":true,"label-undefined":true,“max-line-length”:[true,150],"no-arg":true,“不按”:true,“无控制台”:false,“无构造”:true,“no-constructor-vars”:false,"no-debugger":true,“无重复键”:true,"no-duplicate-variable":true,"no-empty":true,"no-eval":true,“没有字符串文字”:true,“没有切换案例 - 落下”:true,"no-trailing-whitespace":true,"no-unused-expression":true,"no-unused-variable":false,“不可无法访问”:true,“禁止使用前申报”:true,"no-var-requires":false,"one-line":[true,“检查 - 开放式”,“检查抓住”,"check-else",“检查 - 空白”],"quotemark":[true,"double"],"semicolon":true,“三等于”:[true,“允许 - 禁止检查”],"typedef":[true,"callSignature",“indexsignature”,"parameter","propertySignature","variableDeclarator","memberVariableDeclarator"],"use-strict":false,"variable-name":[true,"allow-leading-underscore"],“空白”:[true,"check-branch",“支票下降”,“检查运营商”,"check-separator",“检查型”]}}

If everything works you should be able to execute the grunt command.

$ grunt


TypeScript Express Web Application

如果您认为这一点,我们终于准备好使用TypeScript + Express + Node.js开始编写我们的应用程序。换句话说,现在我们可以开始使用有趣的东西!


$mkdirsrc $cdsrc $touchapp.ts

Let's get started with our application. The first thing we want to do is create a Server class.

"use strict";进口*asbodyParser"body-parser";进口*asexpress“表现”;进口*aspath"path";/** * 服务器。* * @class服务器* /classServer{上市app:expressApplication;/ ** *引导应用程序。* * @class服务器* @method bootstrap * @static * @return {}返回此应用程序的新创建的注射器。* /上市static引导():Server{returnnewServer();}/** * Constructor. * * @class Server * @constructor */构造函数(){//create expressjs application这个app=express();//configure application这个config();}}

Let's quickly walk through the TypeScript above.

  • 首先,我正在使用严格的JavaScript模式。
  • 接下来,我们正在导入应用程序的必要模块。我们正在使用body-parsermodule, theexpressengine, and the built-in node.jspathmodule.
  • 该n I create theServer类。
  • Serverclass has a property named app that is of type express.Application. We'll dig more into this type declaration in a bit. Just hang tight.
  • Serverclass has a static method named bootstrap that will create a new instance of ourServer类。
  • Server类还具有构造函数方法,可创建和配置我们的应用程序。

该re are a couple of issues before we move ahead:

  • 我们尚未安装Body-Parser模块。我们需要使用NPM来做。
  • 该TypeScript compiler doesn't know anything about the built-in objects, likeArrayandBoolean.
  • 该TypeScript compiler doesn't know the type definition for express (remember, the type declaration for the app property was set to express.Application).


$NPM.installbody-parser --save



Open the _all.d.ts file and paste this new line at the top of the file

/// <参考路径=“../ node_modules / pysiftcript / lib / lib.es6.d.ts”/>

该n, modify your app.ts file so that you are referencing the _all.d.ts file


该TypeScript compiler now knows about the ES6 interfaces (and objects). We'll also put more references in the _all.d.ts file, including the reference to our main typings file.

接下来,我们会看看使用typingsfor obtaining type definition files for common modules that we will be using.


Install Typings

Typings uses the肯定休闲用于检索和存储节点模块和开源框架和库(如Express或Angular)的文本定义文件的库。如果您使用的是使用类型签字,您可能已经使用过tsdcommand line utility for installing TypeScript definition files from DefinitelyTyped. However, at the time of this writing, tsd has been deprecated in favor of the newtypingsproject.

$NPM.installtypings --save

Once we have typings installed we can use the command-line interface for searching and installing TypeScript definition files. It is important to note that我将从应用程序的根目录执行键入cli

$ node_modules/.bin/typingsinstallbody-parser  -  ambint --save $ node_modules / .bin /打字install表达——环境——节省node_modules美元/。bin / typingsinstall节点 -  {bsave --save $ node_modules / .bin /打字installserve-static --ambient --save $ node_modules/.bin/typingsinstallexpress-serve-static-core --ambient --save $ node_modules/.bin/typingsinstallmime --ambient --save

该下一个step is to reference thetypings/main.d.ts从敞口生成的文件。main.d.ts文件类似于我们的_all.d.ts文件,因为它包含对由indings安装/管理的所有类型键盘定义文件的引用。因此,打开_all.d.ts文件并在我们刚添加的现有行下方添加此代码行。


Now that we have typings installed and we are referencing the main.d.ts definition file that Typings generates we are ready to build our TypeScript + Express + Node.js application.

$ grunt $NPM.开始

If we visithttp://localhost:8080in our browser we should we an error indicating that there is not a GET route specified for the root.

Screenshot of browser showing error message 'cannot GET'

Define Routes

最后一步是为您的Web应用程序定义路由。我喜欢在路由模块中的单独类中配置我的路由。这是我的src /路由/ index.ts文件的样子。

/// "use strict";进口*asexpress“表现”;module Route{exportclassIndex{上市index(req:express请求,res:express响应,下一个:expressNextFunction){//渲染页面resrender(“指数”);}}}export=路线;

我的Index.index()路由只是呈现索引页面。要加入这一点,我们需要首先要求路线/index.tsmodule in our applicationapp.ts文件。


然后,我将创建一个名为的新私有方法路线(), which is called from the构造函数function.

/** * Constructor. * * @class Server * @constructor */构造函数(){//create expressjs application这个app=express();//configure application这个config();//configure routes这个路线();}

我的路线()方法只需将Web root的GET请求“连接即可:/。

/ ** *配置路由* * @class服务器* @method路由* @return void * /private路线(){//获得路由器let路由器:express路线r;路由器=express路线r();//create routesvar.index:IndexRoute.Index=newIndexRoute.Index();//home page路由器得到("/",indexindexbind(indexindex));//use router middleware这个appuse(路由器);}

In the routes() method I first get access to the路线r()in express, then using the module that I imported previously, I instantiate a new instance of theIndex类。我的Indexclass has a method namedindex(I know, a little confusing).

Hello World

Well, we made it. It's finally time to output the famous "Hello World". When we configured the application I chose to use the jade template engine. You can choose to use another template engine if you prefer. So, let's install jade via npm.

$NPM.installjade --save


$mkdirviews $cdviews $touchindex.jade

Open up index.jade in your favorite editor and add the following.


不要忘记将Ringscript代码重新编译为JavaScript,或使用Grunt Watch命令:

$ gruntwatch



Now, loadhttp://localhost:8080in your browser and you should see the following:

Screenshot of browser displaying 'hello world'



Brian F Love