やはり俺のnodeの理解は間違っている

# tl;dr

~~**やっはろー!!**~~

ノンエンジニア、ノンプログラマな友人知人がプログラミングを始めるぞい！ってなったときに、
だいたいProgateったりudemyったりドットインストールったりするものの、
そもそもノンプログラマのファーストチャレンジ用に
"こいつらなんなん？"
的なことをまとめてあるドキュメントが(自分の観測範囲に)なかったので、まとめてしまおうと思う。
nodeの話じゃないこともするかもしれない(そもそもCLIとかエディタとかがよくわからないレベルの方向けなので)けど、
なんとなくファーストトライの時に「node？npm？うぉー！！わけわからん！！」って人向けの説明記事になればいいなと思っている。
あとはなんか小中高生とかがプログラミングするときの理解の端緒になればいいかな？的な。

そして上述の目的ゆえ、正確性よりも、こういうもんだよ。こう理解しとけばいいよ。的な不正確性を**多分に**孕む。
エンジニア的には**間違った情報断固許さない。**となりがちだけど、これを読む対象はもうすでにコード書いてる人じゃなくて、
これからコード書き始める人たちで、一週間もしたらこんな記事いらなくなる人たちなので、
そういう不正確性や雑な書き方、雑な説明も一旦腹落ちさせて先に進むためのものだと割り切って許してやってもらえれば嬉しい。

あと、タイトルとか小ネタは某ガガガ文庫のラノベから引っ張ってくる所存なので、
わかる人だけわかってもらえれば嬉しいです。

**チャプタータイトルはタイトルの元ネタにしてる某ラノベ1巻の各章から取ってきたので内容とは必ずしも合っていない。すまんな。**


# 1.とにかくnode.jsは流行っている

#### Q. node.jsないしnodeと呼ばれる謎のツール。ソフト。アプリ。なんでもいいけど、アレ。アレって一体なんなの？

#### A. JavaScript(ECMA Script)って呼ばれるプログラミング言語の実行環境。

#### Q. よくわかりません。

#### A. それな。

というわけで、雑にnodeとかJSとかESとかそういう話をしようと思う。

HTML,CSS,JSの最低限をProgateとかでやった人とか、Chromeのコンソールとかで
`console.log('hello world!!');`
とかした人は、
なんかChrome(またはその他のブラウザ)で、JavaScriptというプログラミング言語が動くっぽいぞ。
というのを体験したと思う。
そこで書いた`console.log(hello world!!);`がプログラムで、
その文法がJavaScriptというやつ。
ECMA Scriptというのは、JavaScriptの標準規格。

例えるなら、
> 自動車はメーカーが違っても車種が違っても自動車だし、
> アクセル踏んだら加速するし、
> ブレーキ踏んだら減速するし、
> ハンドル切ったら曲がる

みたいな自動車ってなんだっけの決まりごとがECMA Scriptっていう規格で、
「ブラウザで動くJavaScriptはこういう風に書いたらこういう風に動くようにしてね。」
っていう決まりごとが定義されている。

そのECMA ScriptをもとにGoogleがChrome作ったり、AppleがSafari作ったり、MozillaがFirefox作ったりしている。
トヨタのアクアも日産のノートもホンダのフィットも別の車だけど、ハンドルがついてて、アクセルとブレーキがついてて、アクセルが右、ブレーキが左にあるのは一緒。みたいな感じで、
ECMA Script(のきまりごと)を守って作ってあれば基本的には**同じようなJavaScriptが使える**。

けどアクアとノートとフィットが違うように、各ブラウザによって、必ずしも全部が全部同じではなかったりもするのがJavaScriptなので、
ECMA Scriptの決まりごと以外の部分ではそれぞれ違う機能があったり、
ECMA Scriptの決まりごとの、どのバージョンまで対応しているかとかもブラウザによって違ったりする。

そして、ブラウザの話に戻ると、ブラウザはそもそもウェブサイトを見るためのソフト(今時はアプリか？)なので、
JavaScriptを動かすだけじゃなくて、HTMLを表示させたり、それをCSSで装飾したりする機能など、たくさんの機能がついている。

そのブラウザのなかでも、GoogleのChromeというブラウザに使われているJavaScriptを動かす部分がV8というソフトで、
そのV8をブラウザから引っこ抜いてきて、ちょこちょこ機能を足すことで、
**ChromeというブラウザのJavaScriptを動かす部分だけを取り出したアプリ**がnode.jsだと理解しておけば、
これからプログラミングを勉強する人たちにとっては十分正確な理解だと思う。
JavaScriptを動かす部分を取り出してきたものなので、できることは**JavaScriptを動かすだけ**なので、
node.js(またはnode)は**JavaScriptの実行環境**ということになる。

node.jsはJavaScriptの実行環境なので、例えば

<img width="1677" alt="Screen Shot 2019-02-26 at 19.19.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/60407/9b112683-e7c8-e9d1-199f-41ac0b75f5b1.png">

このHTMLをChromeで開いた時に実行される

```javascript:index.js
console.log('hello world!!');
```

がこんな感じでブラウザで実行されるように

<img width="1116" alt="Screen Shot 2019-02-26 at 19.22.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/60407/a3c5902f-de08-81a4-8230-f32a64f6a561.png">

nodeで実行しても同じように"hello world!!"と表示される。

<img width="580" alt="Screen Shot 2019-02-26 at 19.25.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/60407/91987e32-56c8-d677-1548-285e4058c9d9.png">


### まとめ：node.js(とかnodeって言われてるやつ)は、ブラウザからJavaScriptを動かす機能だけを引っこ抜いてきてたやつ。


# 2.いつでもnpmは付属している

#### Q. nodeが"ブラウザからJavaScriptを動かす部分だけを抜き取ってきたやつ"だということを上で説明したけれど、それ入れるとくっついてくるnpmってなんなんですか。

#### A. node package manager のことです！

#### Q. nodeはともかく"package manager"ってなんですか。

#### A. スマートフォンのAppStoreみたいなもんだと思ってくれ！


つまり、npmはnodeで動くアプリのストアみたいなもの。npmからいろんなソフト(アプリ)をインストールしたりアンインストールしたりできる。

と、言い切ってしまうと誤解が爆発的に産まれそうなので、もっと詳しく解説してみる。

- パッケージマネージャーって何？
- npmは何ができるの？

の2点についてざっくり説明するので、npmがなんなのかふわっとわかっていただければと思います！！

#### パッケージマネージャーって何？

パッケージマネージャーは、各種ソフトウェアのインストール、アンインストール、依存関係管理を行うツール。

#### 依存関係管理？

依存関係とは、ソフトAをインストールする際、ソフトAはソフトBがないと動かない。という時に**"AはBに依存している"**(Bがないと動かない)という関係。

つまり依存関係管理をしてくれるというのは、
**「ソフトAをインストールしてね！」**
と言うコマンドを実行した時に、
**「AはB,C,Dに依存しているのでB,C,Dもインストールしますね！」**
というのを自動でやってくれたり、Aのバージョンアップの時に、
**「B,C,DだけじゃなくてEも追加しないと！」**とか、**「Bもバージョンアップしなきゃ！」**
などを勝手に管理して、ダウンロードしてインストールしてくれる仕組みのこと。

また、逆の操作に対しても管理を行ってくれるため、Aをアンインストールすると、
一緒にB,C,Dもアンインストールしてくれたり、Bを削除しようとすると、
**「AがBに依存しているのでBを削除するとAが動かなくなりますが削除しますか？」**と言ったことを聞いてくれるなどして、
ソフトウェア同士の**依存関係の管理をパッケージマネージャーがしておいてくれる**というもの。

なので、例えば`npm install react`などでreactをインストールすると、reactが依存している数多くのパッケージ(ソフト)が`node_modules`というところに自動でインストールされる。

もちろん、パッケージマネージャーで管理されるものはいろんなプログラムなので、コマンドラインで実行するコマンドのプログラムをインストールすることもできる。

そのため、`npm install create-react-app`とすると、`create-react-app`というコマンドがインストールされて、
`create-react-app {appname}`とコマンドを打つと、`appname`という名前でreactのアプリの雛形が作られる。というようなこともできる。
この時も、`create-react-app`というプログラムを実行するために必要な依存関係にあるソフト群は自動でインストールされて、npmが管理してくれるため、create-react-appを使う時に、create-react-appが依存しているプログラムを意識したり、手動でインストールすることなく利用することができる。

#### npmは何ができるの？

上述のようなパッケージ管理に加えて、npmでは`npm script`というものを書くことで、コマンドを自作したりできる。
自作するコマンドは`package.json`というファイルに記述することで、npmがpackage.jsonを読み込んで、コマンドを実行できるようにしてくれる。

また、`create-react-app`のようなコマンドに関しては、`npx`というコマンドを使うことで、コンピューターにインストールすることなくインターネット上にあるコマンドを実行することができる。

そのため、`create-react-app`がインストールされていなくても、

![Screen Shot 2019-02-26 at 21.09.22.png](https://qiita-image-store.s3.amazonaws.com/0/60407/665af3b7-a9d1-d074-72cc-f06550246ace.png)

このようにnpxコマンドを実行すると

![Screen Shot 2019-02-26 at 21.09.45.png](https://qiita-image-store.s3.amazonaws.com/0/60407/af719115-c0d5-04b3-390c-1378403a2369.png)

こう言った感じで`package.json`が作られ、

![Screen Shot 2019-02-26 at 21.10.36.png](https://qiita-image-store.s3.amazonaws.com/0/60407/4a018ac3-c8ae-39c8-f1a9-713c1a0aa41d.png)

reactのアプリケーションに必要な依存関係パッケージが`node_modules`に展開されて

![Screen Shot 2019-02-26 at 21.11.33.png](https://qiita-image-store.s3.amazonaws.com/0/60407/eb433046-c4e3-50e7-0895-9e350c827c76.png)

必要なパッケージと、初期状態の雛形ファイルが自動的に作られる。

この時、`package.json`の`"scripts"`以下に`"start":"react-scripts start"`というコマンドが作られるので、
ここで、`npm start`を実行すると、実際には`node ./node_modules/react-scripts/bin/react-scripts.js start`が実行される。

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.amazonaws.com/0/60407/a12e6d5e-d8e5-1fcf-8281-77fe22eab46e.gif)

といった具合に、`$ npm {自分で作ったコマンドの名前}`で`$ node {実行するJavaScriptのスクリプト}`が実行されるようにできるというのがパッケージ管理以外のnpmにできることになる。

### まとめ：npmはnodeで実行できるプログラム各種の依存関係を管理したり、インストールしたりアンインストールしたり、あとpackage.jsonに自作コマンドを書くことでnpmのコマンドを作ったりできるパッケージ管理ツール


# 3.つねにnodeとnpmは使われている

ここまでで、**nodeはJavaScriptを実行する部分をブラウザから分離したもの**ということと**npmはnodeの各種パッケージを管理したりスクリプト作ったりするもの**ということを説明したけれど、

#### Q.じゃあそれがあるとプログラムを書く時に何が嬉しいの？

という疑問が出てくると思う。

なので、プログラムを作る時にnodeとnpmがあると何が嬉しくて、nodeとnpmが何に使われているのかを簡単に説明しようと思う。

#### nodeがあると何が嬉しいの?

nodeがあるとできること、それはブラウザの外側でJavaScriptが動かせること。
nodeはブラウザから取り出したJavaScriptの実行環境に、I/O(入出力)の仕組みを追加してあるので、
コンピュータの中にあるファイルを取り込んで、JavaScriptで書いたプログラムを使って処理を行って、
実行結果を出力することができる。

今まではブラウザの中でしか動かすことができず、できることが限られていたJavaScriptというプログラミング言語で、
ブラウザ関係なく動作するプログラムが作れることで、
コマンドラインツールや汎用性のあるプログラムなど、必ずしもブラウザというUIやユーザーによる操作を必要としないプログラムが書けて、実行できるようになったのがすごく大きい。

例えば、nodeで実行できるプログラムであれば、インターネットに繋がっていなくても、通信を必要としないプログラムが書けたり、
通信を必要とするけど操作を必要としない常駐型のプログラムを作ることができるようになる。

node.jsがサーバーサイドJavaScriptと言われるのは、ブラウザ上でのユーザー操作に対して反応するプログラムだけでなく、
サーバー(コンピューター)上で常時実行され続けるプログラムをJavaScriptで書くことができることで、サーバーサイドとクライアントサイドの開発言語を統一することができることが大きなメリットであり、
JavaScriptが基本的にはHTML,CSSと合わせて学ばれる"難しくない"プログラミング言語であるために、ウェブアプリケーション開発において、UI開発の必須項目であるJavaScriptさえある程度できれば、同じ言語でサーバーサイドが開発できることが大きい。

#### npmがあると何が嬉しいの？

パッケージマネージャがあることで依存関係の管理をしなくていい、
独自のコマンドを作れることで長いコマンドを短いコマンドにできる。
というすでにあげたメリットだけでなく、
パッケージ管理システムとインターネット、中央リポジトリを使うことで、他人が今までに作ってきたプログラム資産を自分のソフトウェア開発に使用できるというのがすごく嬉しい。
こういう機能が追加したいな。とか、こういう機能が欲しいな。という時に、0から自分で作ることなく既に誰かが作ってあるものを使えることで、
時間はすごい短縮できるし、ソフトウェアの品質は向上させられるし、自分が作りたいものを作ることに集中できる。
車を作る時に、タイヤとかホイールとか鉄板から自分で全部作っていると大変なので、
タイヤメーカーが作ったタイヤを使う、ホイールメーカーが作ったホイールを使う、鉄鋼メーカーが作った鉄板を使う。
それと同じようにソフトウェアを作る時に(ネットに繋がっていれば)外部から既に他の誰かが作ってあるものを取り込んで使うことができるのが、
エンジニアとしては嬉しいというのがある。


### まとめ：nodeがあると、サーバーサイドとクライアントサイドのプログラムが両方JavaScriptで書けて、npmがあると自分が過去に作ったプログラムや他人が作ったプログラムを利用できるので新しく作るところに集中できて良い。


# あとがき

雑かつ後半とか体力が尽きてだいぶ適当な感じになってしまったが、
nodeってなんだ！npmってなんだ！ウォォオオオーン!!という人たちがこれを読んで少しでもわかった気になってもらえたらいいなと思います。

エンジニア向け解説はもっと強くてJS詳しくて強い、つよつよエンジニアが書いたほうが正確性が高まって良いと思うので、
僕は右も左もわかりません！という方々が、どっちが右でどっちが左かを判別できるようになる程度の情報を提供できればなと思います。


p.s.

渡航先生、やはり俺の青春ラブコメはまちがっている14巻発売日決定&14巻で本編完結おめでとうございます。
発売日を心待ちにしてます。
あと14巻以降も短、中編集などで八幡や他のキャラ達の姿が楽しめることを期待してます。