はじめに
- 各プログラミング言語にはたいていパッケージを管理するしくみがあります
- RubyのgemだったりJavaのGradleやMavenだったり
- JavaScriptではnpmを使ってパッケージを管理します
- 新しいプログラミング言語をさわるときにパッケージ管理の仕組みを使いこなせることは、初心者から一歩踏み出せたと言っていいのではないかと思います
- この記事では初心者向けにnpm周りの使い方を紹介します
前提
- npmコマンドはnodeをインストールするとセットでついてきます
- なので事前にnodeをインストールしておいて下さい
- https://nodejs.org/ja/
依存パッケージの管理
- npmの仕組みでは依存するパッケージの情報を
package.json
で管理します - 例えばちょうど手元にあったReactアプリの
package.json
は以下のようになっています
package.json
{
"name": "react-sample",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.2",
"react-dom": "^16.8.2"
},
"devDependencies": {
"eslint": "^5.13.0",
"eslint-plugin-react": "^7.12.4"
}
}
-
dependencies
とdevDependencies
に依存パッケージが記述されています-
dependencies
はアプリ本体に取り込まれる依存パッケージ -
devDependencies
は開発時のみに利用する依存パッケージ
-
- この
package.json
をカレントディレクトリにおいた状態で以下のコマンドを実行すると依存パッケージがインストールされます-
node_modules
ディレクトリが自動的に作成されそこにインストールされる
-
npm install
# もしくは
npm i
- このように
package.json
に依存パッケージを記述しておくことで、パッケージ本体をリポジトリ管理せずとも誰でも同じ状態を再現できるというわけですね
依存パッケージの追加
- 続いて新しく依存パッケージを追加するケースについてですが、直接
package.json
を編集する必要はありません - 先程の
package.json
の状態で、新たにreact-router
というパッケージを使いたくなったとします - その場合以下のコマンドを実行します
npm i react-router
- コマンドを実行すると
node_modules
にパッケージがインストールされ、さらにpackage.json
のdependencies
に自動で追記されます
package.json
{
"name": "react-sample",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.2",
"react-dom": "^16.8.2",
"react-router": "^5.0.0"
},
"devDependencies": {
"eslint": "^5.13.0",
"eslint-plugin-react": "^7.12.4"
}
}
- さらに
eslint-plugin-react-hooks
というパッケージを追加したくなったとします - このパッケージは開発時しか使わないため
devDependencies
に追加したいです- ESLint・・JavaScriptの構文チェックツール
- その場合以下のコマンドを実行します
npm i -D eslint-plugin-react-hooks
# もしくは
npm i --save-dev eslint-plugin-react-hooks
- 実行すると以下のように自動で追記されます
package.json
{
"name": "react-sample",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.2",
"react-dom": "^16.8.2",
"react-router": "^5.0.0"
},
"devDependencies": {
"eslint": "^5.13.0",
"eslint-plugin-react": "^7.12.4",
"eslint-plugin-react-hooks": "^1.6.0"
}
}
ローカルインストールとグローバルインストール
- npmではパッケージのインストール先をローカルとグローバルを選択することができます
- これまで紹介してきたものは全てローカルにインストールしています
- グローバルにインストールする場合以下のようなコマンドを実行します
npm i -g create-react-app
# もしくは
npm i --global create-react-app
- パッケージはコマンドを実行したディレクトリではなくグローバルな場所にインストールされます
- インストール先は
npm root -g
で確認できる
- インストール先は
- グローバルインストールの使い所としては、アプリの雛形生成ツールなど開発中に何度も使わないようなものが向いているでしょう
- 一度しか使わない => リポジトリで依存を管理する必要がない
- 先程インストールした
create-react-app
はReactアプリの雛形を生成するためのコマンドラインツールです - 試しに以下のコマンドを実行するとReactアプリのベースが一式生成されます
create-react-app react-sample
- また、グローバルインストールと似た役割として
npx
というコマンドがあるので紹介しておきます - 上記の手順だとグローバルにインストールしてコマンドを実行して、と面倒です
- さらに、グローバルにインストールしたパッケージのアップデートを怠っていると、意図せぬ古いパッケージを使ってしまうかもしれません
-
npx
を使うとその場でパッケージをインストールしコマンドを実行するということができます
npx create-react-app react-sample-2
- このコマンドは
create-react-app
をグローバルにインストールせずとも実行することができます - 自分の場合最近はグローバルインストールを使う機会はあまりなく
npx
を使うことがほとんどです
npm scripts
- パッケージ管理の話からは少しそれますが
npm scripts
についてふれておきます -
npm scripts
とはpackage.json
の中にscriptを定義しておき、それを実行できるというものです - 先程登場した
create-react-app
で生成された雛形を例に見てみます- 雛形を生成していない方は
npx create-react-app react-sample
を実行して下さい
- 雛形を生成していない方は
package.json(一部抜粋)
{
"name": "react-sample",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-scripts": "2.1.8"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
}
- 雛形の中にある
package.json
を見るとscripts
に4つの定義があります - これらは
npm run start
やnpm run build
のようにして実行することができます-
npm start
とnpm test
だけはrunを省略できます
-
- 試しに以下のようにlsコマンドの定義を追加してみましょう(実際こんなコマンドをセットすることはありませんが)
package.json(一部抜粋)
{
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lsa": "ls -a"
}
}
- 以下のコマンドを実行すると
ls -a
が実行されることが分かると思います
npm run lsa
> react-sample@0.1.0 lsa /Users/ozaki/Desktop/react-sample
> ls -a
. .git README.md package.json src
.. .gitignore node_modules public
- このようにして
npm scripts
を使うとnpmコマンドで任意のスクリプトを実行することができます - ただ、これくらいなら直接実行しても変わらないのでは?と思うかもしれません
- 私は実際に開発していく中で以下のような恩恵を感じています
-
npm start
で起動、npm run build
でビルドといった共通認識があるため、他人のコードをさわる場合でも起動やビルドの方法がすぐに分かる - 定義するコマンドは状況によりオプションが追加されたり引数が増えたりすることがよくあるので
npm scripts
でラップされていることで意識しなくて良い - CIで実行する時も簡単なコマンドの設定でよくなり、オプションなどが変わっても実行するコマンドは変えなくて良い
-
よくあるディレクトリ構成
- 最後にこれまたパッケージとは関係ありませんが、初心者がJavaScriptで作られたリポジトリを読む際の助けになればと思います
- ディレクトリ構造に慣れていないとgithubのページを開いて以下のようなファイルが並んでいると、どこを見ればいいのか分からないと感じることがあると思います
.
├── .env
├── .eslintrc.js
├── .git
├── .gitignore
├── .prettierrc
├── .storybook
├── .stylelintrc.js
├── README.md
├── build
├── jsconfig.json
├── node_modules
├── package.json
├── public
├── src
├── tsconfig.json
├── tsconfig.paths.json
└── yarn.lock
- トップレベルで並んでいる中で見るべきは
src
とpackage.json
とREADME.md
くらいと思って大丈夫です-
README.md
にリポジトリの説明を書いてくれている場合はまずはそこから読むとよいでしょう -
src
はコードの本体が入っているディレクトリなのでここがメインになります -
package.json
はこれまで紹介したように依存ライブラリなどの情報が書かれています
-
- さらに
src
の中を読むコツとしてindex.js
というファイルを見つけたらまずそれを開くと良いです-
index.js
は暗黙的にエントリーポイント的な役割であることが多いのでそこからたどると読みやすいことが多いです
-
npmとyarn
- 最後にと言いましたがもう一つ
- いろいろな記事やリポジトリを見ると
npm
的な立ち位置でyarn
というものも目にするかと思います -
yarn
はnpm
とほとんど同じなので慣れないうちはyarn
と書いてあってもnpm
と置き換えて読むとよいです
まとめ
- 今まで具体的なフレームワークやライブラリの記事をいくつも書いてきましたが、初心者にとってはnpm周りが実はとっつきにくいのかも?と思いいろいろと書いてみました
- これからJavaScriptを始めるエンジニアのお役に立てれば幸いです