◆はじめに
「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
の初期値(質問&回答を省略した場合)
{
"name": "npm_app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
main
のindex.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 i
、npm 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
というパッケージ名とそのバージョン範囲が記載されています。
{
"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の中身はコチラ(長いのでクリックで参照)
{
"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.json
、package-lock.json
が存在すれば、npmコマンドを使ってパッケージの依存関係を再構築できます。
(これがpackage.json
、package-lock.json
の存在意義です)
では、node_modules
をGitの管理から外しておきます。
$ touch .gitignore
npm_app
├── node_modules
└── パッケージのディレクトリ群
├── .gitignore // 作成した
├── index.js
├── package-lock.json
└── package.json
.gitignore
に以下を追加します。
/node_modules
4. プログラムを書く
では、この状態でnode-fetch
パッケージを利用した簡単なプログラムをindex.js
に書いて実行してみます。
今回は、おしりたんていのキャラクターのページのソースを取得して出力します(※もしご自身で試される場合はURLを好きなものに変えてください)
パッケージはrequire
またはimport
で読み込みます(モジュールの読み込み形式、環境により異なります)
最低限のコードとなりますが…今回は動かすことだけの確認なので。
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"
を追記します。
{
"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. 実行コマンド
$ node .
カレントディレクトリを引数にすることにより、そのディレクトリに存在するpackage.json
に記載されているmainプロパティのファイルが実行されます。
または、以下のようにファイル名を指定してもOK
$ node index.js
もしくは、以下のようにpackage.json
の"scripts"
に"start": "node index.js"
と登録しておくと…
{
"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"
}
}
以下でも実行することができます。
$ 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">© トロル・ポプラ社/おしりたんてい製作委員会</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.json
、package-lock.json
の意義が分かりづらいです…。
次に、他の開発者が上記プロジェクトの環境を構築する時のことを考えます。
◆package.json、package-lock.jsonを元にパッケージをインストールする
他の開発者が先ほど作成したプロジェクトをgit cloneした場合、package.json
、package-lock.json
は存在しますが、node_modules
(=必要なパッケージ群の実態)はgitで管理していないので存在しません。
あくまでパッケージはNPMレジストリで管理されているのでnpmを使って必要なパッケージをインストールする必要があります。
その場合、以下の2つの方法があります。
-
package.json
を元にパッケージのインストールする -
package-lock.json
を元にパッケージをインストールする
「どう違うの?」と私も最初は分からず…個人的に以下のように理解しました。
-
package.json
を元にパッケージをインストールする
→パッケージの依存関係をいい感じに解決した最新版をインストールしたいとき -
package-lock.json
を元にパッケージをインストールする
→とにかく全く同じ環境を構築したいとき
1. package.jsonを元にパッケージをインストール
既存のpackage.json
を元にインストールする場合、引数なしで以下のコマンドを実行します。
npm install
-
package.json
に記載されているバージョンの範囲で最新バージョンのパッケージ(依存関係も解決された状態)がインストールされる - 上記により、
package.json
、package-lock.json
が更新される(この変更は気にしなくて良いし、Gitの管理に含める)
NPMレジストリのパッケージやその依存するパッケージ…(依存関係)は、バグの修正や機能の改善などで日々アップデートされていきます。
npm install
コマンドを叩くだけで自動的に新しい依存関係を取り込めるので便利です。
このコマンドにより、package.json
、package-lock.json
も変更されますが、その状態も他の開発者と共有したいので、Gitで管理します。
「package.json
に記載のある範囲の最新バージョン」とありますが、バージョン範囲の見方は以下を参照ください。
キャレット(^)やチルダ(~)が付いている場合、基本的にはプロジェクト側のソースコードの変更を必要とするようなバージョン変更はされないので、依存関係を更新していっても問題ない、という認識でnpm install
が使われます(ただ、そうでないケースもあるので注意が必要です)
2. package-lock.jsonを元にパッケージをインストール
既存のpackage-lock.json
を元にインストールする場合、以下のコマンドを実行します。
npm ci
-
node_modules
が存在する場合はいったん削除してから再インストールする -
package.json
とpackage-lock.json
の間に一致しない依存関係がある場合、エラーとなる(npm install
はこの場合、package-lock.json
を更新) -
package-lock.json
のバージョンで固定してパッケージをインストールする -
package.json
やpackage-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
- パッケージ名をスペースで区切り、複数のパッケージを指定することもできる
◆最後に
記載内容にバラつきがあるかもしれません。
間違いがありましたらご指摘いただけましたら幸いです!
◆参考