yano3nora
7/2/2017 - 1:43 PM

[nodejs: npm] npm - nodejs package manager. #nodejs #js

[dev: Node.js / npm] Server side JavaScript runtime. #dev #js

NODE.JS

nodejs.org

JavaScript ( EcmaScript2015 準拠 ) 実行環境。JS エンジンは Chrome の V8 JavaScript エンジン (C++ で実装されてるらしい) を採用しており軽量で効率的に動作する。

非同期型・ノンブロッキング I/O・シングルスレッド・イベント駆動モデル。サーバに入れて nginx のような JS 駆動 WEB サーバ構築したり、開発環境にいれて webpack などのバンドルツールを動作させたりできる。

Version & EcmaScript Support

Node.js Dual Packages (CommonJS/ES Modules) に対応した npm パッケージの開発

  • Node.js の書く version と ES20xx の対応状況は node.green にまとまってる
  • Node v13.2.0 からは ESM (EcmaScript Modules, import とかのやつ) に完全対応してたぽい
  • 従来の CJS (CommonJS, require() とか module.exports とか使うやつ) も暫くは生きそう

Install via nodenv (macOS)

nodenv/nodenv - github.com
nodenv/node-build - github.com
nodenv/node-build-update-defs
nodenv を使って Mac に Node.js の環境を構築する

追記: 最近言語ランタイムのバージョン管理は anyenv 経由で nodenv を入れて環境構築する方向に統一した

rbenv の node.js 版。ローカルの Node.js バージョンはまちまちになりやすいので管理しといた方が楽そう。macOS 限定。

# Install
$ brew install nodenv

# シェル起動時のコマンドを設定
$ nodenv init         # .bash_profile などに何を書けばいいか教えてくれるので
$ vi ~/.bash_profile  # お使いのシェルの定義ファイルに追記してやる

# バージョンのインストール / アンインストール
$ nodenv install {VERSION}  # 公式みて stable 適当に入れるのがよさそう
$ nodenv uninstall {VERSION}

# インストール済バージョンリスト
$ nodenv versions

# インストールしたバージョンを
# グローバル or ローカル
# (プロジェクトディレクトリ) に適用
$ nodenv global {VERSION}  # stable とかでよさそう
$ nodenv local {VERSION}   # プロジェクトに応じて

Windows は nodist っていうのがあるけど、ちょっと動作不安定だった。素直に macOS 使うかアンインストール & msi インストールしてください。

Raw Install

Windows 環境の場合は インストーラ によるインストールか Chocolatey でのパッケージインストール が利用可能。

# For Linux.
$ sudo yum remove -y nodejs npm
$ curl -sL https://rpm.nodesource.com/setup_8.x | sudo bash -
$ sudo yum install -y nodejs
$ npm install -g n
$ sudo n stable
$ node -v  #8.*
$ sudo n 6.*
$ node -v  #6.*
// Node.js ではモジュール呼び出しを require() で行える
'use strict';
var $ = require('jQuery');
$(function() {
  $('h1').css('color', 'red');
})

// Babel でうにょってれば es6 準拠な import を使ってもいいよね
import $ from "jquery";
$(function() {
  $('h1').css('color', 'red');
})

NPM

npmjs.com
docs.npmjs.com

npm - Node package manager は Node.js 環境下で標準的に利用できるパッケージ管理ツール。JavaScript モジュールのバージョンや依存関係を管理する。npm には -g で表現する「グローバル領域」と npm init により初期化した「ローカル領域」がある。基本的にはプロジェクトを跨いで利用するパッケージを「グローバル」に、プロジェクト毎に異なるバージョンを利用するパッケージを「ローカル」にインストールすることになる。

パッケージ実体は ./node_modules に設置され、その設定は ./package.json および ./package-lock.json に記述される。 これらには当該領域のパッケージリスト、バージョン情報、依存パッケージ情報などが記述されている。また、パッケージの依存性は「実行時依存 dependencies 」と「開発時依存 devDependencies 」などいくつか分かれており、インストール時に --save または -S--save-dev または -D のように指定する。

Commands

# Init local project.
$ npm init   

# Install packages.
$ npm i -S package-name  # Install to local as dependencies.
$ npm i -D package-name  # Install to local as devDependencies.
$ npm i -g package-name  # Install to global.

# List packages.
$ npm list
$ npm list --depth 0     # Top level only.
$ npm list -g --depth 0  # Global packages.

# List package dependencies.
$ npm ls package-name

# Install packages according to package.json
$ npm install

# Reinstall packages according to package-lock.json.
$ npm ci

# Check package updates.
$ npm outdated

# Update packages.
$ npm update

# Clear cache.
$ npm cache clean --force

Prefix

prefix - docs.npmjs.com

# ./my/pkg/dir/package.json に書いてある build コマンドの実行
$ npm run --prefix my/pkg/dir build

Workspaces

workspaces - docs.npmjs.com

// package.json
{
  //...
  "workspaces": [
    "functions"
  ]
}
# 構成こんなとき
#
# - package.json
# - functions/
#     - package.json
#
$ npm run hoge --workspaces  # workspaces 内を探索して実行

Version Commands

npm-version - docs.npmjs.com
Updating the 'version' field within package.json

# From 1.0.0 -> 1.0.1
$ npm version patch 

# From 1.0.1 -> 1.1.0
$ npm version minor

# From 1.1.0 -> 2.0.0
$ npm version major

Dependencies

install-peerdeps ちゃんと使い分けてる? dependenciesいろいろ。

単体では動作しない分離されたパッケージなどは peer dependencies 依存をもつ場合がある。基本的に必要に応じて別途ユーザが選択するものなので、一緒に dependencies / devDependencies に入れるかどうか考慮が必要。

package.json / package-lock.json & npm ci

npm ciを使おう あるいはより速く

通常 npm install を叩くと package.jsonpackage-lock.json を参照し依存解決を行い、package.json のバージョン指定によって「アップデート可能なものがあればアップデートを行い package-lock.json を更新しながら」インストールが実行される。

これは開発を行いつつ、都度依存パッケージのメンテ・マイナーバージョンアップを拾うのに便利だが、CI などでは「ビルド通過実績のある package-lock.json から依存をインストールしたい」ケースがある。このような場合は以下 npm ci コマンドを利用する。

# node_modules を削除し package-lock.json をもとに
# 依存をインストールしなおします
#
$ npm ci

npm-check-updates

npmでインストールされているパッケージを、npm-check-updatesでまとめてアップデートする方法

# グローバルインストール
$ npm install -g npm-check-updates

# 現在のインストールバージョンと最新版の確認
$ ncu
> Using /Users/example/package.json
> autoprefixer  ^6.4.0  →  ^7.1.2
> postcss       ^5.1.0  →  ^6.0.8

# package.json の更新
$ ncu -u

npx

npx - www.npmjs.com
npm 5.2.0の新機能! 「npx」でローカルパッケージを手軽に実行しよう

パッケージバイナリを npm script 抜きで直実行できる便利なやつ。ローカルにインストールしているものはもちろん、npm ライブラリ上のパッケージを「一度きり実行」みたいなこともできる。

# インストールしてないけど一度きり実行
$ npx create-react-app my-app

npm audit

脆弱性の警告を受けたnpmパッケージの依存関係を力技で直す

npm は自動的にリポジトリの脆弱性情報の登録を参照し、現在インストールされているパッケージ群の中から脆弱性のあるものを検査/報告してくれる。このとき npm audit fix を実施すると package.json および package-lock.json を更新し自動的にパッチ適用済みバージョンまで依存パッケージをアップデートし修復してくれる。

当然 package.jsonpackage-lock.json で縛っていたバージョンが進むことによる副作用があるため、実施の際はテストを行うこと。

# 確認
$ npm audit

# 修正してやる!
$ npm audit fix

npm-run-all

mysticatea/npm-run-all - github.com npm-run-allのもっと便利な使い方

  • npm-scripts を同時実行できるやつ
    • run-s で sequential 順次実行 (多分 && みたいな)
    • run-p で parallel 並列実行 (厳密には違うが & みたいな)
  • build:prepare とか build:prod みたいな command 用意して build* とか指定できるようになる
  • 他にも -- で引数を渡したりとか、ビルドスクリプトを npm-scripts で完結するのに便利
$ npm i -D npm-run-all
{
  "scripts": {
    "watch": "run-p watch:*",
    "watch:test": "jest --watch",
    "watch:webpack": "webpack --watch"
  }
}

出力には両方出てくれる、必要十分感。

# jest と webpack の watch を並列実行
$ npm run watch

TIPS & REFERENCES

npm init private

面倒なのでnpm initを実行しない
shanewholloway/npm-create-private

公開しない package なら (というか製品開発ではほぼ公開しない...) これでいいのではというやつ。

# npm v6.1 から存在しない command 実行時に package 探索して
# 一時的に DL → 実行 → package 破棄 ... のようにふるまうので
# ↑ の npm-create-private が global に一瞬 DL されて実行、だと思う
# これ公式でやってくれればいいのにね
#
$ npm init private

{
  "private": true,
  "version": "0.0.0",
  "dependencies": {},
  "devDependencies": {},
  "scripts": {}
}

CLI でファイル実行したときの引数

Node.jsでコマンドライン引数を取得する

$ node test.js myarg
// argv[0], argv[1] にはそれぞれ
// 実行バイナリ、ファイル名が入っている
// 2 以降が引数になるので注意
//
console.log(process.argv[2]);

npm スクリプトが permission denied で弾かれる

npmでpermission deniedになった時の対処法[mac] - Qiita

上記やらんでも権限変更でいけました。

$ chmod -R 755 node_modules

node-sass のビルド環境が前回と違うぞって怒られる

ビルドは走るんだけど以下のようなエラーが出ることがある。

 Node Sass could not find a binding for your current environment: Linux 64-bit with Node.js 8.x

    Found bindings for the following environments:
      - Windows 64-bit with Node.js 9.x

    This usually happens because your environment has changed since running `npm install`.

node-sass のビルドされた環境が前回と違うって怒られてる。この場合はリビルドしてあげれば OK 。

$ npm rebuild node-sass

node-gyp エラーで node-sass がリビルドできない

windows-build-tools
Windowsでnpm installしてnode-gypでつまずいた時対処方法

node-sass ビルド時に Python2 がないよ、みたいなエラーが出る場合は、恐らくプロジェクトの node-sass が古すぎる ( 実行環境の node.js が新しすぎる ) ため必要なビルドパッケージ群を取得しきれずコケている。Windows 環境なら windows-build-tools をぶち込むと依存パッケージのビルドに必要なものを都度取得/ビルドして無理くり通してくれる。

$ npm i -g windows-build-tools  # 2 ~ 30 分くらいかかるかも
$ npm rebuild node-sass         # ビルドに必要なパッケージを死ぬほどビルドしまくって無理くり通す

Windows 環境下の Linux VM などで npm install すると権限エラーが発生

Windows のファイル名に文字数制限ある問題、Windows はファイルパーミッション概念がないけど VM 内の Linux にはある問題などが複雑に入り組んでいるっぽい。基本的に Windows 環境下に VirtualBox などでたてた Linux OS 上では npm コマンドが叩けない と思ったほうがよい。素直にホスト OS 側で叩こう。