Node.jsとはなにか？なぜみんな使っているのか？

この記事は

「JavaScriptの勉強してたらみんなNode.jsの存在を前提に話が進む。でもNode.jsってWebサーバじゃないの？ なんでインストールしなきゃいけないの？ なんでみんな使ってるの？」

といった疑問を解消することを目的としています。

# 基礎：JavaScriptの特徴

まずはJavaScriptと他のプログラミング言語の違いを知っておく必要があるので解説します。

**JavaScript**はChromeやFirefoxといった「**ブラウザ上**」で動作するプログラミング言語です。
対して**Python**や**Ruby**のような一般的なプログラミング言語は通常「**パソコン上**」で動作します。[^0]
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238976/41688c17-e75a-44d3-d147-66ccba1ca4d8.png" width="531px">

[^0]: 本来「OS上」と表現すべきところですが、噛み砕いて「パソコン上」と表現しています。~~というのは嘘で先に作った図に「パソコン」って書いちゃったからです~~

このことが生み出す違いは、**OSの機能にアクセスできるかどうか**です。
「OSの機能」とは例えばファイルの読み書きや、ネットワーク通信などの機能のことです。
パソコン上で動作するアプリケーション（PythonやRubyなどを含む）ではこれらの機能を扱うことができます。[^2]
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238976/7f0a84bd-a324-35ab-3eb7-20b48810147a.png" width="341px">

[^2]: 昨今ではOSのセキュリティがしっかりしてきたので、インストールしたアプリケーションであっても自由に全てのOSの機能を使えるわけではなく、アプリケーションが特定の機能にアクセスしようとすると、まずユーザーに許可が求められます。

それに対し、ブラウザ上で動作するプログラム（JavaScript）がOSの機能へアクセスできてしまうとセキュリティ的に問題があります[^3]。例えば、あるサイトにアクセスしただけで勝手にパソコン上のファイルを読み書きされたり、パソコン上のファイルを一部消されたりしたら、大問題です[^4]。

[^3]: ActiveXとかいうのはこれができちゃいますが。
[^4]: JavaScriptは関係ないですけど昔とあるゲームでアップデートを行ったら、OSを含む関係ないデータまで消されてしまうHDDバースト事件なんてのがあったのを思い出しました。あれでプログラムって結構好き勝手できちゃうんだなと実感しました。

ということで、ブラウザ上で動作するJavaScriptはOSの機能にアクセスできないようになっています。
ですがOSの機能へ全くアクセスができないのでは些か不便なので、ブラウザが限定的にOSの機能へのアクセスを仲介してくれています。[^5]
最近ではカメラやマイクへのアクセスの仲介もやってくれるので、ブラウザ上でWeb会議できたりして便利になってきています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238976/0127a5af-6f2e-0e26-70d9-aa52e2110d17.png" width="531px">

[^5]: ブラウザはインストールされたアプリケーションなので当然OSの機能へアクセスできます


# Node.jsって何者？

そんなブラウザ上という制限された環境でしか動けなかったJavaScriptを、PythonやRubyのようにパソコン上で動かせるようにしてくれるのが「**Node.js**」です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238976/753eb852-56ca-8539-cfb1-5ecb70717009.png" width="500px">
誤解されることが多いのですが、Node.jsはWebサーバでもなければRailsやDjangoのようなWebフレームワークでもありません。**JavaScript実行環境**です。

WindowsにPythonをインストールすると「python.exe」ができるように、Node.jsをインストールすると「node.exe」ができます。
python.exeがPythonコードを実行するアプリケーションであるように、node.exeはJavaScriptコードを実行するアプリケーション＝JavaScript実行環境です。

Node.jsではJavaScriptでOSの機能にアクセスするプログラムを組むことができます。[^6]
ブラウザ上で動作していたときはできなかった自由なファイルの読み書きやネットワーク通信などのOSの機能を扱えるのです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238976/b5b4f7d6-56c0-776e-91bf-36cdc566a8f5.png" width="331px">
結果的にPythonやRubyなどと同じようにWebアプリケーションを作成することもできますが、Node.jsはそれ以外にも様々な用途に使われています。

[^6]: 「JavaScriptでOSの機能にアクセスできる」と書きましたが、実はこれは微妙な表現で、実際にOSの機能にアクセスするにはC++でNode.jsの拡張機能を作る必要があります。ほとんどの場合、標準ライブラリやサードパーティライブラリが用意されていますが。

## Node.jsはサーバサイドのJavaScript実行環境？

Node.jsに関する記事などで、Node.jsは「**サーバサイドのJavaScript実行環境**」であると書かれているのをよく見ます。
これはNode.jsが作られた目的からこういった紹介のされ方をしています。

Node.jsは**大量の同時接続をさばけるネットワークアプリケーションの構築**を目的に設計されたJavaScript環境です。[^7]
その「JavaScriptでWebアプリケーション（Webサーバ）が作れる」という特徴から「Node.jsはサーバサイドのJavaScript実行環境である」という紹介がよくされています。

[^7]:CommonJS(ServerJS)というサーバサイドなどのブラウザ外の環境でJavaScriptを動かすための仕様が考えられており、Node.jsは初期からそれに準拠しています。

ところが現在のWeb業界ではNode.jsは**クライアントサイドJavaScriptの開発環境**としても広く利用されています。
詳しくは後述しますが、「ブラウザで実行するJavaScript」を手元のパソコンで開発するための環境にもNode.jsが使われているのです。

これはNode.jsの「パソコン(OS)上でJavaScriptを実行できる」という特性に目を付けた開発者によって、どんどんクライアントサイドJavaScriptの開発に便利なライブラリが整備されていった結果なのだと思います。

経緯はともかく、現在では「Node.jsは**サーバサイドのJavaScript実行環境**としても**クライアントサイドJavaScriptの開発環境**としても利用される」というのが実態となっています。

# npmって何者？

ちょっと話はそれますが一応**npm**のことも解説しておきます。

npmはNode.jsのパッケージ管理ツールです。
Pythonにおけるpip、Rubyにおけるgem(RubyGems)、Debianにおけるapt、MacにおけるHomebrew、Rustにおけるcargo。だいたいそんな感じです。

たまに**yarn**というのが出てきますがnpmと同じことができる物だと思って大丈夫です。

「パッケージ」というのはライブラリやフレームワークのことです。
つまりVueやReact, webpack, jQueryなどのことです。

Node.jsで使いたいライブラリがある場合、jsファイルをダウンロードしてきて`<script src="xxx.js"></script>`って書いて……とかはせずにnpmを使ってインストールします。

# Node.jsってなんでみんな使ってるの？

Node.jsによって枷を外されたJavaScriptは色々なことができるようになりました。
その用途は多種多様ですが、現在、Node.jsを使っている人の目的のほとんどは以下の３つに分類できます。（と筆者は思っています）

1. **新しい仕様のJavaScript**または**TypeScript**でクライアントサイドのプログラムを書きたい。
1. **Webアプリケーション**を作りたい。
1. **モバイル/デスクトップ用のアプリケーション**を作りたい。

## 目的1. 新しい仕様のJavaScriptまたはTypeScriptでクライアントサイドのプログラムを書きたい

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238976/48767829-fdf9-d14f-159f-d6369fa01146.png" width="450px">

新しい仕様（ES2015以降）のJavaScriptの詳細や経緯は至る所で解説されているのでここでは短めに解説します。TypeScriptについては割愛します。

JavaScriptは年々仕様が更新され、どんどん新しい機能が増えています。特に**ES2015**というバージョンではそれまでにはなかった便利な機能がたくさん仲間入りしました。
しかしJavaScriptの仕様を新しくしても既存のブラウザがその仕様に追いついてこれないという問題が発生します。
これを解決するために登場したのが「新しい仕様で書いたJavaScriptファイル」を機械的に「旧仕様（ES5）のJavaScriptファイル」に変換（トランスパイル）する手法です。

この変換を行うツール（トランスコンパイラ）の現在の主流が**Babel**であり、それを動かすための**環境**として現在よく選ばれているのが**Node.js**です。

## 目的2. Webアプリケーションを作りたい

Ruby + RailsやPython + Djangoなどで作るような**Webアプリケーション**をNode.jsで作ることも可能です。

この場合の対応する項目を表で書くと

| 実行環境 | 言語 | Webフレームワーク |
|:-:|:-:|:-:|
| Ruby | Ruby | Ruby on Railsなど |
| Python | Python | Djangoなど |
| Node.js | JavaScript | Express, Next.jsなど |

となります。

またNode.jsの特徴として「Webサーバの役割もNode.jsがこなす」という点があります。（というかNode.jsの目的を考えるとWebサーバとしての役割がメインです）
元々Node.jsは**大量の同時接続をさばけるようなネットワークアプリケーション**を構築することを目的として設計されています。
そのため、Webサーバとしての機能から一貫してNode.jsが受け持ち、効率的に処理できるようになっています。
要するに通常使われる**Apache**や**nginx**のようなWebサーバの代わりにNode.jsが直接HTTPリクエストを受け取り、処理をしてくれます。
（実際にはNode.jsのみだとWebサーバとしては少し機能が物足りないので、その前段にApacheやnginxをリバースプロキシとして置く構成が多いです。）

## 目的3. モバイル/デスクトップ用のアプリケーションを作りたい

Node.jsでは**モバイルアプリケーション**や**デスクトップアプリケーション**の開発ができます。
フレームワークはモバイルアプリケーションであれば**React Native**が、デスクトップアプリケーションであれば**Electron**が使われることが多いです。

React Nativeは使ったことがなく知識も少ないので、以下Electronのみについて説明します。悪しからず。

**Electron**は**JavaScript+HTML+CSS**を使用してデスクトップアプリケーションを作成するためのフレームワークです。

**Electron**
https://www.electronjs.org/

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238976/15e2d457-b1c9-f038-7913-3351dd761663.png" width="200px">

JavaScriptは元々ウェブサイト用の言語ですのでUIの操作に使われることが多く、UI系のライブラリやフレームワークが洗練され、成熟しています。その財産を利用してWebサイトと同じようにUIを構築できるというのは大きなメリットになります。

加えてOSの機能を扱うアプリケーションを作成できるので、ブラウザのJavaScriptに比べてできることの幅が広がります。
また、Electronでは同じコードでWindows/Mac/Linuxのアプリが作成（クロスプラットフォーム開発）できるのも特徴の一つです。

Visual Studio Code, Slack, Discord, Twitch, Skypeといったデスクトップアプリがこの**Electron**でできています。

## 目的4. その他

他にも**ウェブサイトのアセットをバンドル**（webpack）するためにNode.jsを使ったり、**SassをCSSに変換**（node-sass）するためにNode.jsを使ったり、**テストツール**（Jest）や**コード検証ツール**（ESLint）を使うためにNode.jsを使ったり、**開発用の簡易Webサーバ**（webpack-dev-server）をローカルで立てるためにNode.jsを使ったり、**静的サイトをビルド**（Gatsby）するためにNode.jsを使ったりと、Node.jsは様々な用途で使われています。

# 最後に

Node.jsは他のプログラミング言語と同じような大きな可能性をJavaScriptにもたらしてくれました。（話が複雑になるので本文中では言及を避けましたがV8 JavaScriptエンジンのおかげでもあります）

ちまたで言われるように、たしかにJavaScriptは（その出自のせいもあり）他の言語に比べて設計が甘い部分もあります。それで同じ土俵に立たれてもなあ……という意見もわかります。
ですがこんなに若い層の使用人口が多く、ライブラリなども含めて物凄い勢いで進化していき、トレンドが走馬灯のように移り変わるプログラミング言語は他にありません。

jQueryなんてもはや歴史的遺物みたいな扱いになっていますが、誕生したのはRailsやDjangoより後ですからね（比較するのも微妙ですが）。物凄いスピード感です。

この時代に生まれ、このスリリングなJavaScriptの進化の波に乗れるのはワクワクできて楽しいことだと個人的には思います。

最後に、冒頭でも言いましたが、この記事で「Node.jsってWebサーバじゃないの？ES2015で書きたいだけなのになんでインストールしなきゃいけないの？」みたいなよくある疑問が解消できたら幸いです。