0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「依存関係」をそもそも論から掘り返すーpackage.jsonからnode_modulesについてー

Posted at

前書き

この記事の目的

技術的な調査をしているとき、解説文に出てきている用語の意味や、その文脈での意味合いが掴みきれずに、なんとなくで読み進めていくことってありませんか?

なんとなくで読み進めていくから、最後の方はほとんどが ”なんとなく” の理解になっていて、どこまで行っても分かった ”つもり” にしかなれないような、そんなあなた、そして、そんな私自身のための記事です。

できるだけ補足をつけていくので立ち止まりながらゆっくり読むような記事にできればと思います。

前提

この記事ではNode.jsを用いた開発を対象にしています。

(私はそれ以外にあまり触れたことがないので)

「依存関係」とは何を指すのか

そもそも論になりますが、

「依存関係」

この用語がなんとも初心者にはわかりにくいですよね。

まずは例を挙げます。

例えば、あなたが「ペンギン」というアプリを開発しているとします。

「ペンギン」はReact.jsを用いて開発しており、デザインはBootstrapというツールを使用しています。

React.jsを用いて開発しているわけですから、当然、「ペンギン」はReactが存在していないと正常に動いてくれません。

つまり、「ペンギン」はReactに ”依存している” と言うことができます。

また、デザインはBootstrapがいい感じにしてくれるので、「ペンギン」はBootstrapにも 依存 しています。

その上で、BootstrapにはReactでの使用を前提としたツールセットのようなものも存在しているので、それを使用するとしたら、BootstrapもReactに依存していると言うことができるかもしれません。

イメージとしてはこんな感じ。

依存関係.jpg

この一連の関係性のことを「依存関係」と言うのです。

「依存関係」は誰がどのように管理するのか

依存関係というものが何を指すのかが分かったところで、
「でもそれってどう管理しているの?」
という疑問に出会うかもしれません。

Node.jsでの開発では、package.jsonというファイルでそれを管理します。

package.json

きっと皆さんが目にしたことのあるファイル名が出てきましたね。

「package.json とは」でググると最初にこんな説明が出てきます。

package.jsonはNode.jsプロジェクトにおける依存関係管理やスクリプトの定義に必要なファイルです。 外部パッケージの管理、バージョンの指定、プロジェクトの情報の記述など、プロジェクトの一貫性と管理を助ける重要な役割を果たします。

引用元:https://gk-fe.com/article/about-packagejson/

今の段階では

  • 外部パッケージの管理
  • バージョンの指定

この二つができるファイルだと思ってもらえればいいです。

ここでいうパッケージというのが、前述の「ペンギン」におけるReactやBootstrapに該当します。

このファイルは、プロジェクトを作成する際にターミナルやコマンドプロンプトで

npm init

などと入力すると勝手に作成されます。

Reactの雛形を作るときなんかは

npx create-react-app my-react-app

みたいにしてもちゃんと作成されます。

せっかくなので、npx create-react-app my-react-app で作成したプロジェクトのpackage.jsonを確認してみましょう。

{
  "name": "my-react-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

色々書いてありますが、今回重要なのはこの部分です。

"dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },

dependenciesを和訳すると「依存関係」です。

つまり、これが依存関係を管理している部分です。

dependencies

では、ここでどのようにして依存関係を管理しているのでしょうか?

それは先ほどの

  • 外部パッケージの管理
  • バージョンの指定

を決まった形式で記述して管理している、ということになります。

一例として

"react": "^18.3.1",

を見てみましょう。

これは「Reactのバージョン18.3.1を使う」という指定です。

つまり、

"外部パッケージ名": "バージョン",

ということになります。

つまり、依存関係を管理するということは、

「それぞれのパッケージのバージョンを適切に管理すること」

ということもできるかもしれません。

package.jsonとは、

「必要なパッケージの名前とバージョンのリスト」

だと思ってくれれば大丈夫です。

パッケージをインストールする

では、そのリストをもとに実際にパッケージをインストールするのは誰なのでしょうか?

Node.jsにはその辺りをカバーしてくれる便利なシステム「npm」が備わっています。

補足:npmについて

本題からズレるので、npmについての説明は省きますが、詳しく知りたい方には下記の記事がおすすめです。

使い方はとても簡単。

ターミナルやコマンドプロンプトで

npm install

というコマンドを入力するだけです。

Node.jsさえ入っていれば正常にインストールが走ります。

node_modules

npm installを実行すると、きっとあなたのプロジェクトにはpackage-lock.jsonというファイルとnode_modulesというフォルダが生成されるはずです。

今回重要なのはnode_modulesなので、package-lock.jsonの細かい説明は省きます。

補足:package-lock.jsonについて

本題からズレるので、package-lock.jsonについての説明は省きますが、詳しく知りたい方には下記の記事がおすすめです。

node_modules とは package.json を元にしてインストールされる各種パッケージがインストールされるディレクトリ先のことです。

Node.jsがあなたの作成したpackage.jsonの依存関係リストをもとにして、実際のパッケージをネットワークを介してnode_modulesの中に格納します。

これだけでは曖昧な理解になる方もいるかもしれないので、例えてみます。

イメージとしては倉庫のようなものをイメージするといいかもしれないです。

node_modules (1).jpg

Node.jsは注文(npm install)を受け付けると、発注リスト(package.json)をもとにインターネット上から商品(パッケージ)を探しに行って、倉庫(node_modules)に格納する、といった流れです。

あなたの開発プロジェクトでそれぞれのパッケージが必要になったときには、このnode_moduleを参照します。

ここでよくある疑問としては、

「リストの管理なんかせずに、最初からパッケージを直接node_modulesに格納しちゃえばいいじゃん」

という疑問だと思います。

その理由としては、

「後々面倒になるかもしれないから」

です。

先ほどの例のように2.3個しかパッケージがなければ実はそれほど面倒にはなりません。しかし、管理するパッケージが20個や30個になったら場合を想像すると、その面倒さと、リストと倉庫を分ける理由もわかります。

package.jsonでパッケージをリスト管理するとき、パッケージの名前とともにバージョン情報を管理していましたね。それはつまり、パッケージにおいてバージョンとは非常に重要な情報であることを指します。

バージョンが重要な情報ということは、

  • バージョンが変わる可能性があるということ
  • バージョンが変われば、パッケージの中身も変わること

が想像できます。

実際に、パッケージは適切に管理されていればいるほどアップデートが頻繁に発生します。

その内容は軽微な修正から、大幅な機能更新、重要なセキュリティ問題の解決など、多岐にわたります。

そういったものを確認し、毎回自分のプロジェクトのパッケージを手動で更新するのは非常に面倒であり、多分、ミスも発生します。

そのために、リストと倉庫というふうに分離させることで、管理を簡単にしています。

最後に

ここまで読めば、

  • 依存関係
  • package.json
  • node_modules

などがそれぞれどんなものなのかがある程度わかったかと思います。

皆さんのプログラミングライフのささやかな手助けになれたら幸いです。

内容に指摘や補足がありましたら、適宜修正・補足の追加を行いますので、ぜひご指摘ください。

参考にした記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?