課外活動7

Node.js の勉強をします.

環境は,Windows10 使う シェルは PowerShell を想定して記事を書きます.

Node.jsとは?

Node はスケーラブルなネットワークアプリケーションを構築するために設計された非同期型のイベント駆動の JavaScript 環境です。 Node.js とは | Node.js

単語の意味

スケーラブル

  1. used to describe a computer, a network, software, etc. that can be adapted to meet greater needs in the future
  2. designed to work on a large or small scale, according to needs
  3. that can be climbed

https://www.oxfordlearnersdictionaries.com/definition/english/scalable?q=scalable

今回の場合,1番の「将来のニーズに対して適応可能」という意味です.

非同期型

非同期とは、データを転送する際に、送信側と受信側のタイミングの一致(同期)を気にせずにデータをやり取りすることである。

非同期とは (asynchronous) ひどうき: - IT用語辞典バイナリ

イベント駆動

イベントドリブンとは、コンピュータプログラムの開発および実行方式の一つで、利用者や外部の別のプログラムなどが引き起こす出来事に対応する形で処理を記述あるいは実行する方式。

イベントドリブン(EDA)とは - IT用語辞典

Node.js のインストール

PowerShell で以下のコマンドを打って確認してください.

node -v

もし,Node.jsが既にインストールされているのであればバージョン情報が返ってきます.

node -v
v10.13.0

インストールされていなければ,以下のURLからダウンロードしインストールしてください.

nodejs.org

補足:Node.jsはバージョンの更新が頻繁にあるので,nodist を使うことをおすすめします.nodist はwindows において使うことができるnode.js/npm のバージョンマネージャーです.複数のバージョン環境をPC上に作成でき,コマンドでバージョンを切り替えることができます. github.com

プロジェクト(パッケージ)の作成

cd でプロジェクトを作りたいディレクトリに入って以下のコマンドを打ってください.

npm init

パッケージ名やversion,ライセンス等聞かれますがすべて デフォルトでも問題ありません.(enterを押し続けると,デフォルトの括弧でくくられた値となります.)

すると,package.jsonが作成されています.

Node.js によるサーバアプリケーションの作成

Nodejsによるサーバを構築します.初日の図を思い出してください.

f:id:Polyomino:20190125004455p:plain

クライアントは,サーバに対してリクエストを行います.

サーバは,クライアントに対してレスポンスを返します.

すなわち,レスポンスを返す部分を作成します.

先程の 「プロジェクトの作成」で作成したフォルダに index.js というファイルを作成します.index.jsに以下のコードを書いてください.

// httpモジュールの読み込み
const http = require("http");

// ホスト名とポートの定義
const hostname = "127.0.0.1";
const port = 3000;

// リクエストに対してのレスポンスを定義
const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end("Hello world\n");
});

// サーバを起動.起動時に,コンソールにメッセージを表示
server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

node.jsでindex.js動かします.PowerShell で以下のコマンドを打って下さい.

node index.js

package.json に mainとしてindex.js が指定されているため,以下のコマンドでも実行できます.

node .

すると,Server running at http://127.0.0.1:3000/というメッセージが出てきます. ブラウザで http://127.0.0.1:3000/ にアクセスしてみると,Hello world というメッセージが表示されます.

f:id:Polyomino:20190131104051p:plain

HTMLファイルを返してみる.

適当なhtmlファイルを作成します. index.html という名前で保存してください.

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Node</title>
  </head>
  <body>
    Nodeはおもしろいなぁ
  </body>
</html>

リクエストがきたとき,htmlを返すようにindex.jsを書き換えます

const http = require("http");
// File Systemを扱うfsモジュールを読み込み
const fs = require("fs");

// index.htmlを読み込む
const index = fs.readFileSync("index.html");

const hostname = "127.0.0.1";
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  // 返すものはテキストではなくhtml
 res.setHeader("Content-Type", "text/html; charset=utf-8");
  // index.htmlを返す
  res.end(index);
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

ブラウザで http://127.0.0.1:3000/ にアクセスしてみると,「 Nodeはおもしろいなぁ」というメッセージが表示されます.

f:id:Polyomino:20190131110258p:plain

パッケージの利用

すべて自分でコードを書いてもいいのですが,毎回同じコードを書いていては非効率です.また,サーバを立てる,ファイルを返す等の処理は多くの人が利用するものなので,共同(ときには個人)で作り上げてみんなでそれを使ったほうが非常に効率的です.

nodeには標準でnpmというパッケージマネージャがついています. npmを利用することによって,他人の作ったパッケージを自分のパッケージで利用することができます. package.json はそのパッケージを管理するためのjsonファイルです.

引き続き同じディレクトリで作業します.

Nodeでよく用いられるパッケージとして,expressというものがあります.expressを使ってみます.

npm install express --save

するとexpressのインストールが始まります. インストール完了後,package.json を見てみると,"dependencies" に expressが追加されています.

expressを使ってサーバを立ち上げます.app.jsという名前で以下のコードを打ち込んでください.

const express = require("express");

const app = express();
const hostname = "127.0.0.1";
const port = 3000;

app.get("/", (req, res) => res.send("Hello world"));

app.listen(port, hostname, () =>
  console.log(`express server running at http://${hostname}:${port}/`)
);

そして,サーバを立ち上げます.

node app.js

ブラウザで http://127.0.0.1:3000/ にアクセスしてみると,先程同様 Hello world というメッセージが表示されます.

index.htmlを返すサーバにしてみます.

const express = require("express");
const app = express();

const path = require("path");

const hostname = "127.0.0.1";
const port = 3000;

app.get("/", (req, res) => res.sendFile(path.join(__dirname, "/index.html")));

app.listen(port, hostname, () =>
  console.log(`express server running at http://${hostname}:${port}/`)
);

ブラウザで http://127.0.0.1:3000/ にアクセスしてみると,「 Nodeはおもしろいなぁ」というメッセージが表示されます.

この小さな例ではわからないかもしれませんが,プロジェクトが大きくなってきた時,パケージを利用するメリットが大きくなります.

Express 4.x - API Reference

expressには多くの機能があり,ほんの数行書くだけでその機能を作ることができます.仮にすべて自分で実装しようとすると複雑になってしまったり書く量が増えてしまったりと大変なことになります.

時と場合に合わせて適切にパッケージを利用しましょう.

gitignore

npm install express をしたあと,node_modulesというフォルダができていたことに気づいたかもしれません.これは,expressのソースコードなどが入っています.GItでプロジェクトを管理するとき,この node_modules は含めない方が良いです.なぜなら,パッケージは日々いろんな人が更新します.それらが更新されるごとに node_modules の中身も更新されます.この変更も gitで管理してしまうと,自分の変更した点がわかりづらくなったり,リポジトリが重たくなったりしてしまいます.なので,.gitignore というファイルを作成してgitの管理から外します.

.gitignore というファイルを作成し,以下の内容をコピーしてください.

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

gitignore/Node.gitignore at master · github/gitignore · GitHub

これで node_modules がGitの管理から外れました.

「別のPCでgit clone してきたとき node_modules が無いじゃないか」と思うかもしれません.しかしこれは心配する必要はなく,npm install というコマンドを打てば package.json にかかれているパッケージ群がインストールされます.

まとめ

nodeは非同期型のイベント駆動の JavaScript 環境

nodeにはnpmというパッケージマネージャがある.

ケースに合わせて適切にパッケージを利用しよう.