前回の記事
はじめに
こんにちは、梅雨です。
前回の記事では、バックエンドとは何かから始まり、Node.js、TypeScript、Express の概要について学びました。
今回は、実際に TypeScript を用いて Express でバックエンドの構築をしていく方法について解説していこうと思います。
npm とは?
TypeScript(および JavaScript)で開発を行なう上で欠かせないのがnpmです。
npm とは「node package manager」の略であり(諸説あり)、名前の通り Node.js で利用できるパッケージマネージャーとなっています。
今回利用する Express は Node.js のフレームワークですが、こちらは npm パッケージとして公開されています。
また、前回 TypeScript を JavaScript にトランスパイルするために使用したtsc
コマンドは typescript という npm パッケージに含まれています。
Node.js は前回説明したようにパッケージやフレームワークではなくランタイムなので npm パッケージとしてインストールしたりすることはできません。
JavaScript には最小限の機能しか含まれていない(と書くと語弊がありますが。)ため、他の人や組織が開発した追加の機能を用いるためには npm を通してパッケージをインストールする必要があります。
npm は node package manager の略であると書きましたが、npm のパッケージは deno や bun など他のランタイムでも基本的には動きます。また、npm の他に yarn や pnpm のようなパッケージマネージャーも存在します。
とはいえ、Node.js + npm の組み合わせは非常に一般的なので、まずはこれを選んでおけば間違いはないです。
npm で利用できるパッケージは以下のサイトから検索することができます。
バックエンド環境構築
それでは、ようやくバックエンドの環境構築に入っていきます。
まずはプロジェクトのディレクトリに移動します。ディレクトリが存在しない場合は新規で作成してください。
また、前回の記事で使用したindex.ts
およびindex.js
が残っている場合は消してしまって大丈夫です。
$ cd express-typescript-handson
移動できたら、npm を使用するためにプロジェクトを初期化しましょう。
$ npm init -y
するとプロジェクト内にpackage.json
が作成されます。
{
"name": "express-typescript-handson",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
main
、keywords
、author
、license
、description
は自分で開発した npm パッケージを公開するときに以外は特に必要のない項目なので、消してしまっても大丈夫です。
{
"name": "express-typescript-handson",
"version": "1.0.0",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
}
次に、Express をインストールしましょう。
npm パッケージのインストールは以下のように行なうことができます。
$ npm install express
npm install
にはエイリアスとしてnpm i
が割り当てられているため、以下のコマンドでも同様に Express のインストールができます。
$ npm i express
npm 関連の記事を見ていると、パッケージのインストール時に
$ npm i --save express
のように、--save
オプションをつけていることがたまにあります。これは古い書き方であり、現在はこのオプションを指定する必要はありません。(デフォルトで指定されるようになっています。)
Express のインストールが成功すると、package.json
の中身が以下のようになります。
{
"name": "express-typescript-handson",
"version": "1.0.0",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"express": "^4.21.1"
}
}
dependencies
はプロジェクトが使用しているパッケージを指しており、npm install
コマンドによってインストールされたパッケージは自動でここに追加されます。
^4.21.1
はパッケージのバージョンを示しています。
バージョンの前についている^
はキャレットといい、例えば^4.21.1
はバージョン4.x.x
を満たすバージョンへのアップデートは許容する、といった意味になっています。
一般的に npm パッケージのバージョンは4.x.x
から5.x.x
など、一番左の数字が変わるタイミングで大きな変更が行われるため、多くの場合このキャレットを用いてバージョン指定をします。
また、package.json
と同じ階層にpackage-lock.json
というファイルが生成されていると思います。このファイルには、プロジェクトが使用しているパッケージに加え、それらのパッケージが使用しているパッケージ、さらにそれらのパッケージが使用しているパッケージ...とこのプロジェクトが結果的に使用しているすべてのパッケージが記載されています。
package.json
は直接変更しても構いませんが、変更後は必ずnpm install
を実行してパッケージのインストールを行いましょう。
一方でpackage-lock.json
はnpm install
で自動的に生成されるファイルなので、決して直接変更しないようにしましょう。
開発環境と本番環境
ここで少し趣向を変えて、開発環境と本番環境の違いについて説明していこうと思います。
バックエンドに限らず、アプリケーションの開発を行なう際、エンジニアはほとんどの全ての場合において「開発環境」と呼ばれる環境で開発を行います。
開発環境はアプリケーションの"開発"に特化しており、記述したコードが素早く反映されたり、コードの間違いに気づきやすくなっていたりします。
その一方で、開発が完了したアプリケーションを一般向けに公開する際は、「本番環境」と呼ばれる環境でソースコードを実行します。
本番環境はアプリケーションの"実行"に特化しており、軽量化および高速化に重きをおいています。
この「開発環境」と「本番環境」の関係、何かに似ていませんか?
そうです、JavaScript と TypeScript の関係とほとんど同じなのです。
TypeScript は JavaScript に型の概念を加えたものであり、開発中にコードの間違いやエラーの起こりうる箇所に気付くことができます。
一方で、何度も述べているように Node.js は JavaScript のランタイムであり、TypeScript で書かれたコードを直接実行することはできません。そのため、TypeScript を JavaScript にトランスパイルする必要があるのでした。
つまり、本番環境には TypeScript は必要ないのです。
このことを踏まえて、次は開発時のみに使用するパッケージのインストール方法について学びましょう。
開発用パッケージのインストール
では、開発時のみに使用するパッケージはどのようにインストールすればよいのでしょうか?
答えは、--save-dev
オプションをつけることです。
実際に typescript パッケージを開発環境用にインストールしてみましょう。
$ npm i --save-dev typescript
また、Express で TypeScript を使うためには、typescript パッケージの他に@types/express パッケージのインストールも必要となります。
$ npm i --save-dev @types/express
これらのインストールが成功すると、package.json
にdevDependencies
の欄が新しく現れ、その中に typescript パッケージと@types/express パッケージが追加されています。
{
"name": "express-typescript-handson",
"version": "1.0.0",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"express": "^4.21.1"
},
"devDependencies": {
"@types/express": "^5.0.0",
"typescript": "^5.7.2"
}
}
これで開発用のパッケージインストールができました。
--save-dev
オプションはいちいち打つには長すぎるので、大抵の場合は短縮系の-D
オプションで指定します。
また、パッケージを 1 つずつインストールするのは面倒なので、複数のパッケージを一気にインストールすることもできます。
$ npm i -D typescript @types/express
Node.js でサーバを起動する
パッケージのインストールも終わったので、ついにサーバの起動に移っていきましょう。
バックエンドとは?の章で「Web サーバ」の存在について触れましたが、実は自身のパソコン上にもサーバを起動することができます。
パソコン上のサーバを用いることで、開発時にいちいちインターネット上の通信をしなくてよくなり、快適に開発を行なうことができます。
まずは、プロジェクト内にserver.ts
を作成しましょう。
$ touch server.ts
server.ts
のファイル内で、まずはバックエンドの核となる Express をインポートします。
import * as express from "express";
先ほどインストールしたパッケージを使用するためには、このようにインポートを行なう必要があります。
少し難しい話になりますが、JavaScript にはCommonJSとES Moduleという 2 つののモジュールシステムが存在します。
CommonJS ではモジュールをインポートする際に
const express = require("express");
のような書き方をする決まりがあります。
TypeScript では ES Module にしたがった記法が推奨されているため、この先はimport
の使い方を覚えていきましょう。
この先は一旦理解せずともコードを書き写してしまって大丈夫です。次以降の記事で詳しく解説するのですぐに理解できるはずです。
import * as express from "express";
const app = express();
app.get("/", (req, res) => {
res.send("Hello World!");
});
app.listen(3000, () => {
console.log("Server is running on http://localhost:3000");
});
TypeScript で書いたコードは JavaScript のコードに変換する必要があったので、tsc
コマンドでトランスパイルを行いましょう。
$ tsc server.ts
前回と同じように、server.js
が生成されたはずです。
Node.js でserver.js
を実行してみましょう。
$ node server.js
Server is running on http://localhost:3000
http://localhost:3000 にアクセスすると、Hello World!
という文字が表示されているはずです。
これでバックエンドサーバの起動ができました。
サーバを停止するためにはターミナル上で Ctrl + C
を押せば良いです。
おわりに
この記事では、npm によるパッケージのインストール方法、開発環境の構築、そして Express を用いたサーバの起動までを学びました。
次の記事では、REST API と呼ばれる、バックエンドサーバの仕様のようなものについて学んでいきます。
分からないところや間違っていると思う部分があった方は、是非コメントしていただければと思います。
次回の記事