動作環境
- macOS Mojave
- node v12.14.1
- npm 6.13.4
- express 4.16.4
- typescript 3.8.2
最終的なコード
最終的なコードは以下に上げてあるので、先に見たい方は御覧ください。
https://github.com/jumperson/quick-start-express-typescript
作成手順
JavaScriptのExpressアプリケーションを作成する
Express のアプリケーション生成プログラム に従って作成していきます。
グローバルにexpressをインストールします。
$ npm install express-generator -g
インストールしたコマンドで作業ディレクトリに quick-start-express-typescript
という名のExpressアプリケーションを作成します。
$ express quick-start-express-typescript --git --no-view
npm installを実行し、Expressアプリケーションを起動します。
$ cd quick-start-express-typescript
$ npm install
$ DEBUG=myapp:* npm start
http://localhost:3000/ にアクセスし、動作していることを確認します。
不要なViewファイルを削除する
今回はTypeScriptにするファイルを減らすためにViewファイルは削除します。
$ rm -r ./public/
$ rm ./routes/index.js
上記を参照しているコードも修正します。
diff --git a/app.js b/app.js
index d187f73..3aecdc0 100644
--- a/app.js
+++ b/app.js
@@ -3,7 +3,6 @@ var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
-var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
@@ -14,7 +13,6 @@ app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
-app.use('/', indexRouter);
app.use('/users', usersRouter);
module.exports = app;
TypeScriptに書き換える
初めに、以下のコマンドを実行し、TypeScriptに必要なモジュールを追加します。
$ npm install --save-dev typescript @types/node @types/express @types/debug
次に、以下のコマンドで、 tsconfig.json
を作成します。
$ ./node_modules/.bin/tsc --init
次に、JavaScriptファイルを以下の通りTypeScriptに書き換えます。
./routes/users.js
=> ./routes/users.ts
import { Request, Response } from "express";
/* GET users listing. */
export const index = (req: Request, res: Response) => {
res.send('respond with a resource');
};
./app.js
=> ./app.ts
import express = require('express')
import * as usersRouter from "./routes/users";
const app = express();
app.use('/users', usersRouter.index);
export default app;
./bin/www
=> ./bin/www.ts
#!/usr/bin/env node
/**
* Module dependencies.
*/
import app from '../app';
import * as http from 'http';
import * as debugModule from 'debug';
var debug = debugModule.debug('quick-start-express-typescript:server');
/**
* Get port from environment and store in Express.
*/
const port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
/**
* Create HTTP server.
*/
const server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val: string): number | string | boolean {
const nport = parseInt(val, 10);
if (isNaN(nport)) {
// named pipe
return val;
}
if (nport >= 0) {
// port number
return nport;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error: any): void {
if (error.syscall !== 'listen') {
throw error;
}
const bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening(): void {
function bind() {
const addr = server.address();
if (addr === null) {
return '';
}
if (typeof addr === 'string') {
return 'pipe ' + addr;
}
if ('port' in addr) {
return 'port ' + addr.port;
}
}
debug('Listening on ' + bind());
}
TypeScriptをJavaScriptにトランスパイルする
まずは src
ディレクトリを用意し、上記の .ts
ファイルをすべて移動します。
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: app.ts -> src/app.ts
renamed: bin/www.ts -> src/bin/www.ts
renamed: routes/users.ts -> src/routes/users.ts
次に dist
ディレクトリを用意し、 tsconfig.json
を以下のように変更します。
diff --git a/tsconfig.json b/tsconfig.json
index 54d53fd..b88125a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -12,7 +12,7 @@
// "outFile": "./", /* Concatenate and emit output to single file. */
- // "outDir": "./", /* Redirect output structure to the directory. */
+ "outDir": "./dist", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
次に、トランスパイルのコマンドを追加します。
diff --git a/package.json b/package.json
index 29eaa22..48a62e0 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,8 @@
"version": "0.0.0",
"private": true,
"scripts": {
- "start": "node ./bin/www"
+ "start": "node ./bin/www",
+ "build": "tsc"
},
"dependencies": {
"cookie-parser": "~1.4.4",
追加したコマンドを実行し、 dist
ディレクトリにJavaScriptのファイルが作成されることを確認します。
$ npm run build
また、 dist
ディレクトリはgit管理不要なので、以下の修正を行います。
diff --git a/.gitignore b/.gitignore
index d1bed12..a031e35 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,3 +59,5 @@ typings/
# next.js build output
.next
+
+/dist
トランスパイルされたファイルでExpressを起動する
Express起動をコマンドを修正してExpressを起動できるようにします。
diff --git a/package.json b/package.json
index 48a62e0..ee55eb6 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"version": "0.0.0",
"private": true,
"scripts": {
- "start": "node ./bin/www",
+ "start": "npm run build && node ./dist/bin/www.js",
"build": "tsc"
},
"dependencies": {
ホットリロードの設定
最後に、開発時のコード修正時にホットリロードされるようにします。
以下のモジュールを追加します。
$ npm install --save-dev ts-node nodemon
次にルートに以下のファイルを追加します。
{
"watch": ["src"],
"ext": "ts",
"exec": "ts-node ./src/bin/www.ts"
}
次にコマンドを追加します。
diff --git a/package.json b/package.json
index f602cdd..c56097d 100644
--- a/package.json
+++ b/package.json
@@ -4,6 +4,7 @@
"private": true,
"scripts": {
"start": "npm run build && node ./dist/bin/www.js",
+ "start:dev": "nodemon",
"build": "tsc"
},
"dependencies": {
これで以下のコマンドでExpressが起動し、またコードを修正した際に自動で再起動されるようになります。
npm run start:dev
最終的なコード(再掲)
冒頭でも記載しましたが、最終的なコードは以下に上げてあります。
https://github.com/jumperson/quick-start-express-typescript
参考にしたページ
以下はこの記事の参考にさせて頂いたページです。
- microsoft/TypeScript-Node-Starter: A starter template for TypeScript and Node with a detailed README describing how to use the two together.
- TypescriptでExpressを設定する - Qiita
- nodebestpractices/separateexpress.md at master · goldbergyoni/nodebestpractices
- Express のアプリケーション生成プログラム
- NodeJSでTypeScriptのホットリロード - Qiita