Help us understand the problem. What is going on with this article?

初学者向けpackage.jsonハンズオン

これは Node.js Advent Calendar 2019 の8日目の記事です。
昨日は @yuta-ron さんによる スクレイピング & サーバレスAPIでNode.jsの雰囲気を体験してみる でした。

初学者向けpackage.jsonハンズオン

Node.js初学者向けにpackage.jsonハンズオンを実施しましたので、その時に作ったハンズオン資料を公開します。

npmコマンドやpackage.jsonに慣れることが目的のハンズオンの資料ですので、Node.jsとは何か?といった説明はしません。ご了承ください。

文章の手順通りに進めていけば、npmコマンドやpackage.json編集が体験できます!

事前準備

Node.jsのインストール

事前にNode.jsのインストールをお願いします。(すでにNode.jsがインストール済の方は飛ばしてください。)

Windowsの場合

Windowsの方は、こちらの記事をご参照ください。Chocolatey > Nodist > Node.jsの順番でインストールします。

Windowsで、Chocolateyとnodistで、バージョン切り替え可能なNode.jsの環境を構築する

Macの場合

Macの方は、こちらの記事をご参照ください。Homebrew > nodebrew > Node.jsの順番でインストールします。

macOS に Homebrew で nodebrew をインストールして Node.js を使う

package.jsonハンズオン

それではハンズオンを始めます。

作業ディレクトリを作ろう

お好きな場所に作業ディレクトリを作りましょう。

Windowsの場合

今回のハンズオンでは以下のディレクトリを 作業ディレクトリ と呼ぶことにします。

D:\JavaScript\package-json-handson

Macの場合

今回のハンズオンでは以下のディレクトリを 作業ディレクトリ と呼ぶことにします。

~/JavaScript/package-json-handson

WindowsならGit Bashを使おう

Web界隈ではLinuxサーバーが主流ですので、DOSコマンドよりもLinuxコマンドが使える環境の方が、何かと都合がよいと思います。

Git for Windows をインストールしていれば、 Git Bash というターミナルがインストールされており、そこでLinuxコマンドが使えます。

今回のハンズオンでは、Git Bashを使う前提で進めます。

カレントディレクトリを作業ディレクトリにしてください。

作業ディレクトリに移動

カレントディレクトリを作業ディレクトリにしてください。

以下のコマンドを実行してみましょう。

# Windows
cd /d/JavaScript/package-json-handson

# Mac
cd ~/JavaScript/package-json-handson

npmコマンドでpackage.jsonを生成してみる

作業ディレクトリにnpmパッケージを作っていきます。

以下のコマンドを実行して、npmパッケージを初期化してみましょう。

# 作業ディレクトリをnpmで初期化
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: (package-json-handson)

最後の行で上記のように表示されると思います。

ここでは、これから作るnpmパッケージの名前をどうするのか質問されています。デフォルトでディレクトリ名が表示されていますので、そのまま何も入力せずEnterしてください。

そうすると、以下のように次の質問が表示されます。

version: (1.0.0)

ここでは、npmパッケージのバージョンをどうするのか聞かれています。

デフォルトは 1.0.0 となっていますが、ここでは、 0.1.0 を入力してください。(理由は後で説明します。)

そうすると、以下のように次の質問が表示されます。

description: 

ここでは、npmパッケージの説明文の入力を求められています。

とりあえず handson と入力してください。(後から変更できますので、真剣に悩まなくても大丈夫です。)

そうすると、以下のように次々と質問されます。

entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)

とりあえず、何も入力せず、すべてEnterしてください。

そうすると、最後に以下の質問が表示されます。

Is this OK? (yes)

ここでも、何も入力せずEnterしてください。(yes の意味になります。)

これで、npmパッケージの初期化が完了しました!

package.json が作業ディレクトリに生成されていますので、内容を確認してみましょう!

# package.json の中身を表示する
cat package.json

以下のようにJSON形式のデータが表示されれば成功です!

{
  "name": "package-json-handson",
  "version": "0.1.0",
  "description": "handson",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

自分が入力してきた値が格納されていることがわかると思います。

npm-scriptをつくってみる

テキストエディター(こだわりがなければVS Codeがオススメです)で package.json を開いてください。

scripts という項目があります。この部分には、独自のスクリプトを登録できます。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "show-files": "ls -al"
  },

試しに、上記のように show-files の行を追加してみてください。

package.json を保存したら、以下のコマンドを実行してみましょう。

npm run show-files

そうすると、 ls -al が実行されます!

Linuxコマンドが動くターミナル(Git Bash等)なら、ファイル一覧が表示されます!

もし、コマンドプロンプトを使っている場合は、Linuxコマンドが動かないので、エラーが表示されます。

この独自のスクリプトのことを npm-script と呼びます!覚えておきましょう。

app.jsをつくってみる

作業ディレクトリに app.js というファイルを作ってください。

中身に以下の一行を書いて保存してください。

console.log("Hello World!");

以下のコマンドを実行してみてください。

node app.js

以下が表示されれば成功です。

Hello World!

おまけ: index.jsapp.js の使い分け

たったいま、 app.js を作りましたが、先ほどの package.json には index.js という記述がありました。

これらは何が違うのでしょうか?

実は、今作っているnpmパッケージが

  • アプリケーションなら app.js に、最初に実行するコードを書く。
  • ライブラリなら index.js に、最初に実行するコードを書く。

という慣習があります。(諸説あります)

Start Scriptを作ってみる

今度は、 package.jsonscriptsstart の行を追加してください。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "show-files": "ls -al",
    "start": "node app.js"
  },

以下のコマンドを実行してみてください。

npm run start

以下が表示されれば成功です。

Hello World!

次に、以下のコマンドを実行してみてください。

npm start

こちらのコマンドでも同じ結果になりました!以下が表示されれば成功です。

Hello World!

実は npm start というのは npm run start のエイリアスになっています。

メインに実行する処理はnpm-scriptの start に登録しましょう。

moment をインストールしてみる

まず、以下のコマンドを実行してみましょう。

# moment をインストール
npm install moment

作業ディレクトリに node_modules フォルダーが生成されました。

このフォルダーを開くと、 moment フォルダーが見つかります。

加えて、 package.json に以下の行が自動で追加されます。

  "dependencies": {
    "moment": "^2.24.0"
  }

バージョン番号が勝手に追加されましたね。このバージョンの先頭についている ^ に関しては、あとで説明します。

次に、app.js を以下のように書き換えてください。

// ライブラリを読み込む
const moment = require("moment");

// 現在時刻を取得する
const now = moment().format("YYYY-MM-DD HH:mm:ssZ");

// 現在時刻を表示する
console.log(now);

以下のコマンドを実行してみてください。

npm start

すると、以下のように現在時刻が表示されます。

2019-11-20 18:51:02+09:00

moment は日付に関する処理を扱った歴史のあるライブラリで、Node.js界隈で広く使われています。

歴史がある分、多機能でファイルサイズが大きいという欠点もあります。

dayjs のような軽量なライブラリも台頭してきていますので、必要に応じて使い分けていきましょう。

moment をアンインストールしてみる

せっかく入れた moment ですが、今度はアンインストールしてみます。

以下のコマンドを実行してみましょう。

# moment を案インストール
npm uninstall moment

node_modules フォルダーから moment フォルダーが削除されました。

同時に package.json からも消えました。

  "dependencies": {}

以下のコマンドを実行してみてください。

npm start

moment がなくなったので、以下のようにエラーが表示されるはずです。

internal/modules/cjs/loader.js:626
    throw err;
    ^

Error: Cannot find module 'moment'

package.json から moment をインストールしてみる

今度は、 package.json に以下の行を手動で追加してみましょう。

  "dependencies": {
    "moment": "^2.24.0"
  }

以下のコマンドを実行してみます。

# dependencies に書かれたライブラリをインストール
npm install

実は、これでも moment がインストールされます!

以下のコマンドを実行してみてください。

npm start

以下のように現在時刻が表示されれば成功です。

2019-11-20 18:51:02+09:00

dependencies に色々インストールしてみる

試しに色々インストールしてみましょう

# dependencies にインストール
npm install express
npm install cors

package.jsondependencies にアルファベット順で追加されていくのがわかると思います。

  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "moment": "^2.24.0"
  }

eslintdev-dependencies にインストールしてみる

ESLintというライブラリがあります。
これを使うと、JavaScriptの文法を検査し、問題があればVS Code上に警告を表示してくれたりします。

このライブラリは開発環境では使いますが、サーバー環境では使いません。

こういったライブラリを扱うのが devDependencies です。

以下のコマンドを実行してみてください。

# devDependencies にインストール
npm install --save-dev eslint
npm install --save-dev eslint-config-airbnb-base

package.jsondependencies とは別に devDependencies という項目が増えたと思います。

  "devDependencies": {
    "eslint": "^5.16.0",
    "eslint-config-airbnb-base": "^13.1.0",
  },

dependencies のみインストールする

サーバー環境等で、 devDependencies をインストールせずに、 dependencies のみをインストールしたいということがあります。

以下のコマンドを使えば可能です。

# dependencies のみインストール
npm install --production

セマンティックバージョニングについて

いつのまにか package-lock.json というものが生成されています。これは何なのでしょうか?

これが何なんか説明する前に、セマンティックバージョンについて説明します。

Node.js界隈では セマンティックバージョニング X.Y.Z という考え方が浸透しています。

おおざっぱに説明すると、以下のようにバージョン番号を付けます。

  • X : メジャーバージョン : 互換性がなくなったら上昇
  • Y : マイナーバージョン : 互換性を保ちつつ、機能を追加したら上昇
  • Z : パッチバージョン : バグ修正したら上昇

それでは、一番最初の開発版のバージョンはどうするのか?というと、セマンティックバージョニングによれば、 0.1.0 から始めるのが良いとされています。

このハンズオンの最初に、バージョン番号を 0.1.0 にしたのも、それが理由です。

バージョンの範囲指定について

package.json でのバージョンの範囲指定についても説明します。

先ほど ^ という記号が登場しました。以下のような特徴があります。

  • ~X.Y.Z : パッチバージョン Z の上昇まで許容します。
  • ^X.Y.Z : マイナーバージョン Y の上昇まで許容します。

たとえば、以下の表のように、複数のバージョンを持つライブラリがあるとします。

バージョン 2.x 2.1.x ~2.1.1 ^2.1.1
1.35.7 :x: :x: :x: :x:
2.0.0 :white_check_mark: :x: :x: :x:
2.1.0 :white_check_mark: :white_check_mark: :x: :x:
2.1.1 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
2.1.2 :white_check_mark: :white_check_mark: :white_check_mark: :white_check_mark:
2.2.0 :white_check_mark: :x: :x: :white_check_mark:
3.0.0 :x: :x: :x: :x:

:white_check_mark: がついているものの中で、最新のものがインストールされます!

このようにバージョンを範囲指定することで、 npm install するだけで、バグが修正された新しいライブラリを使うことができます。

ただし、以下のようなことも発生します。

  • Aさん、11月に npm install を実行したところ、 2.1.1 がインストールされた。
  • Bさん、12月に npm install を実行したところ、 2.1.2 がインストールされた。

npm install を実行したタイミングで異なるバージョンのライブラリがインストールされます!

結局どのバージョンがインストールされているのか?は、 package.json を見ただけではわかりません。

それを記録しているのが、 package-lock.json です!

これは自動で生成されるファイルなので、このファイルを手動で編集しないようにお願いします。

npm cipackage-lock.json から高速にインストールする

せっかく色々インストールしましたが、ここでいったん、 node_modules フォルダーを削除してみましょう。

(VS Codeで node_modules を開いている場合は、エラーが起きるかもしれません。その場合は、VS Codeを閉じてください。)

削除ができたら、以下のコマンドを実行してください。

npm ci

node_modules フォルダーが復活しました!

実は、 npm cipackage-lock.json を元にライブラリをインストールするんです!

また、 npm install よりも npm ci の方が、インストールが早く終わったことに気づいたかもしれません。

npm install を実行したときは、ライブラリが依存している別のライブラリを検索したりと、依存関係の解決に時間がかかります。

しかし、 package-lock.json には、そういった依存関係の検索が済んだデータが記載されています。そのため、 npm ci の方が npm install よりも高速になったんです。

グローバルに npm install

今度は、以下のコマンドを実行してくてみましょう。

npm install --global fixpack

fixpack というライブラリがインストールされたはずですが、 package.json にも node_modules にも fixpack は追加されていません。

実は、npmにはグローバル用の node_modules があり、そこに追加されています。

WindowsでNodistを使ってNode.jsをインストールした場合、 C:\Program Files (x86)\Nodist\bin\node_modules にあるようです。

fixpack を使ってみる

グローバルにインストールした fixpack を使ってみましょう。

以下のコマンドを実行してください。

fixpack

package.json の中身が自動でソートされたと思います。

とくにぐちゃぐちゃになりがちな dependencies の中身がアルファベット順にソートされるので便利です。

積極的に使っていきましょう!

さいごに

以上おつかれさまでした。

ひととおり、npmコマンドや package.json の編集を体験できたと思います。

本記事作成にあたり、以下のページを参考にしました。ありがとうございました。

これは Node.js Advent Calendar 2019 の8日目の記事でした。
明日は @shimataro999 さんによる Node.js v12のES Modulesと、Babel/TypeScriptの対応について です!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away