npmとpackage.jsonが良く分からなかったので独自目線で纏めた

# はじめに

どうも、またまた私です。
今度はnpmを深掘りすることになりました。
例の如く手探りです。

参考にしたもの

[npmとpackage.json使い方 - Kokudoriing](http://kokudori.hatenablog.com/entry/2013/04/04/025521)
[npmでnode.jsのpackageを管理する]()

# そもそもnpmってなんだよ
Node Package Manager.
要約するとNode.js用のパッケージ管理ツールです。
詳しくは[ここ](https://www.npmjs.com/)みてください。

# npm導入方法
色々ありますが今回はnvm導入で出来る方法をお伝え。
## nvmってなんだよ
Node Version Manager.
Node.js用バージョン管理ツールです。
gitとかとは違ってソースのバージョン管理ではなく、
Node.jsのバージョン（v8.10.0とかv9.4.0とか）をコントロールするやつです。
やっぱり詳しくは[こっち](https://github.com/creationix/nvm)みてください。
## nvm導入方法
```
$ git clone git://github.com/creationix/nvm.git ~/.nvm
```
そもそもgitが入ってない人はyumでinstallしてください。
## npm導入手順は？
nvmを導入すると、「node」コマンドと「npm」コマンドが使えるようになっています。

```
$ node -v
v8.10.0

$ npm -v
5.6.0
```

# npmコマンド
主にオプションとかで悩んだので。。
## install
文字通り、パッケージインストール用コマンド。

```
$ npm install mysql
```
上記を打つとmysqlパッケージがインストールできます。

```:例
$ mkdir hoge
$ cd hoge
hoge]$ ls
hoge]$ npm install mysql
npm WARN saveError ENOENT: no such file or directory, open '/home/username/hoge/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/home/username/hoge/package.json'
npm WARN hoge No description
npm WARN hoge No repository field.
npm WARN hoge No README data
npm WARN hoge No license field.

+ mysql@2.15.0
added 11 packages in 0.769s
hoge]$ ls
node_modules  package-lock.json
hoge]$ ls node_modules/
bignumber.js  core-util-is  inherits  isarray  mysql  process-nextick-args  readable-stream  safe-buffer  sqlstring  string_decoder  util-deprecate
```
hogeフォルダを作って、その中にmysqlパッケージを含む11パッケージが追加されたことが分かります。
mysqlパッケージ以外の10パッケージは、mysqlに必要なので自動でインストールされたものです。

## uninstall
文字通り、パッケージをアンインストールします。

```:例
hoge]$ npm uninstall mysql
npm WARN saveError ENOENT: no such file or directory, open '/home/username/hoge/package.json'
npm WARN enoent ENOENT: no such file or directory, open '/home/username/hoge/package.json'
npm WARN hoge No description
npm WARN hoge No repository field.
npm WARN hoge No README data
npm WARN hoge No license field.

removed 1 package in 0.39s

hoge]$ ls node_modules/
bignumber.js  core-util-is  inherits  isarray  process-nextick-args  readable-stream  safe-buffer  sqlstring  string_decoder  util-deprecate
```
mysqlパッケージが消えていることが分かりますね。
実際はプログラムを用意しておいてrequireするのがベターです。

## list
インストールしているパッケージ一覧を出してくれます。

```:例
hoge]$ npm list
/home/username/hoge
├── bignumber.js@4.0.4
├─┬ readable-stream@2.3.3
│ ├── core-util-is@1.0.2
│ ├── inherits@2.0.3
│ ├── isarray@1.0.0
│ ├── process-nextick-args@1.0.7
│ ├── safe-buffer@5.1.1
│ ├─┬ string_decoder@1.0.3
│ │ └── safe-buffer@5.1.1 deduped
│ └── util-deprecate@1.0.2
└── sqlstring@2.3.0
```
「npm list -g」と実行すると、グローバルフォルダを表示してくれます。

```:グローバルな例
$ npm list -g
/home/username/.nvm/versions/node/v8.10.0/lib
├─┬ mysql@2.15.0
│ ├── bignumber.js@4.0.4
│ ├─┬ readable-stream@2.3.3
│ │ ├── core-util-is@1.0.2
│ │ ├── inherits@2.0.3
│ │ ├── isarray@1.0.0
│ │ ├── process-nextick-args@1.0.7
│ │ ├── safe-buffer@5.1.1 deduped
│ │ ├─┬ string_decoder@1.0.3
│ │ │ └── safe-buffer@5.1.1 deduped
│ │ └── util-deprecate@1.0.2
│ ├── safe-buffer@5.1.1
│ └── sqlstring@2.3.0
└─┬ npm@5.6.0
（長いので以下略）
```

## version
npmのバージョンを確認するコマンドです。

```:例
$ npm version
{ npm: '5.6.0',
  ares: '1.10.1-DEV',
  cldr: '32.0',
  http_parser: '2.7.0',
  icu: '60.1',
  modules: '57',
  nghttp2: '1.25.0',
  node: '8.10.0',
  openssl: '1.0.2n',
  tz: '2017c',
  unicode: '10.0',
  uv: '1.19.1',
  v8: '6.2.414.50',
  zlib: '1.2.11' }
```

## -gオプション
グローバルという意味らしいです。
らしいというのはどうにも自信が無いもので。。

```:例
$ npm install -g mysql
+ mysql@2.15.0
added 11 packages in 1.778s

$ ls /home/username/.nvm/versions/node/v8.10.0/lib/node_modules/
mysql  npm
```

どこにインストールされるかが謎いですね。

## config list
npmのコンフィグなのですが、 ~~どこがグローバルなのかなどが書かれています。~~
深堀したら、これはあくまで今いるフォルダがどこかとか、ホームどこかとか、実行バイナリどこかとか書いてあるだけですね。

```:例
$ npm config list
; cli configs
metrics-registry = "https://registry.npmjs.org/"
scope = ""
user-agent = "npm/5.6.0 node/v8.10.0 linux x64"

; node bin location = /home/username/.nvm/versions/node/v8.10.0/bin/node
; cwd = /home/username
; HOME = /home/username
; "npm config ls -l" to show all defaults.
```

~~今回の場合、nvmインストール＆デフォルト設定したバージョンフォルダ、
「/home/username/.nvm/versions/node/v8.10.0/」
がグローバルっぽいですね。~~
「node bin location」がnodeコマンドで実行される実際のバイナリっぽいです。
（違ったらコメントで違うって指摘してください！）

ちなみにグローバルインストールの逆がローカルインストールで、
「-g」オプションをつけないだけです。

## -saveオプション
package.jsonなるものにインストールするパッケージの名前とバージョンを記録できるオプションです。
package.jsonは自前で用意しなければなりませんが、
「npm init」を実行すればお手軽に用意できます。

```:package.jsonが無い場合
$ npm install mysql -save 
npm WARN saveError ENOENT: no such file or directory, open '/home/username/piyo/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/home/username/piyo/package.json'
npm WARN piyo No description
npm WARN piyo No repository field.
npm WARN piyo No README data
npm WARN piyo No license field.

+ mysql@2.15.0
added 11 packages in 0.82s
```
こんな感じで、インストールは出来ますが「package.jsonがねーよ」って怒られます。

```:package.jsonを用意した場合
$ npm install mysql -save
npm WARN fuga@1.0.0 No repository field.

+ mysql@2.15.0
added 11 packages in 0.859s
```

# package.jsonってなんだよ
話が前後しましたが、package.jsonはnpmのパッケージ情報を管理するjsonファイルです。
生成には「npm init」でいろいろ聞かれて結果的に完了します。ざっくり。

```:npminit

fuga]$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (fuga) 
version: (1.0.0) 
description: fuga is hoge piyo.
entry point: (node_require_mysql.js) main.js
test command: 
git repository: 
keywords: 'hoge','piyo'
author: 
license: (ISC) 
About to write to /home/username/fuga/package.json:

{
  "name": "fuga",
  "version": "1.0.0",
  "description": "fuga is hoge piyo.",
  "main": "main.js",
  "dependencies": {
    "mysql": "^2.15.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "'hoge'",
    "'piyo'"
  ],
  "author": "",
  "license": "ISC"
}


Is this ok? (yes)
```

出来上がったのが以下。

```json:package.json
{
  "name": "fuga",
  "version": "1.0.0",
  "description": "fuga is hoge piyo.",
  "main": "main.js",
  "dependencies": {
    "mysql": "^2.15.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "'hoge'",
    "'piyo'"
  ],
  "author": "",
  "license": "ISC"
}
```

## package-lock.jsonってあるんだけど
package.jsonを生成しなかった場合に自動生成されるjsonファイルのようです。
詳細は下記を。
[package-lock.jsonの各プロパティについて調べてみました。](https://qiita.com/shisama/items/bb816522a8468c3a367e)


# おわりに
まだまだ謎だらけです。
何かご存知の情報があればコメントにていただけますと幸いです。
よろしくお願いいたします。