Help us understand the problem. What is going on with this article?

Get started Express + TypeScript する

More than 1 year has passed since last update.

はじめに

どうしてもJavascriptでサーバーサイドの実装したかったのでExpress+TypeScriptのセットアップ。
特に嵌りポイントもなかったのですが備忘に。

前提条件

Node.jsとnpmのインストールは一通り終わってる前提です。

目指す姿

  • TypeScriptでserver.tsを書いてserver.jsにトランスパイルできるようにする
  • ちゃんとデバッグできるようにする

必要なモジュールをインストールする

Express

この記事のテーマです。typesもまとめてインストールしてしまいます。

npm install --save express
npm install --save-dev @types/express

TypeScript

TypescriptとLinterとwebpackにいれるloaderをインストールしておきます。ルールはairbnbで。

npm install --save-dev typescript ts-loader tslint tslint-loader tslint-config-airbnb

Webpack

みんなが大好きなwebpackです。たくさんのjsファイルを1個にしてくれるすごいやつです。

npm install --save-dev webpack webpack-cli
npm install --save-dev webpack-node-externals    #warningの抑制

各種設定ファイル

Webpackの設定

気をつけるのはtargetをnodeにすることと、externalにwebpack-node-externalsを指定するくらい。
webpack-node-externalsを指定しないと、'"/Users/xxx/node_modules/@types/express/index"' has no default exportが出てうざいです。

webpack.config.dev.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
    mode: 'development',
    entry: './src/server.ts',     // src下に書いていくので src/server.tsにしとく
    target: 'node',               // Module not found: Error: Can't resolve 'fs'とかいっぱい出たら、この行書き忘れ
    externals: [nodeExternals()], 
    devtool: 'inline-source-map',
    module: {
        rules: [
            {
                enforce: 'pre',
                loader: 'tslint-loader',
                test: /\.ts$/,
                exclude: [
                    /node_modules/
                ],
                options: {
                    emitErrors: true
                }
            },
            {
                loader: 'ts-loader',
                test: /\.ts$/,
                exclude: [
                    /node_modules/
                ],
                options: {
                    configFile: 'tsconfig.dev.json'
                }
            }
        ]
    },
    resolve: {
        extensions: [ '.ts', '.js' ]
    },
    output: {
        filename: 'server.js',
        path: path.resolve(__dirname, 'dist')
    }
};
webpack.config.prod.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
    mode: 'production',
    entry: './src/server.ts',     // src下に書いていくので src/server.tsにしとく
    target: 'node',               // Module not found: Error: Can't resolve 'fs'とかいっぱい出たら、この行書き忘れ
    externals: [nodeExternals()], 
    module: {
        rules: [
            {
                enforce: 'pre',
                loader: 'tslint-loader',
                test: /\.ts$/,
                exclude: [
                    /node_modules/
                ],
                options: {
                    emitErrors: true
                }
            },
            {
                loader: 'ts-loader',
                test: /\.ts$/,
                exclude: [
                    /node_modules/
                ],
                options: {
                    configFile: 'tsconfig.dev.json'
                }
            }
        ]
    },
    resolve: {
        extensions: [ '.ts', '.js' ]
    },
    output: {
        filename: 'server.js',
        path: path.resolve(__dirname, 'dist')
    }
};

tsconfig.jsonとtslint.jsonの設定

Requestなど必ずしもすべての引数を使うわけではないのでnoUnusedParametersはfalseに、インデントサイズは4にしておく(好み)。

tsconfig.dev.json
{
  "compilerOptions": {
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "lib": ["es2018", "dom"],
    "moduleResolution": "node",
    "removeComments": true,
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "strictFunctionTypes": false
  }
}
tsconfig.prod.json
{
  "compilerOptions": {
    "noImplicitAny": true,
    "module": "es6",
    "target": "es5",
    "jsx": "react",
    "lib": ["es2018", "dom"],
    "moduleResolution": "node",
    "removeComments": true,
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": false,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "strictFunctionTypes": false
  }
}
tslint.json
{
    "extends": "tslint-config-airbnb",
    "rules": {
        "ter-indent": [true, 4]
    }
}

最後に

ソースの追加

最後にソースの追加をします。

src/server.ts
import * as Express from 'express';

const app = Express();

app.get(
    '/',
    (req: Express.Request, res: Express.Response) => {
        return res.send('Hello world.');
    });

app.listen(
    3000,
    () => {
        console.log('Example app listening on port 3000!');
    });

export default app;

ビルドして起動

あとはビルドして起動するだけです。

webpack --config webpack.config.dev.js    # もちろん本番用ビルドはwebpack.config.prod.jsに変える
node dist/server.js

できあがったソース群はこちら
https://github.com/IgnorantCoder/typescript-express-sample

IgnorantCoder
Handii, Inc.のCTOです
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした