8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Yarn】パッケージをオフラインでインストールする

Posted at

背景

Yarn v2についての動画で出てきた「v1のオフラインインストール」について、よく知らなかったので調べてみた。

概要

Yarnのオフラインインストールとは、パッケージを追加する際に実態のtarballをローカルにダウンロードしておき、後からそれを用いてパッケージをインストール出来るようにしたものである。パッケージをインストールする際に yarn.lock ファイルにダウンロード元のURLが記録されているため、URLが有効な限りは何度実行しても同一のファイルがダウンロードされることが保証されるが、ダウンロード元のダウンや閉鎖等によってURLが無効になった場合はダウンロードに失敗する。このような場合に備えて予めtarballをダウンロードしておき、オフライン時に利用するのがオフラインインストールである。

詳解

事前準備

まずはじめに、適当なディレクトリを作成して以下のファイルを配置する。

package.json
{
  "name": "yarn-offline",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "is-array": "^1.0.1",
    "left-pad": "^1.3.0",
    "mime-types": "^2.1.27"
  }
}

パッケージを追加し、ディレクトリの構成が以下の通りになっていることを確認する。

$ yarn
(略)
$ ls
node_modules    package.json    yarn.lock

オフラインミラーの設定

オフラインミラー(ダウンロードされるtarballが配置されるパス)を設定する。ここで指定するパスはホームディレクトリからの相対パスであることに留意する。

$ yarn config set yarn-offline-mirror ./npm-packages-offline-cache
yarn config v1.22.0
success Set "yarn-offline-mirror" to "./npm-packages-offline-cache".
✨  Done in 0.04s.
$ yarn config set yarn-offline-mirror-pruning true
yarn config v0.23.2
success Set "yarn-offline-mirror-pruning" to "true".
✨  Done in 0.06s.

yarn config set で追加した設定は ~/.yarnrc に記録されている。これを特定のプロジェクトでのみ利用可能にするため、ファイルをプロジェクトディレクトリ内に移動する。

$ mv ~/.yarnrc ./

パッケージのダウンロード

オフラインインストールを用いる場合でも、yarn.lock は変更されないためパッケージ管理に影響を及ぼさない。これを検証するためにファイルをコピーしておく。

$ cp yarn.lock yarn.lock.before

node_modules/yarn.lock を削除して再度パッケージの追加を行う。その後、~/npm-packages-offline-cache にtarballがダウンロードされていることを確認する。

$ rm -rf node_modules/ yarn.lock
$ yarn
yarn install v1.22.4
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 0.52s.
$ ls ~/npm-packages-offline-cache
is-array-1.0.1.tgz      left-pad-1.3.0.tgz      mime-db-1.44.0.tgz      mime-types-2.1.27.tgz

yarn.lock が変更されていないことを確認する。

$ diff yarn.lock yarn.lock.before
$ rm yarn.lock.before

オフラインインストールの実行

オフラインインストールの検証を行うため、node_modules/ とキャッシュを削除する。

$ rm -rf node_modules/
$ yarn cache clean
yarn cache v1.22.4
success Cleared cache.
✨  Done in 0.10s.

ネットワークを切断してオフラインにする。続けて yarn --offline を実行し、オフライン時でもパッケージが追加できることを確認する。

thara@ht-mbp-2:yarn-offline $ ls
package.json            yarn.lock
thara@ht-mbp-2:yarn-offline $ yarn --offline
yarn install v1.22.4
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
✨  Done in 0.55s.
thara@ht-mbp-2:yarn-offline $ ls
node_modules            package.json            yarn.lock

検証

上記に続けて、ダウンロード済みtarball、キャッシュ、yarn.lock の関係について検証する。

オフラインインストールはキャッシュが無い場合に行われる

オフラインインストール時のパッケージとしてダウンロード済みtarballが用いられたように思えるがこれは正確ではない。キャッシュにもtarballが存在しており、こちらが優先して用いられるため「キャッシュが無ければダウンロード済みtarballが用いられる」という説明が正しい。以下を実行し、~/npm-packages-offline-cache が存在しなくともオフラインインストールに成功することを確認する。

$ rm -rf node_modules/
$ mv ~/npm-packages-offline-cache ~/npm-packages-offline-cache-renamed
$ yarn --offline
yarn install v1.22.4
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 0.28s.

キャッシュとダウンロード済みtarballの両方が存在しなければ、当然オフラインインストールは失敗する。

$ rm -rf node_modules/
$ yarn cache clean
yarn cache v1.22.4
success Cleared cache.
✨  Done in 0.05s.
$ yarn --offline
yarn install v1.22.4
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
error Can't make a request in offline mode ("https://registry.yarnpkg.com/is-array/-/is-array-1.0.1.tgz")
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

ダウンロード済みパッケージの検証には yarn.lock が用いられる

~/npm-packages-offline-cache を元に戻し、yarn.lock を削除してオフラインインストールに失敗することを確認する。yarn.lock が存在しない場合は、インストールするべきパッケージの検証が出来ないためである。

$ mv ~/npm-packages-offline-cache-renamed/ ~/npm-packages-offline-cache
$ rm yarn.lock
$ yarn --offline 
yarn install v1.22.4
info No lockfile found.
[1/4] 🔍  Resolving packages...
error An unexpected error occurred: "There should only be one folder in a package cache (got  in /Users/thara/.cache/yarn/v6/npm-is-array-1.0.1-e9850cc2cc860c3bc0977e84ccf0dd464584279a-integrity/node_modules)".
info If you think this is a bug, please open a bug report with the information provided in "/Users/thara/Desktop/yarn-offline/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

キャッシュが存在する場合は yarn.lock は不要である

端末をオンライン状態にし、パッケージを追加してキャッシュを作成する。

$ yarn 
yarn install v1.22.4
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
✨  Done in 0.57s.
$ yarn cache list
yarn cache v1.22.4
Name       Version Registry Resolved                                                                                                
is-array   1.0.1   npm      https://registry.yarnpkg.com/is-array/-/is-array-1.0.1.tgz#e9850cc2cc860c3bc0977e84ccf0dd464584279a     
left-pad   1.3.0   npm      https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e     
mime-db    1.44.0  npm      https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92      
mime-types 2.1.27  npm      https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f
✨  Done in 0.04s.

端末をオフライン状態にして node_modules/yarn.lock を削除し、オフラインインストールに成功することを確認する。

$ rm -rf node_modules/ yarn.lock
$ yarn --offline
yarn install v1.22.4
info No lockfile found.
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 0.40s.
8
5
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
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?