LoginSignup
0
1

More than 3 years have passed since last update.

ディレクトリ構成を変えずに最小限の手間でexpressをTypescriptにする手順

Last updated at Posted at 2021-03-30

目的

TypeScriptにするためにディレクトリ構成を変更するなどせず、拡張子を変える + αのおまじない程度でTypeScript化します。

ソースを変えた際に自動で再起動する機能も持っています。

/src や /dest は不要(jsファイルのパスから変更する必要もなく、トランスパイル後の出力先も意識する必要はありません)
(tsconfigファイルの設定で頭を悩ます必要はないです)

3部構成です

  1. express-generatorインストール+プロジェクトテンプレート作成
  2. 拡張子の変更 + おまじない(www.jsでts-nodeを使い、tsファイルをロードする)
  3. requireをimportに変えて型定義の恩恵に預かる

1部 expressとTypeScriptの導入

npx express-generator --no-view --git ./express-generator-tsnode
cd express-generator-tsnode/
npm install
  • REST API用に作るので、viewエンジンは未使用にしています(--no-view)
  • --git を付けて「.gitignore」を作っています(楽をするため)

この時点でexpressをサーバとして動作させることができます。「http://localhost:3000」

npm run start
  • 次にTypeScriptと、型定義をインストールします
npm i -D typescript nodemon ts-node @types/cookie-parser @types/express @types/morgan 
  • Typescriptの設定ファイルを作成します(tsconfig.json)
npx tsc --init

2部 拡張子の変更 + おまじない(www.jsでts-nodeを使い、tsファイルをロードする)

この章がメインです。

  1. 生成されたjsファイルの拡張子を全て「ts」に変更します

    ./route/index.js ⇒ ./route/index.ts

    ./route/users.ts ⇒ ./route/users.ts

    ./bin/wwww.js  ⇒ ./bin/wwww.ts

  2. ./bin フォルダに「www.js」を追加し下記の内容を追記します。

require('ts-node').register();
require('./www.ts');
  1. tsconfig.json のコメントを1行外します

    jsソースのままでも動作可能とするためです。

"noImplicitAny": false,
  • これでtypescript化したexpressアプリケーションが動作します。
npm run start
  • ファイル変更時にリコンパイル&再起動を行うため、package.jsonに「dev」を追加します。
  "scripts": {
    "start": "node ./bin/www",
    "dev": "nodemon --ext js,ts ./bin/www"
  },

これでファイル変更時にリロードされるようになります。

npm run dev

3部 requireをimportに変えて型定義の恩恵にあずかる

2章まで目的のts化は果たしていますが、require()で読み込んだモジュールはany扱いとなり
typescriptの恩恵にあずかれないため、importに書き換えます。

exportの書き換えも必要ですが、元のmodule.exportに加えて、export defaultを追加することで読み込み側は変更を強制されなくなります。

// importでもrequire()でも読み込めるように2種類export
module.exports = app;
export default app;

変更前(app.ts)

var express = require('express');
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();

app.use(logger('dev'));
app.use(express.json());
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;
  • 変更後のソースは一部のみ紹介

変更後(app.ts)

import express from 'express';
import path from 'path';
import cookieParser from 'cookie-parser';
import logger from 'morgan';

// module.exportsとexport default両方使っているので
// 読み込み側はimportでもrequire()でも使えます
// ちょっとずつ変更していくためには便利です
var indexRouter = require('./routes/index');
import usersRouter from './routes/users';

var app = express();

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// importでもrequire()でも読み込めるように2種類export
module.exports = app;
export default app;

変更後(index.ts)

import express from 'express';
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

// importでもrequire()でも読み込めるように2種類export
module.exports = router;
export default router;
0
1
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
0
1