LoginSignup
6
6

More than 3 years have passed since last update.

TypeScriptのExpressアプリケーションを作る

Posted at

動作環境

  • 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

参考にしたページ

以下はこの記事の参考にさせて頂いたページです。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6