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

npmパッケージをgitリポジトリから取得したときに動くnpm scriptsを調べてみた

More than 1 year has passed since last update.

やってみたこと

node.jsのアプリをいくつか書いていたら、共通の処理が出てきたのでライブラリ化したくなった。
でもあれやこれや…な理由でパブリックには公開できなかった。:cry:
そこでnpmのリポジトリには公開せず、プライベートなgitリポジトリからnpm i git+https://<git-repo>としてインポートすることにした。

npm prepublish の現状と今後どう変わっていくかという記事でnpm scriptsが実行される順序がまとめられていたので参考にしていたのだが、「publishされていないパッケージをgitのリポジトリから直接取ってきたらどうなんねん?」という疑問が湧いてきたので調べてみた。

検証環境

とりあえずnpm 5系と6系のふたつだけ調べました。
検証に使用したPCはmacOS Mojaveの入ったMacBook Proです。

1つ目
* node v8.11.4
* npm 5.6.0

2つ目
* node v8.12.0
* npm 6.4.1

検証方法

まずは下のようなpackage.jsonを用意する。scripts以外は基本的にnpm init -yで吐き出しただけ。

package.json
{
  "name": "npm-script-timings",
  "description": "This project is used to check timings when each npm scripts run.",
  "version": "1.0.0",
  "keywords": [],
  "license": "ISC",
  "main": "index.js",
  "scripts": {
    "prepublish": "echo \"##### prepublish #####\"",
    "prepare": "echo \"##### prepare #####\"",
    "prepublishOnly": "echo \"##### prepublishOnly #####\"",
    "prepack": "echo \"##### prepack #####\"",
    "pack": "echo \"##### pack #####\"",
    "postpack": "echo \"##### postpack #####\"",
    "publish": "echo \"##### publish #####\"",
    "postpublish": "echo \"##### postpublish #####\"",
    "preinstall": "echo \"##### preinstall #####\"",
    "install": "echo \"##### install #####\"",
    "postinstall": "echo \"##### postinstall #####\"",
    "preuninstall": "echo \"##### preuninstall #####\"",
    "uninstall": "echo \"##### uninstall #####\"",
    "postuninstall": "echo \"##### postuninstall #####\"",
    "preversion": "echo \"##### preversion #####\"",
    "version": "echo \"##### version #####\"",
    "postversion": "echo \"##### postversion #####\"",
    "pretest": "echo \"##### pretest #####\"",
    "test": "echo \"##### test #####\"",
    "posttest": "echo \"##### posttest #####\"",
    "prestop": "echo \"##### prestop #####\"",
    "stop": "echo \"##### stop #####\"",
    "poststop": "echo \"##### poststop #####\"",
    "prestart": "echo \"##### prestart #####\"",
    "start": "echo \"##### start #####\"",
    "poststart": "echo \"##### poststart #####\"",
    "prerestart": "echo \"##### prerestart #####*\"",
    "restart": "echo \"##### restart #####\"",
    "postrestart": "echo \"##### postrestart #####\"",
    "preshrinkwrap": "echo \"##### preshrinkwrap #####\"",
    "shrinkwrap": "echo \"##### shrinkwrap #####\"",
    "postshrinkwrap": "echo \"##### postshrinkwrap #####\""
  }
}

このpackage.jsonをプライベートgitリポジトリにpushし、別プロジェクトからnpm i git+https://<git-repo>.gitしたときのコンソールを見てみる。
今回はこのプロジェクトをnpm-script-timingsという名前のリポジトリにして、下のようなディレクトリ構成を取って確認してみた。別プロジェクトと言いながらサブディレクトリに含めてしまっているのは特に意味はありません。

npm-script-timings
├── package-lock.json
├── package.json        # 上記のpackage.json
└── another-project     # npm-script-timingsをインストールするプロジェクト

結果

パス中に登場してしまっている以下の名前は置換しています。

  • ホームディレクトリ -> $HOME
  • gitリポジトリのURL -> $GIT_REPO

npm 5.6.0の場合

インストール対象のスクリプトは、prepack -> postpack -> preinstall -> install -> postinstallの順で動作するようです。

> npm-script-timings@1.0.0 prepack $HOME/.npm/_cacache/tmp/git-clone-d3d05fce
> echo "##### prepack #####"

##### prepack #####

> npm-script-timings@1.0.0 postpack $HOME/.npm/_cacache/tmp/git-clone-d3d05fce
> echo "##### postpack #####"

##### postpack #####

> npm-script-timings@1.0.0 preinstall $HOME/.ghq/$GIT_REPO/another-project/node_modules/npm-script-timings
> echo "##### preinstall #####"

##### preinstall #####

> npm-script-timings@1.0.0 install $HOME/.ghq/$GIT_REPO/another-project/node_modules/npm-script-timings
> echo "##### install #####"

##### install #####

> npm-script-timings@1.0.0 postinstall $HOME/.ghq/$GIT_REPO/another-project/node_modules/npm-script-timings
> echo "##### postinstall #####"

##### postinstall #####
added 1 package in 7.137s

npm 6.4.1の場合

基本的な動作はnpm 5.6.0の場合と同じようですが、なぜかprepackpostpackが2回ずつ走っています。
そこまで問題にはならない気もしますが、意図した動作ではなさそう?

> npm-script-timings@1.0.0 prepack $HOME/.npm/_cacache/tmp/git-clone-8b6cee0a
> echo "##### prepack #####"

##### prepack #####

> npm-script-timings@1.0.0 postpack $HOME/.npm/_cacache/tmp/git-clone-8b6cee0a
> echo "##### postpack #####"

##### postpack #####

> npm-script-timings@1.0.0 prepack $HOME/.npm/_cacache/tmp/git-clone-79212f62
> echo "##### prepack #####"

##### prepack #####

> npm-script-timings@1.0.0 postpack $HOME/.npm/_cacache/tmp/git-clone-79212f62
> echo "##### postpack #####"

##### postpack #####

> npm-script-timings@1.0.0 preinstall $HOME/.ghq/$GIT_REPO/npm-script-timings/another-project/node_modules/npm-script-timings
> echo "##### preinstall #####"

##### preinstall #####

> npm-script-timings@1.0.0 install $HOME/.ghq/$GIT_REPO/npm-script-timings/another-project/node_modules/npm-script-timings
> echo "##### install #####"

##### install #####

> npm-script-timings@1.0.0 postinstall $HOME/.ghq/$GIT_REPO/npm-script-timings/another-project/node_modules/npm-script-timings
> echo "##### postinstall #####"

##### postinstall #####
added 1 package and audited 1 package in 12.331s
found 0 vulnerabilities

まとめ

npmリポジトリから取得するときと違って、gitリポジトリから直接取得しようとしたときにはnpm prepacknpm postpackが追加で動作するようです。
npmリポジトリに登録をしないときにはnpm publishをするタイミングがないので代わりにnpm packが行われる、というイメージでしょうか。

おまけ

TypeScript で作ったパッケージを TravisCI で npm に公開するときの Tipsでも述べられてる.gitignore.npmignoreの動作に気付かずに同じハマり方しました…。

Why do not you register as a user and use Qiita more conveniently?
  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