1
0

More than 1 year has passed since last update.

【npm】概念、コマンドについて調べました。

Last updated at Posted at 2023-01-03

◆はじめに

npmって何?」「package.jsonって?」と、ふんわりした状態だったので、調べた自分のメモをまとめておきます。

◆目次

◆はじめに
◆目次
◆Node.jsとは
◆npmとは
 1. オンライン上のパッケージレジストリ
 2. 上記パッケージレジストリとやりとりするためのCLI
◆特定のパッケージをインストールしてプロジェクトを作成する手順
 1. Node.jsをインストール
 2. プロジェクトを作成
 3. パッケージのインストール(特定のパッケージを指定)
 4. プログラムを書く
 5. 実行コマンド
◆package.json、package-lock.jsonを元にパッケージをインストールする
 1. package.jsonを元にパッケージをインストール
 2. package-lock.jsonを元にパッケージをインストール
◆その他のよく使うnpmコマンド
 1. パッケージのバージョン確認
 2. パッケージのアップデート
 3. パッケージのアンインストール
◆最後に
◆参考

◆Node.jsとは

  • JavaScriptのサーバー上の実行環境
  • 処理を非同期で実行できる
  • 外部のパッケージを読み込んで利用できる

これまでWebブラウザの中だけで動いていたJavaScriptという言語のエンジン部分をWebブラウザから切り離し、独立したプログラムとして実行できるようにしたのがNode.jsなのです。

(「Node.js超入門 第3版」より引用)

◆npmとは

  • Node Package Managerの略
  • 次の2つの意味合いがある

1. オンライン上のパッケージレジストリ

世界中で開発されたNode.js のパッケージがまとめて公開されている場所。
(パッケージ=Node.jsの機能を拡張するプログラム。モジュールとも呼ばれる)
自分でコードを書かなくても、パッケージを利用することでその機能をより簡単にプロジェクトに追加することができる。

次の2.と区別するため大文字でNPMと表現されることも(この記事でもそうします)

2. 上記パッケージレジストリとやりとりするためのCLI

  • CLI =コマンドラインインターフェース
  • 「Node.jsのパッケージ管理システム」と定義される場合はこちらの意味合いで使われている
  • コマンドを実行することにより、1.のNPMパッケージレジストリからパッケージのインストール、アップデート、アンインストールなど、様々なことができる
  • 1つのパッケージは他の複数のパッケージに依存し、そのパッケージがまた複数の他のパッケージに依存して…と依存関係が連鎖しているが、1つ1つ個別に対応しなくても、コマンドで全ての依存関係を解決してくれる
  • Node.jsと一緒にインストールされる

◆特定のパッケージをインストールしてプロジェクトを作成する手順

1. Node.jsをインストール

以下のサイトからインストールできます。

※OSによりインストール方法が違ったり、Node.jsのバージョン管理ツールを利用してインストールしたりしますが今回は割愛します(参考サイト一例

バージョンを確認。

$ node -v
v16.13.0
        
$ npm -v
8.1.0

2. プロジェクトを作成

まず、プロジェクトのディレクトリを作成し、その中に移動します。
プロジェクト名がnpm_appとすると↓

$ mkdir npm_app
$ cd npm_app

プロジェクトでnpmを利用するには、以下のコマンドで初期化します。

$ npm init
$ npm init -y  # 質問&回答を省略する場合
  • -yオプションをつけない場合、package.jsonに記述する内容を質問されるが、特に指定がなければ全ての質問にEnterキーを押してOK
  • プロジェクト名はコマンドを実行したディレクトリ名となる(プロジェクト名は変更可能)
  • package.jsonファイルがプロジェクト内のディレクトリに作成される
npm_app   
 └── package.json

package.jsonとは

  • パッケージのバージョン管理を行うファイル
  • プロジェクトで使用するパッケージとバージョン範囲が記載される
  • Git管理に含める

作成されたpackage.jsonの初期値(質問&回答を省略した場合)

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

mainindex.jsがプロジェクトを実行する時のエントリポイントとなります。
index.jsは同じディレクトリ内に自分で作成します。

$ touch index.js
npm_app
├── index.js  // 作成した
└── package.json

3. パッケージのインストール(特定のパッケージを指定)

以下のコマンドで、NPMレジストリからパッケージをインストールしてnode_modulesディレクトリに保存します(node_modulesディレクトリがない場合は作成されます)

npm install <パッケージ名>          # 最新のバージョン
npm install <パッケージ名@バージョン> # 特定のバージョン
npm install -g <パッケージ名>       # グローバルにインストール ※各パッケージのバージョン依存が大きいため非推奨
npm install -D <パッケージ名>       # 開発環境のみで使用するパッケージをインストール(eslintなど)
  • npm installのエイリアス→npm inpm addなど
  • パッケージ名をスペースで区切り、複数のパッケージを指定することもできる
  • インストール対象のパッケージが依存するパッケージがある場合は自動でインストールされる

では、実際にNPMからパッケージをインストールしてみます。
何でもいいのですが、今回はnode-fetchをインストールします。

node-fetch モジュールは、Node.js アプリで Web ブラウザと同様の fetch 関数を扱えるようにするためのライブラリです。 これを使うと、Promise ベースの HTTP 通信を行うことができます。

node-fetch モジュールを使用して HTTP 通信を行う 」より

では、インストールします。

npm install node-fetch

すると、package.jsonにパッケージ情報が追記され、
node_modulesディレクトリ、package-lock.jsonファイルが新たに作成されます。

npm_app
├── node_modules // 作成された
   └── パッケージのディレクトリ群
├── index.js
├── package-lock.json // 作成された
└── package.json  // 追記された

まず、package.jsonを確認すると、dependenciesというプロパティが追加され、その値としてnode-fetchというパッケージ名とそのバージョン範囲が記載されています。

package.json
{
  "name": "npm_app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "node-fetch": "^3.3.0"
  }
}

次に、package-lock.jsonを見てみます。

package-lock.jsonとは

  • 実際にインストールしたパッケージ(パッケージが依存するパッケージ含む)とそのバージョンが記載される
  • このファイルが存在することで、複数の開発者が全く同じ開発環境を再現できる
  • Git管理に含める
作成されたpackage-lock.jsonの中身はコチラ(長いのでクリックで参照)
package-lock.json
{
  "name": "npm_app",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "npm_app",
      "version": "1.0.0",
      "license": "ISC",
      "dependencies": {
        "node-fetch": "^3.3.0"
      }
    },
    "node_modules/data-uri-to-buffer": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
      "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==",
      "engines": {
        "node": ">= 12"
      }
    },
    "node_modules/fetch-blob": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
      "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/jimmywarting"
        },
        {
          "type": "paypal",
          "url": "https://paypal.me/jimmywarting"
        }
      ],
      "dependencies": {
        "node-domexception": "^1.0.0",
        "web-streams-polyfill": "^3.0.3"
      },
      "engines": {
        "node": "^12.20 || >= 14.13"
      }
    },
    "node_modules/formdata-polyfill": {
      "version": "4.0.10",
      "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
      "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
      "dependencies": {
        "fetch-blob": "^3.1.2"
      },
      "engines": {
        "node": ">=12.20.0"
      }
    },
    "node_modules/node-domexception": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
      "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/jimmywarting"
        },
        {
          "type": "github",
          "url": "https://paypal.me/jimmywarting"
        }
      ],
      "engines": {
        "node": ">=10.5.0"
      }
    },
    "node_modules/node-fetch": {
      "version": "3.3.0",
      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz",
      "integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==",
      "dependencies": {
        "data-uri-to-buffer": "^4.0.0",
        "fetch-blob": "^3.1.4",
        "formdata-polyfill": "^4.0.10"
      },
      "engines": {
        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/node-fetch"
      }
    },
    "node_modules/web-streams-polyfill": {
      "version": "3.2.1",
      "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
      "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
      "engines": {
        "node": ">= 8"
      }
    }
  },
  "dependencies": {
    "data-uri-to-buffer": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
      "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA=="
    },
    "fetch-blob": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
      "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
      "requires": {
        "node-domexception": "^1.0.0",
        "web-streams-polyfill": "^3.0.3"
      }
    },
    "formdata-polyfill": {
      "version": "4.0.10",
      "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
      "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
      "requires": {
        "fetch-blob": "^3.1.2"
      }
    },
    "node-domexception": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
      "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
    },
    "node-fetch": {
      "version": "3.3.0",
      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz",
      "integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==",
      "requires": {
        "data-uri-to-buffer": "^4.0.0",
        "fetch-blob": "^3.1.4",
        "formdata-polyfill": "^4.0.10"
      }
    },
    "web-streams-polyfill": {
      "version": "3.2.1",
      "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
      "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q=="
    }
  }
}

最後にnode_modulesです。

node_modulesとは

  • インストールしたパッケージの実態が入っている
  • Gitでは管理しない(パッケージはプロジェクトとは独立して管理する)

中身を見てみると、node_fetchや、それが依存するパッケージ群がインストールされているのが確認できます。

Gitで管理しない理由としては、パッケージを追加していくことにより膨大なデータ量となってしまうため、また、パッケージのアップデートや依存関係の変更のたびに都度パッケージのコードまでGitで管理するのは大変なためです。

開発者は、package.jsonpackage-lock.jsonが存在すれば、npmコマンドを使ってパッケージの依存関係を再構築できます。
(これがpackage.jsonpackage-lock.jsonの存在意義です)

では、node_modulesをGitの管理から外しておきます。

$ touch .gitignore
npm_app
├── node_modules
   └── パッケージのディレクトリ群
├── .gitignore // 作成した
├── index.js
├── package-lock.json
└── package.json

.gitignoreに以下を追加します。

.gitignore
/node_modules

4. プログラムを書く

では、この状態でnode-fetchパッケージを利用した簡単なプログラムをindex.jsに書いて実行してみます。
今回は、おしりたんていのキャラクターのページのソースを取得して出力します(※もしご自身で試される場合はURLを好きなものに変えてください)

パッケージはrequireまたはimportで読み込みます(モジュールの読み込み形式、環境により異なります)
最低限のコードとなりますが…今回は動かすことだけの確認なので。

index.js
import fetch from "node-fetch"; // パッケージの読み込み

fetch("https://www.oshiri-tantei.com/character/")
  .then((res) => res.text())
  .then((body) => console.log(body));

importを使用する場合、package.json"type": "module"を追記します。

package.json
{
  "name": "npm_app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "node-fetch": "^3.3.0"
  }
}

では、この状態で実行します。

5. 実行コマンド

実行コマンド(1)
$ node .

カレントディレクトリを引数にすることにより、そのディレクトリに存在するpackage.jsonに記載されているmainプロパティのファイルが実行されます。

または、以下のようにファイル名を指定してもOK

実行コマンド(2)
$ node index.js

もしくは、以下のようにpackage.json"scripts""start": "node index.js"と登録しておくと…

package.json
{
  "name": "npm_app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "node-fetch": "^3.3.0"
  }
}

以下でも実行することができます。

実行コマンド(3)
$ npm start
# もしくは
$ npm run start
取得結果はコチラ(長いのでクリックで参照)
<!DOCTYPE html>
<html xml:lang="ja" lang="ja">
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
  <meta charset="utf-8" />
<meta name="viewport" content="width=device-width,user-scalable=no,shrink-to-fit=yes">
<meta name="format-detection" content="telephone=no">
<meta http-equiv="imagetoolbar" content="no" />
<link rel="shortcut icon" href="/favicon.ico">
<meta http-equiv="x-ua-compatible" content="IE=edge" />
<title>キャラクター | おしりたんてい | アニメ公式ホームページ</title>
<meta name="description" content="アニメ「おしりたんてい」NHK Eテレにて好評放送中!エクセレントな推理と必殺技でどんな事件もププッと解決!是非お楽たのしみください!放送時間は(土)Eテレ 午前9:00~9:20、(木)Eテレ 午後6:55~7:15です。">
<meta name="keywords" content="おしりたんてい,アニメ,東映,東映アニメーション" />
<meta property="og:title" content="キャラクター | おしりたんてい | アニメ公式ホームページ" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://www.oshiri-tantei.com/character/" />
<meta property="og:image" content="http://www.oshiri-tantei.com/ogp2.jpg">
<meta property="og:description" content="アニメ「おしりたんてい」NHK Eテレにて好評放送中!エクセレントな推理と必殺技でどんな事件もププッと解決!是非お楽たのしみください!放送時間は(土)Eテレ 午前9:00~9:20、(木)Eテレ 午後6:55~7:15です。" />
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:domain" content="https://www.oshiri-tantei.com/character/">
<meta name="twitter:description" content="アニメ「おしりたんてい」NHK Eテレにて好評放送中!エクセレントな推理と必殺技でどんな事件もププッと解決!是非お楽たのしみください!放送時間は(土)Eテレ 午前9:00~9:20、(木)Eテレ 午後6:55~7:15です。">
<meta name="twitter:image" content="http://www.oshiri-tantei.com/ogp2.jpg">

<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=M+PLUS+Rounded+1c:wght@400;500;700;800;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/assets/css/jquery.fancybox.css">
<link rel="stylesheet" href="/assets/css/slick.css">
<link rel="stylesheet" href="/assets/css/slick-theme.css">
<link rel="stylesheet" href="/assets/css/style.css">

<script src="/assets/js/jquery-3.6.0.min.js"></script>
<script src="/assets/js/jquery.fancybox.min.js"></script>
<script src="/assets/js/lazyload.js"></script>
<script src="/assets/js/slick.min.js"></script>
<script src="/assets/js/script.js"></script>

<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-K3755S4');</script>
<!-- End Google Tag Manager --></head>
<body class="character">
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-K3755S4"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->


<header id="header">
  <div class="headerInr">
    <div class="logo">
      <a href="/index.html"><img src="/assets/img/header/img_logo.png" alt="おしりたんてい"></a>
    </div>
    <div class="menu">
      <div class="menuInr">
        <a href="" class="btnOpen">
          <img src="/assets/img/common/arw_top.svg" alt="" class="ico">メニューをひらく
        </a>
        <h2 class="tit">
          メニュー
        </h2>
        <nav>
          <ul>
            <li><a href="/info/"><img src="/assets/img/header/img_menu01.png" alt="おしりたんていとは?"></a></li>
            <li><a href="/onair/"><img src="/assets/img/header/img_menu02.png" alt="放送情報配信"></a></li>
            <li><a href="/character/"><img src="/assets/img/header/img_menu03.png" alt="キャラクター"></a></li>
            <li><a href="/story/"><img src="/assets/img/header/img_menu04.png" alt="ストーリー"></a></li>
            <li><a href="/goods/"><img src="/assets/img/header/img_menu05.png" alt="本・グッズ"></a></li>
            <li><a href="/events/"><img src="/assets/img/header/img_menu06.png" alt="イベント"></a></li>
            <li><a href="/movie/"><img src="/assets/img/header/img_menu07.png" alt="ムービー・ぬりえ"></a></li>
            <li class="SP"><a href="/index.html"><img src="/assets/img/header/img_menu_top.png" alt="トップページ"></a></li>
          </ul>
        </nav>
        <a href="" class="btnClose">
          <img src="/assets/img/common/ico_cross.png" alt="" class="ico">メニューをとじる
        </a>

        <div class="chara03">
          <img src="/assets/img/header/img_menu_chara.png" alt="">
        </div>
      </div>
    </div>
  </div>
  <img src="/assets/img/header/bg_header.png" class="bg" alt="">
</header><main id="main">
  <h1 class="tit">キャラクター</h1>
  <section class="character-main">
    <ul class="chara-tab">
      <li class="act">
        <a href="/character/"><img src="/assets/img/character/img_character01.png" alt="">おしりたんていじむしょ</a>
      </li>
      <li>
        <a href="/character/wankoro.html"><img src="/assets/img/character/img_character02.png" alt="">ワンコロけいさつしょ</a>
      </li>
      <li>
        <a href="/character/other.html"><img src="/assets/img/character/img_character03.png" alt="">とりまくひとびと</a>
      </li>
    </ul>
    <div class="character-list">
      <div class="character-wrap">
        <div class="character-item">
          <ul class="chara">
                                                              <li>
                <a href="/character/?char=char-oshiri">
                  <figure>
                    <img src="/assets/img/character/osiri/01_img.png" alt="" loading="lazy">
                  </figure>
                  <div class="name">おしりたんてい</div>
                                                                        <div class="cv">声:三瓶由布子</div>                </a>
              </li>
                                                              <li>
                <a href="/character/?char=char-brown">
                  <figure>
                    <img src="/assets/img/character/osiri/02_img.png" alt="" loading="lazy">
                  </figure>
                  <div class="name">ブラウン</div>
                                                                        <div class="cv">声:齋藤彩夏</div>                </a>
              </li>
                                                          </ul>
        </div>
      </div>
    </div>
  </section>
</main>

<footer id="footer">
        <ul class="banner">



                                <li><a href="https://www.poplar.co.jp/oshiri-tantei/" target="_blank"><img src="/assets/img/banner/bnr_poplar.jpg" alt="" ></a></li>
                <li><a href="https://www.toei-anim.co.jp/" target="_blank"><img src="/assets/img/banner/bnr_toeianim.jpg" alt=""></a></li>
                <li><a href="http://www.shonenjump.com/j/saikyo/oshiri-dandy/" target="_blank"><img src="/assets/img/banner/bnr_dandy.jpg" alt=""></a></li>
        </ul>
        <div class="copyright">&copy; トロル・ポプラ社/おしりたんてい製作委員会</div>

        <a href="" id="pagetop">
                <img src="/assets/img/footer/img_pagetop.png" class="PC" alt="">
                <img src="/assets/img/footer/img_pagetop_sp.png" class="SP" alt="">
        </a>
        <div class="sns">
                <ul>
                        <li><a href="https://twitter.com/intent/tweet?text=アニメ「おしりたんてい」公式ホームページサイト!アニメ化プロジェクト始動!&url=http://www.oshiri-tantei.com" rel=”nofollow” onClick="window.open(encodeURI(decodeURI(this.href)),'twwindow','width=550, height=450, personalbar=0, toolbar=0, scrollbars=1'); return false;"><img src="/assets/img/footer/ico_tw.png" class="tw" alt="Twitter"></a></li>
                        <li><a href="https://www.facebook.com/sharer/sharer.php?u=http://www.oshiri-tantei.com/" onclick="window.open(encodeURI(decodeURI(this.href)), 'FBwindow', 'width=554, height=470, menubar=no, toolbar=no, scrollbars=yes'); return false;" rel="nofollow"><img src="/assets/img/footer/ico_fb.png" class="fb" alt="Facebook"></a></li>
                                                <li><a href="http://line.naver.jp/R/msg/text/?アニメ「おしりたんてい」公式ホームページサイト!アニメ化プロジェクト始動! http://www.oshiri-tantei.com" onclick="window.open(encodeURI(decodeURI(this.href)), 'LINEwindow', 'width=554, height=470, menubar=no, toolbar=no, scrollbars=yes'); return false;" rel="nofollow"><img src="/assets/img/footer/ico_line.png" class="line" alt="Line"></a></li>
                        <li><a href="https://www.youtube.com/watch?v=047VMJlBZxQ" target="_blank"><img src="/assets/img/footer/ico_youtube.png" class="youtube" alt="Youtube"></a></li>
                </ul>
        </div>


</footer><div id="modal" >
        <div class="modal_main">
                <div class="inner">
                                        </div>
        </div>
</div>

</body>
</html>

これで、Node.jsでパッケージを使ったプロジェクトが作成できました。

これだけだと、package.jsonpackage-lock.jsonの意義が分かりづらいです…。

次に、他の開発者が上記プロジェクトの環境を構築する時のことを考えます。

◆package.json、package-lock.jsonを元にパッケージをインストールする

他の開発者が先ほど作成したプロジェクトをgit cloneした場合、package.jsonpackage-lock.jsonは存在しますが、node_modules(=必要なパッケージ群の実態)はgitで管理していないので存在しません。
あくまでパッケージはNPMレジストリで管理されているのでnpmを使って必要なパッケージをインストールする必要があります。

その場合、以下の2つの方法があります。

  1. package.jsonを元にパッケージのインストールする
  2. package-lock.jsonを元にパッケージをインストールする

「どう違うの?」と私も最初は分からず…個人的に以下のように理解しました。

  1. package.jsonを元にパッケージをインストールする
     →パッケージの依存関係をいい感じに解決した最新版をインストールしたいとき
  2. package-lock.jsonを元にパッケージをインストールする
     →とにかく全く同じ環境を構築したいとき

1. package.jsonを元にパッケージをインストール

既存のpackage.jsonを元にインストールする場合、引数なしで以下のコマンドを実行します。

npm install
  • package.jsonに記載されているバージョンの範囲で最新バージョンのパッケージ(依存関係も解決された状態)がインストールされる
  • 上記により、package.jsonpackage-lock.jsonが更新される(この変更は気にしなくて良いし、Gitの管理に含める)

NPMレジストリのパッケージやその依存するパッケージ…(依存関係)は、バグの修正や機能の改善などで日々アップデートされていきます。
npm installコマンドを叩くだけで自動的に新しい依存関係を取り込めるので便利です。

このコマンドにより、package.jsonpackage-lock.jsonも変更されますが、その状態も他の開発者と共有したいので、Gitで管理します。

package.jsonに記載のある範囲の最新バージョン」とありますが、バージョン範囲の見方は以下を参照ください。

バージョンの範囲の参考サイト

キャレット(^)やチルダ(~)が付いている場合、基本的にはプロジェクト側のソースコードの変更を必要とするようなバージョン変更はされないので、依存関係を更新していっても問題ない、という認識でnpm installが使われます(ただ、そうでないケースもあるので注意が必要です)

2. package-lock.jsonを元にパッケージをインストール

既存のpackage-lock.jsonを元にインストールする場合、以下のコマンドを実行します。

npm ci
  • node_modulesが存在する場合はいったん削除してから再インストールする
  • package.jsonpackage-lock.jsonの間に一致しない依存関係がある場合、エラーとなる(npm installはこの場合、package-lock.jsonを更新)
  • package-lock.jsonのバージョンで固定してパッケージをインストールする
  • package.jsonpackage-lock.jsonファイルは更新されない

自動的な依存関係の更新はせずに、package-lock.jsonでロックされたバージョンでインストールします。
プロジェクトの現状と全く同じバージョンで環境構築したい時に使用します。

◆その他のよく使うnpmコマンド

ここからは、ただのメモに近いのですが…自分のためにも残しておきます。

1. パッケージのバージョン確認

インストール済みのパッケージのバージョン一覧を確認

npm list --depth=0    # ローカル
npm list --depth=0 -g # グローバル
  • npm listのエイリアス→npm ls

--depth=0オプションをつけない場合、インストールしたパッケージが依存しているパッケージも出力される↓

npm list

リリースされているパッケージのバージョン一覧を取得するコマンド

npm info パッケージ名 versions

2. パッケージのアップデート

パッケージを指定

npm update パッケージ名
npm update パッケージ名@バージョン

全てのパッケージ

npm update    # ローカル
npm update -g # グローバル
  • package.json に記載されているバージョンの範囲で最新のバージョンにアップデートする(世の中の最新のバージョンに更新されるわけではない)

3. パッケージのアンインストール

npm un パッケージ名    # ローカル
npm un -g パッケージ名 # グローバル
  • npm unのエイリアス→npm rm
  • パッケージ名をスペースで区切り、複数のパッケージを指定することもできる

◆最後に

記載内容にバラつきがあるかもしれません。
間違いがありましたらご指摘いただけましたら幸いです!

◆参考

1
0
1

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
1
0