Node.js初学者の学習メモ

# 概要

Node.jsでのアプリケーション開発の基礎を理解するために、簡単なアプリケーションを作成して実行するところまで試してみました。
記事の後半はnpmでのパッケージ管理とnodistのインストールについて記述しています。


**環境**

* Windows7 (64bit)
* Node.js 4.2.2
* npm 3.4.0

**参考**

* [Node.js] (https://nodejs.org/en/)
 * [Node.js v4.2.2 Documentation] (https://nodejs.org/docs/v4.2.2/api/index.html)
* [npm] (https://www.npmjs.com/)
 * [express] (https://www.npmjs.com/package/express)
     * [express-generator] (https://www.npmjs.com/package/express-generator)
 * [mongodb] (https://www.npmjs.com/package/mongodb)
     * [Node.js MongoDB Driver API] (http://mongodb.github.io/node-mongodb-native/2.0/api/index.html)
     * [Getting Started with MongoDB (Node.js Edition)] (https://docs.mongodb.org/getting-started/node/)
 * [lodash] (https://www.npmjs.com/package/lodash)
     * [lodash documentation] (https://lodash.com/docs)
 * [moment] (https://www.npmjs.com/package/moment)
     * [Moment.js Documentation] (http://momentjs.com/docs/) 
 * [eslint] (https://www.npmjs.com/package/eslint)
* [npm package.json 取扱説明書] (http://liberty-technology.biz/PublicItems/npm/package.json.html)
* [nodist] (https://github.com/marcelklehr/nodist)


## Node.js

### http

Node.jsのHTTP APIを使用したwebアプリケーションのデモです。

アプリケーションコード

```js:http_demo.js
console.log("http start");

var http = require("http");
var fs = require("fs");

var server = http.createServer(function (req, res) {
  var body = fs.readFileSync("response.html", "utf-8");
  res.writeHead(200, {
    "Content-Length": body.length,
    "Content-Type": "text/html"
  });
  res.write(body);
  res.end();
});
server.listen(3000, "127.0.0.1");
```

(2015/11/12)上記のコードを下記のように書き直しました。
上記のソースコードではresponse.htmlの読み込みに`fs.readFileSync`を使用していますが、これだとファイル読み込みが同期処理になるためNode.jsの良さが損なわれてしまいます。
このような場合は`fs.createReadStream`を使用すると非同期でファイルの読み込みができます。
なお`stream.on`でイベント毎にcallbackを設定することができます。

```js:http_demo2.js
"use strict"
console.log("http start");

const http = require("http");
const fs = require("fs");

const server = http.createServer(function (req, res) {
  let stream = fs.createReadStream(__dirname + "/response.html", {encoding: "utf-8"});

  stream.on("open", function(){
    console.log("open stream");
  });
  stream.on("close", function(){
    console.log("close stream");
  });
  stream.on("end", function(){
    console.log("end stream");
  });

  res.writeHead(200, {
//    "Content-Length": body.length,
    "Content-Type": "text/html"
  });
  stream.pipe(res);
});
server.listen(3000, "127.0.0.1");
```


表示するhtmlファイルを作成します。

```html:response.html
<!DOCTYPE html>
<html>
<head>
  <title>demo</title>
</head>
<body>
  <div>
    <h1>demo application</h1>
  </div>
</body>
</html>
```

実行します。

```bat:run
> node http_demo
```

アプリケーションが起動したら下記のURLにアクセスして"demo application"というメッセージがブラウザに表示されることを確認します。
http://localhost:3000/


### [express] (https://www.npmjs.com/package/express)

expressフレームワークを使用したwebアプリケーションのデモです。

```bat:install
> npm install express --save
```

デモコード

```js:express_demo.js
console.log("app start");

var express = require("express");
var app = express();

app.get("/", function (req, res) {
  res.send("Hello World");
});

app.listen(3000);
```

実行します。

```bat:run
> node express_demo
```

アプリケーションが起動したら下記のURLにアクセスして"Hello World"というメッセージがブラウザに表示されることを確認します。
http://localhost:3000/


### [express-generator] (https://www.npmjs.com/package/express-generator)

express-generatorで生成したexpressアプリケーションを実行するデモです。

```bat:install
> npm install express-generator --save-dev
```

上記の方法でインストールするとカレントディレクトリ下の`node_modules\.bin`にexpressコマンドが用意されます。
雛形はこのコマンドを実行して作成します。

```bat:create
> .\node_modules\.bin\express
destination is not empty, continue? [y/N] y

   create : .
   create : ./package.json
   create : ./app.js
   create : ./public/stylesheets
   create : ./public/stylesheets/style.css
   create : ./routes
   create : ./routes/index.js
   create : ./routes/users.js
   create : ./public
   create : ./public/javascripts
   create : ./public/images
   create : ./views
   create : ./views/index.jade
   create : ./views/layout.jade
   create : ./views/error.jade
   create : ./bin
   create : ./bin/www

   install dependencies:
     > cd . && npm install

   run the app:
     > SET DEBUG=npm_test:* & npm start

```

依存関係にあるパッケージをインストールします。

```bat:dependecies_install
> npm install
```

実行します。

```bat:run
> SET DEBUG=npm_test:* & npm start

> npm_test@0.0.0 start D:\dev\node_workspace\npm_test
> node ./bin/www

  npm_test:server Listening on port 3000 +0ms
```

ここで実行した`npm start`というコマンドは、package.jsonのscirptsプロパティに定義されているstartタスクを実行します。
startタスクは下記のように定義されているので、実際に実行されるのは"./bin/wwww"というスクリプトになります。

```json:package.json
{
  "scripts": {
    "start": "node ./bin/www"
  },
}
```

アプリケーションが起動したら下記のURLにアクセスして"Express"というメッセージがブラウザに表示されることを確認します。
http://localhost:3000/


### [mongodb] (https://www.npmjs.com/package/mongodb)

MongoDB Node.JS Driverを使用してMongoDBに接続するデモです。
このDriverをラップした[mongoose] (https://www.npmjs.com/package/mongoose)というパッケージもあります。

```bat:install
> npm install mongodb --save

...省略...

npm_test@0.0.0 D:\dev\node_workspace\npm_test
└─┬ mongodb@2.0.48
  ├── es6-promise@2.1.1
  ├── UNMET PEER DEPENDENCY kerberos@~0.0
  ├─┬ mongodb-core@1.2.21
  │ └── bson@0.4.19
  └─┬ readable-stream@1.0.31
    ├── core-util-is@1.0.1
    ├── isarray@0.0.1
    └── string_decoder@0.10.31

npm WARN EPEERINVALID mongodb-core@1.2.21 requires a peer of kerberos@~0.0 but none was installed.
```

kerberosパッケージがインストール出来なかったようなので、個別にインストールしました。

```bat:install
> npm install kerberos --save

...省略...

npm_test@0.0.0 D:\dev\node_workspace\npm_test
└─┬ kerberos@0.0.17
  └── nan@2.0.9
```

デモコード

```js:mongodb_demo.js
"use strict";

var MongoClient = require("mongodb").MongoClient;
var assert = require("assert");

const url = "mongodb://localhost:27017/test";
const DOCUMENTS = "documents";

MongoClient.connect(url, function(err, db) {
  assert.equal(null, err);
  console.log("Connected correctly to server");

  deleteDocument(db, function() {
    insertDocuments(db, function(){
      findDocuments(db, function() {
        db.close();
      });
    });
  });

});

var insertDocuments = function(db, callback) {
  var collection = db.collection(DOCUMENTS);

  collection.insertMany([{a : 1}, {a : 2}, {a : 3}],
    function(err, result) {
      assert.equal(err, null);
      console.log("Inserted documents");
      callback(result);
    }
  );
}

var deleteDocument = function(db, callback) {
  var collection = db.collection(DOCUMENTS);

  collection.deleteMany({}, function(err, result) {
    assert.equal(err, null);
    console.log("Removed documents");
    callback(result);
  });
}

var findDocuments = function(db, callback) {
  var collection = db.collection(DOCUMENTS);

  collection.find({}).toArray(function(err, docs) {
    assert.equal(err, null);
    console.log("Found the following records");
    console.dir(docs);
    callback(docs);
  });
}
```

実行します。

```bat:run
> node mongodb_demo
```


### [lodash] (https://www.npmjs.com/package/lodash)

[lodash] (https://lodash.com/)はJavascriptのユーティリティライブラリーです。
このlodashをNode.jsで使用したデモです。

```bat:install
> npm install lodash --save
```

デモコード

```js:lm.js
"use strict";

var _ = require("lodash");


const cols = [1, 2, 3, 4, 5];
const objs = {"a":1, "b": 2, "c":3 };

/*
 * Array
 */

var resd = _.drop(cols, 2);
console.log(resd);
// ⇒ [ 3, 4, 5 ]

var resf = _.first(cols);
console.log(resf);
// ⇒ 1

var resl = _.last(cols)
console.log(resl);
// ⇒ 5


/*
 * Collection
 */


var resm = _.map(cols, (n) => {
  return n * 3;
});
console.log(resm);
// ⇒ [ 3, 6, 9, 12, 15 ]


_.forEach(objs, (n, key) => {
  console.log(n, key);
  // ⇒ 1 'a'
  // ⇒ 2 'b'
  // ⇒ 3 'c'
});


var resr = _.reduce(cols, (total, n) => {
  return total + n;
});
console.log(resr);
// ⇒ 15


/*
 * Date
 */

console.log(_.now());
// ⇒ 1447080518885


/*
 * Lang
 */

var resa = _.isArray(cols);
console.log(resa);
// ⇒ true

var reso = _.isObject(objs);
console.log(reso);
// ⇒ true

var ress = _.isString("abc");
console.log(ress);
// ⇒ true

var resn = _.isNumber(8.4);
console.log(resn);
// ⇒ true

var resd = _.isDate(new Date);
console.log(resd);
// ⇒ true


/*
 * Number
 */
_.times(10, function(){
  console.log(_.random(0, 5));
  // ⇒ 5
  // ⇒ 1
  // ⇒ 5
  // ⇒ 2
  // ⇒ 5
  // ⇒ 5
  // ⇒ 5
  // ⇒ 1
  // ⇒ 0
  // ⇒ 0
});


/*
 * String
 */

var rese = _.escape("<img src='/public/img/face.img'>IMG</img>");
console.log(rese);
// ⇒ &lt;img src=&#39;/public/img/face.img&#39;&gt;IMG&lt;/img&gt;

var rest = _.trunc('15Th ANNIVERSARY History of MONKEY MAJIK', 30);
console.log(rest);
// ⇒ 15Th ANNIVERSARY History of...


/*
 * Utility
 */

var resu = _.range(0, 5);
console.log(resu);
// ⇒ [ 0, 1, 2, 3, 4 ]
```

実行します。

```bat:run
> node lm
```


### [moment] (https://www.npmjs.com/package/moment)

[Moment.js] (http://momentjs.com/)はJavaScriptのDateオブジェクトをより簡単に扱うことができるライブラリーです。
このmomentをNode.jsで使用したデモです。

```bat:install
> npm install moment --save
```

デモコード

```js:mm.js
"use strict";

var moment = require("moment");

var current = moment(new Date());

//This is essentially the same as calling moment(new Date())
//var current = moment();


/*
 * format
 */

console.log( current.format() );
// ⇒ 2015-11-09T21:43:31+09:00
console.log( current.format("YYYY-MM-DD") );
// ⇒ 2015-11-09
console.log( current.format("YYYY-MM-DD HH:mm:ssZ") );
// ⇒ 2015-11-09 21:43:31+09:00


/*
 * String to Date
 */

var d1 = moment("2015-11-09 21:35:43.123");
console.log( d1.format("YYYY-MM-DD HH:mm:ssZ") );
// ⇒ 2015-11-09 21:35:43+09:00


/*
 * Object to Date
 */

var d2 = moment({ y:2015, M:10, d:9, h:21, m:35, s:43, ms:123 });
console.log( d2.format("YYYY-MM-DD HH:mm:ssZ") );
// ⇒ 2015-11-09 21:35:43+09:00


/*
 * validation
 */

/*
invalidAt()

0: years
1: months
2: days
3: hours
4: minutes
5: seconds
6: milliseconds
*/

var m = moment("2015-11-31 21:35:43");
console.log( m.isValid() );
// ⇒ false
console.log( m.invalidAt() );
// ⇒ 2


/*
 * set
 */

var d3 = moment();
console.log( d3.format("YYYY-MM-DD HH:mm:ssZ") );
// ⇒ 2015-11-09 21:43:31+09:00

d3.date(1);
console.log( d3.format("YYYY-MM-DD HH:mm:ssZ") );
// ⇒ 2015-11-01 21:43:31+09:00


/*
 * get
 */

var d4 = moment();
console.log("%d-%d-%d %d:%d:%d.%d", d4.get("year"), d4.get("month")+1, d4.get("date"), d4.get("hour"), d4.get("minute"), d4.get("second"), d4.get("millisecond"));
// ⇒ 2015-11-9 21:43:31.41
```

実行します。

```bat:run
> node mm
```


### [eslint] (https://www.npmjs.com/package/eslint)

eslintで構文チェックを行うデモです。

```bat:install
> npm install -g eslint
```

基本的なルールの設定を行います。
選択肢を<kbd>1</kbd> or <kbd>2</kbd>、又は:arrow_up: :arrow_down:キーで選び<kbd>Space</kbd>で決定します。
設定したルールは".eslintrc"ファイルに記録されます。このファイルをカスタマイズして構文チェックのルールを拡張することができます。

```bat
> eslint --init
? What style of indentation do you use? Spaces
? What quotes do you use for strings? Double
? What line endings do you use? Windows
? Do you require semicolons? Yes
? Are you using ECMAScript 6 features? Yes
? Where will your code run? Node
? Do you use JSX? No
? What format do you want your config file to be in? JSON
Successfully created .eslintrc file in D:\dev\node_workspace\npm_test
```

構文チェックを行います。

```bat
> eslint app.js

D:\dev\node_workspace\npm_test\app.js
  1:1  error  Unexpected console statement                            no-console
  7:3  error  Expected indentation of 4 space characters but found 2  indent

✖ 2 problems (2 errors, 0 warnings)
```


### debug

express-generetorで生成した雛形アプリケーションで、2種類のdebugの方法を確認しました。

#### consoleでdebugする

ブレークポイントに`debugger`を記述します。

```js:index.js
var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  debugger;
  res.render('index', { title: 'Express' });
});

module.exports = router;
```

debugモードでアプリケーションを起動します。

```bat:debug
> node debug .\bin\www
```

consoleがdebugモードに切り替わります。
アプリケーションの起動時に一旦停止するので<kbd>c</kbd>を入力して継続します。

```bat
< Debugger listening on port 5858
debug> . ok
break in D:\dev\node_workspace\npm_test\bin\www:7
  5  */
  6
> 7 var app = require('../app');
  8 var debug = require('debug')('npm_test:server');
  9 var http = require('http');
debug> c
```

ブラウザから`http://localhost:3000/`にアクセスします。
ブレークポイントで処理が停止するので、プロンプトにreplと入力します。

```bat
break in D:\dev\node_workspace\npm_test\routes\index.js:6
  4 /* GET home page. */
  5 router.get('/', function(req, res, next) {
> 6   debugger;
  7   res.render('index', { title: 'Express' });
  8 });
debug> repl
Press Ctrl + C to leave debug repl
```

停止しているコンテキスト内の変数の状態を確認できます。
replから抜けるには<kbd>Ctrl</kbd> + <kbd>c</kbd>を押します。

```bat
> req.headers
{ host: 'localhost:3000',
  connection: 'keep-alive',
  'cache-control': 'max-age=0',
  accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
  'upgrade-insecure-requests': '1',
  'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrom... (length: 108)',
  'accept-encoding': 'gzip, deflate, sdch',
  'accept-language': 'ja,en-US;q=0.8,en;q=0.6',
  'if-none-match': 'W/"aa-SNfgj6aecdqLGkiTQbf9lQ"' }
> Ctrl + c
debug>
```

処理を再開するには<kbd>c</kbd>(continue)を押します。
処理を継続するには<kbd>n</kbd>(next)、<kbd>s</kbd>(step in)、<kbd>o</kbd>(step out)を押します。


#### node-inspectorでdebugする

もう1つのdebug方法としてnode-inspectorパッケージを利用する方法があります。

```bat:install
> npm install node-inspector -g
```

アプリケーションの起動時に'--debug'オプションを付けます。

```bat:debug
> node --debug .\bin\www
Debugger listening on port 5858
```

別のウィンドウでnode-inspectorを起動します。

```bat:node-inspector
> node-inspector
Node Inspector v0.12.3
Visit http://127.0.0.1:8080/?ws=127.0.0.1:8080&port=5858 to start debugging.
```

ブラウザで`http://127.0.0.1:8080/?ws=127.0.0.1:8080&port=5858`にアクセスしてデバッグ画面を表示します。
この例ではブレークポイントを下図の箇所へセットしました。

![in01.png](https://qiita-image-store.s3.amazonaws.com/0/22772/6ce164cf-d7f1-449c-ebd0-321b0ffb6fcb.png)

次にアプリケーションのページ`http://localhost:3000/`にアクセスします。

consoleでdebugしたときと同じように停止しているコンテキスト内の変数を確認することができます。

![in02.png](https://qiita-image-store.s3.amazonaws.com/0/22772/f45f6ae3-a54a-c692-1005-06085fb7f3eb.png)


### module

expressが使用しているモジュールを例にmoduleの定義と使用方法を確認します。
モジュールを使用するには下記のようにrequire関数を使用します。
この関数を実行すると、そのモジュールにpackage.jsonファイルがあればmainプロパティで定義されているスクリプトが実行されます。

```js:require
var mod = require("モジュール名");
```

#### [parseurl] (https://github.com/pillarjs/parseurl)

##### package.json

このモジュールのpackage.jsonにはmainプロパティがありませんが、このプロパティが省略されたときは"index.js"がデフォルト値となります。

```json:package.json
{
  ...省略...
  "name": "parseurl",
  "optionalDependencies": {},
  "readme": "ERROR: No README data found!",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/expressjs/parseurl.git"
  },
  "scripts": {
    "bench": "node benchmark/index.js",
    "test": "mocha --check-leaks --bail --reporter spec test/",
    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --check-leaks --reporter dot test/",
    "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --check-leaks --reporter spec test/"
  },
  "version": "1.3.0"
}
```

##### index.js

index.jsには4つの関数が定義されています。
このうち`parseurl`関数と`originalurl`関数がモジュールとして公開されます。残りの2つの関数はこのモジュール内でのみ利用でき外部からは参照できません。

```js:public
module.exports = parseurl
module.exports.original = originalurl
```

```js:index.js
/*!
 * parseurl
 * Copyright(c) 2014 Jonathan Ong
 * Copyright(c) 2014 Douglas Christopher Wilson
 * MIT Licensed
 */

...省略...

/**
 * Exports.
 */

module.exports = parseurl
module.exports.original = originalurl

/**
 * Parse the `req` url with memoization.
 *
 * @param {ServerRequest} req
 * @return {Object}
 * @api public
 */

function parseurl(req) {
  ...省略...
};

/**
 * Parse the `req` original url with fallback and memoization.
 *
 * @param {ServerRequest} req
 * @return {Object}
 * @api public
 */

function originalurl(req) {
  ...省略...
};

/**
 * Parse the `str` url with fast-path short-cut.
 *
 * @param {string} str
 * @return {Object}
 * @api private
 */

function fastparse(str) {
  ...省略...
}

/**
 * Determine if parsed is still fresh for url.
 *
 * @param {string} url
 * @param {object} parsedUrl
 * @return {boolean}
 * @api private
 */

function fresh(url, parsedUrl) {
  ...省略...
}
```

##### moduleの使用

下記のように`require("parseurl")`を実行すると、index.jsで`export.modules`に代入した`parseurl`関数が戻り値として返されます。

```js:routes/index.js
var express = require('express');
var parseurl = require("parseurl");
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  var p = parseurl(req);
  console.log(p);
  var o = parseurl.original(req);
  console.log(o);
  res.render('index', { title: 'Express' });
});

module.exports = router;
```

#### [debug] (https://github.com/visionmedia/debug)

> tiny node.js & browser debugging utility for your libraries and applications

##### package.json

mainプロパティに"./node.js"が設定されているので、require関数を呼ぶとnode.jsが実行されます。
ちなみに同じディレクトリ内にbrowser.jsというファイルもあり、実行環境によりnode.jsかbrowser.jsのどちらかが実行されるようです。

```json:package.json
{
  ...省略...
  "main": "./node.js",
  "maintainers": [
    {
      "name": "tjholowaychuk",
      "email": "tj@vision-media.ca"
    },
    {
      "name": "tootallnate",
      "email": "nathan@tootallnate.net"
    }
  ],
  "name": "debug",
  "optionalDependencies": {},
  "readme": "ERROR: No README data found!",
  "repository": {
    "type": "git",
    "url": "git://github.com/visionmedia/debug.git"
  },
  "scripts": {},
  "version": "2.2.0"
}
```

##### node.js

node.jsの中ではさらに"debug.js"が呼ばれます。

```js:node.js
/**
 * This is the Node.js implementation of `debug()`.
 *
 * Expose `debug()` as the module.
 */

exports = module.exports = require('./debug');
exports.log = log;
exports.formatArgs = formatArgs;
exports.save = save;
exports.load = load;
exports.useColors = useColors;

...省略...
```

##### debug.js

```js:debug.js
/**
 * This is the common logic for both the Node.js and web browser
 * implementations of `debug()`.
 *
 * Expose `debug()` as the module.
 */

exports = module.exports = debug;
exports.coerce = coerce;
exports.disable = disable;
exports.enable = enable;
exports.enabled = enabled;
exports.humanize = require('ms');

/**
 * Select a color.
 *
 * @return {Number}
 * @api private
 */

function selectColor() {
...省略...
}

/**
 * Create a debugger with the given `namespace`.
 *
 * @param {String} namespace
 * @return {Function}
 * @api public
 */

function debug(namespace) {
...省略...
}

/**
 * Enables a debug mode by namespaces. This can include modes
 * separated by a colon and wildcards.
 *
 * @param {String} namespaces
 * @api public
 */

function enable(namespaces) {
...省略...
}

/**
 * Disable debug output.
 *
 * @api public
 */

function disable() {
...省略...
}

/**
 * Returns true if the given mode name is enabled, false otherwise.
 *
 * @param {String} name
 * @return {Boolean}
 * @api public
 */

function enabled(name) {
...省略...
}

/**
 * Coerce `val`.
 *
 * @param {Mixed} val
 * @return {Mixed}
 * @api private
 */

function coerce(val) {
...省略...
}
```

##### moduleの使用

wwwスクリプトでは下記のように使用しています。2つ目のカッコの値(`exp-example:server`)はdebug関数の引数として渡すnamespaceになります。

```js:www
var debug = require('debug')('exp-example:server');
```


## npm (Node Package Manager)

### package.json

パッケージの情報はpackage.jsonというファイルに記述します。
nameおよびversionは必須で、この項目によりパッケージを一意に識別します。
dependenciesには、そのパッケージが依存関係にあるパッケージ（とそのバージョン）を指定します。

***package.jsonの例***

```js:package.json
{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "main": "lib/index.js"
  "scripts": {
    "start": "node app",
    "test": "echo run test"
  },
  "dependencies": {
    "express": "3.0.0rc5",
    "jade": "*",
    "log4js": "1.0"
  }
}
```


### パッケージのインストール

ローカルインストールの場合、パッケージは`./node_modules`にインストールされます。

package.jsonに記述されている依存関係にあるパッケージをローカルにインストールします。

```bat
> npm install
```

パッケージ名で指定するパッケージをローカルにインストールします。

```bat
> npm install <パッケージ名>
```

パッケージ名で指定するパッケージをローカルにインストールし、package.jsonのdependenciesに追記します。

```bat
> npm install <パッケージ名> --save
```

パッケージ名で指定するパッケージをローカルにインストールし、package.jsonのdevDependenciesに追記します。

```bat
> npm install <パッケージ名> --save-dev
```

ローカルにインストールしたパッケージを一覧表示します。

```bat
> npm list
```

パッケージ名で指定するパッケージのpackage.jsonの内容を表示します。

```bat
> npm info <パッケージ名>
```

グローバルインストールの場合のインストール先は`npm bin -g`で確認できます。

```bat
> npm bin -g
C:\Users\%USERNAME%\git\nodist\bin
```

パッケージ名で指定するパッケージをグローバルインストールします。

```bat
> npm install -g <パッケージ名>
```

グローバルインストールしたパッケージを一覧表示します。

```bat
> npm list -g
```


#### npm ERR! extraneous

パッケージはインストールされているのに、package.jsonの依存関係にそのパッケージが記述されていない場合に発生します。
この場合はもう一度インストールを行うことで解決することができます。

```bat:list
> npm list

...省略...

npm ERR! extraneous: express-generator@4.13.1 D:\dev\node_workspace\exp-example\node_modules\express-generator
```

```bat
> npm install express-generator --save-dev
```


### scriptの実行

package.jsonのscripts要素にタスクを定義することができます。

```json:package.json_scirpts
{
  "scripts": {
    "start": "node app",
    "test": "echo run test",
    "lint": "eslint *.js || exit 0"
  }
}
```

runコマンドで定義されているタスクの一覧を確認することができます。

```bat:run
> npm run
Lifecycle scripts included in npm_test:
  test
    echo app test
  start
    node app

available via `npm run-script`:
  lint
    eslint *.js || exit 0
```

タスクの実行は下記のようにrunコマンドの後にタスク名を指定します。
この例ではlintタスクを実行します。

```bat:lint
> npm run list
```

start,restart,stop,testなどのデフォルトのタスクは、実行時に"run"を付ける必要はありません。

```bat
npm start
npm restart
npm stop
npm test
```


## インストールメモ

### [nodist] (https://github.com/marcelklehr/nodist)

Windows環境で異なるバージョンのNodeを切り替えるためのツールとしてnodistを利用します。
インストールはgithubの説明の通りに行いました。

```bash:clone
$ git clone git://github.com/marcelklehr/nodist.git
Cloning into 'nodist'...
remote: Counting objects: 4857, done.
remote: Total 4857 (delta 0), reused 0 (delta 0), pack-reused 4857
Receiving objects: 100% (4857/4857), 10.74 MiB | 337.00 KiB/s, done.
Resolving deltas: 100% (1914/1914), done.
Checking connectivity... done.
Checking out files: 100% (1603/1603), done.
```

環境変数の登録

|environment   |value                                       |
|:-------------|:-------------------------------------------|
|NODIST_PREFIX |C:\Users\%USERNAME%\git\nodist              |
|PATH          |%NODIST_PREFIX%\bin;%PATH%                  |
|NODE_PATH     |%NODIST_PREFIX%\bin\node_modules;%NODE_PATH%|


```bat:selfupdate
> nodist selfupdate
Installing latest stable version...
nodev5.0.0
Update dependencies...
npm http GET https://registry.npmjs.org/request
npm http GET https://registry.npmjs.org/mkdirp
npm http GET https://registry.npmjs.org/semver
npm http GET https://registry.npmjs.org/rimraf
npm http GET https://registry.npmjs.org/vows
npm http 200 https://registry.npmjs.org/rimraf
npm http 200 https://registry.npmjs.org/mkdirp
npm http 200 https://registry.npmjs.org/semver
npm http 200 https://registry.npmjs.org/vows
npm http 200 https://registry.npmjs.org/request
npm http GET https://registry.npmjs.org/mkdirp/0.3.5
npm http GET https://registry.npmjs.org/rimraf/2.4.3
npm http GET https://registry.npmjs.org/semver/5.0.3
npm http GET https://registry.npmjs.org/request/2.9.203
npm http GET https://registry.npmjs.org/vows/0.9.0-rc3
npm http 200 https://registry.npmjs.org/semver/5.0.3
npm http GET https://registry.npmjs.org/semver/-/semver-5.0.3.tgz
npm http 200 https://registry.npmjs.org/vows/0.9.0-rc3
npm http GET https://registry.npmjs.org/vows/-/vows-0.9.0-rc3.tgz
npm http 200 https://registry.npmjs.org/mkdirp/0.3.5
npm http 200 https://registry.npmjs.org/request/2.9.203
npm http GET https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz
npm http GET https://registry.npmjs.org/request/-/request-2.9.203.tgz
npm http 200 https://registry.npmjs.org/request/-/request-2.9.203.tgz
npm http 200 https://registry.npmjs.org/rimraf/2.4.3
npm http GET https://registry.npmjs.org/rimraf/-/rimraf-2.4.3.tgz
npm http 200 https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz
npm http 200 https://registry.npmjs.org/rimraf/-/rimraf-2.4.3.tgz
npm http 200 https://registry.npmjs.org/semver/-/semver-5.0.3.tgz
npm http GET https://registry.npmjs.org/glob
mkdirp@0.3.5 node_modules\mkdirp
semver@5.0.3 node_modules\semver
request@2.9.203 node_modules\request
npm http 200 https://registry.npmjs.org/glob
npm http GET https://registry.npmjs.org/minimatch
npm http GET https://registry.npmjs.org/once
npm http GET https://registry.npmjs.org/path-is-absolute
npm http GET https://registry.npmjs.org/inflight
npm http GET https://registry.npmjs.org/inherits
npm http 200 https://registry.npmjs.org/vows/-/vows-0.9.0-rc3.tgz
npm http 200 https://registry.npmjs.org/once
npm http 304 https://registry.npmjs.org/inherits
npm http 200 https://registry.npmjs.org/minimatch
npm http 200 https://registry.npmjs.org/inflight
npm http GET https://registry.npmjs.org/eyes
npm http GET https://registry.npmjs.org/diff
npm http GET https://registry.npmjs.org/glob/-/glob-4.3.5.tgz
npm http 200 https://registry.npmjs.org/path-is-absolute
npm http 200 https://registry.npmjs.org/eyes
npm http 200 https://registry.npmjs.org/glob/-/glob-4.3.5.tgz
npm http GET https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz
npm http GET https://registry.npmjs.org/brace-expansion
npm http GET https://registry.npmjs.org/wrappy
npm http 200 https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz
npm http 200 https://registry.npmjs.org/wrappy
npm http 200 https://registry.npmjs.org/brace-expansion
npm http GET https://registry.npmjs.org/balanced-match
npm http GET https://registry.npmjs.org/concat-map/0.0.1
npm http 200 https://registry.npmjs.org/balanced-match
npm http 200 https://registry.npmjs.org/diff
npm http GET https://registry.npmjs.org/diff/-/diff-1.2.2.tgz
npm http 200 https://registry.npmjs.org/concat-map/0.0.1
npm http GET https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz
npm http 200 https://registry.npmjs.org/diff/-/diff-1.2.2.tgz
npm http 200 https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz
rimraf@2.4.3 node_modules\rimraf
└── glob@5.0.15 (path-is-absolute@1.0.0, inherits@2.0.1, inflight@1.0.4, once@1.3.2, minim
vows@0.9.0-rc3 node_modules\vows
├── diff@1.2.2
├── eyes@0.1.8
└── glob@4.3.5 (inherits@2.0.1, once@1.3.2, inflight@1.0.4, minimatch@2.0.10)

> nodist 
> nodev5.0.0  (global)
```

Node.js v4.2.2のインストール

```bat:install_v4.2.2
> nodist 4.2.2
nodev4.2.2

> nodist list
> nodev4.2.2  (global)
  nodev5.0.0

> node -v
v4.2.2
```

Node.js v0.10.40のインストール

```bat:install_v0.10.40
> nodist 0.10.40
nodev0.10.40

> nodist list
> nodev0.10.40  (global)
  nodev4.2.2
  nodev5.0.0

> node -v
v0.10.40
```

npmのアップデート

```bat:update_npm
> npm -v
1.4.6

> npm update -g npm
npm http GET https://registry.npmjs.org/npm
npm http 200 https://registry.npmjs.org/npm
npm http GET https://registry.npmjs.org/npm/3.4.0
npm http 200 https://registry.npmjs.org/npm/3.4.0
npm http GET https://registry.npmjs.org/npm/-/npm-3.4.0.tgz
npm http 200 https://registry.npmjs.org/npm/-/npm-3.4.0.tgz
C:\Users\%USERNAME%\git\nodist\bin\npm -> C:\Users\%USERNAME%\git\nodist\bin\node_modules\npm\bin\npm-cli.js
npm@3.4.0 C:\Users\%USERNAME%\git\nodist\bin\node_modules\npm

> npm -v
3.4.0
```

設定を確認しprefixが登録されていなければこのコマンドを実行します。

```bat
> npm config list

> npm config set prefix "%NODIST_PREFIX%\bin"
```

## メモ

### process.versions

Node.jsと依存ライブラリーのバージョンを調べる方法

```bat:cmd
> node -p process.versions.v8
4.5.103.35
```

もしくはコマンドプロンプトよりnodeコマンドを実行して対話モード(repl)に入ります。

```bat:cmd
> node
```

replのプロンプトで下記のように入力します。

```bat:repl
> process.versions
{ http_parser: '2.5.0',
  node: '4.2.2',
  v8: '4.5.103.35',
  uv: '1.7.5',
  zlib: '1.2.8',
  ares: '1.10.1-DEV',
  icu: '56.1',
  modules: '46',
  openssl: '1.0.2d' }
```

|lib         |site|
|:-----------|:---------------------|
|http_parser |[HTTP Parser] (https://github.com/nodejs/http-parser) |
|node        |[nodejs] (https://github.com/nodejs/node) |
|v8          |[V8 JavaScript Engine] (https://code.google.com/p/v8/) |
|            |[v8/v8.git - Git at Google] (https://chromium.googlesource.com/v8/v8.git) |
|uv          |[libuv] (https://github.com/libuv/libuv) |
|zlib        |[zlib] (http://www.zlib.net/) |
|ares        |[c-ares] (http://c-ares.haxx.se/) |
|icu         |[ICU - International Components for Unicode] (http://site.icu-project.org/)|
|modules     |? |
|openssl     |[OpenSSL] (https://www.openssl.org/) |


### ES6

Node.js 4.0よりECMAScript2015(ES6)をサポートしています。
デフォルトで使用できる機能

> [ECMAScript 2015 (ES6) in Node.js] (https://nodejs.org/en/docs/es6/)
> 
> * Block scoping
>  * let (strict mode only)
>  * const
>  * function-in-blocks (strict mode only)
> * Classes (strict mode only)
> * Collections
>  * Map
>  * WeakMap
>  * Set
>  * WeakSet
> * Typed arrays
> * Generators
> * Binary and Octal literals
> * Object literal extensions (shorthand properties and methods)
> * Promises
> * New String methods
> * Symbols
> * Template strings
> * Arrow Functions
> * new.target
> * Object.assign
> * Spread operator

#### Block scope

今まではこのように記述していたrequireは、

```js
var app = require("../app");
```

このようにconstにした方が良いようです。

```js:ES6
const app = require("../app");
```

[const vs var while 'requiring' a module] (http://stackoverflow.com/questions/23483926/const-vs-var-while-requiring-a-module)