search
LoginSignup
143
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Node.jsの開発時に必要な情報(2020年9月更新)

注意
この記事は、2014年の段階でNode.jsの開発時にデバッグ~継続的インテグレーションが行えるようにするために必要な情報をまとめていました。
その後、2020年08月にnode v12.18.3を対象に調査しなおしました。

Node.jsのインストール方法

ここから、インストーラなりソースなり取得してインストールする。

Windows,Macはインストーラが存在している。
Windowsの場合、VS2008や、VS2012などの複数のVisualStudioが混在している環境だとnpm installが失敗することがあった。
その場合は、環境変数を調整してVisualStudioのバージョンを指定して動作するようにしておくこと。

Node.jsのデバッグ方法(2020年)

ローカルのデバッグ

Visual Studio Codeでアプリケーションのあるフォルダを開いて実行すると、デバッグが可能

image.png

chromeを用いてリモートデバッグを行う方法

事前準備

下記の拡張機能をChromeにインストールする。

デバッグ方法

1. デバッグ対象のアプリケーションの起動方法

$ node --inspect=0.0.0.0 hello-world.js
Debugger listening on ws://0.0.0.0:9229/4d491e82-cd7a-4e4c-8ac0-914d14ab95d5
For help, see: https://nodejs.org/en/docs/inspector
Server running at http://192.168.0.100:3000/

2. chromeのNIM拡張機能を開く
image.png

デバッグ対象のホストのアドレスとポートを入力後、「Open DevTools」を開く

3. Chromeでデバッグが行えるようになる。

ブレイクポイントの例
image.png

メモリの使用状況の例
image.png
Chromeの開発者ツールのメモリタブから調べることができる。

なお、かって存在したnode-webkit-agentについてはv0.12では使用できない。
https://github.com/c4milo/node-webkit-agent/issues/78

ガベージコレクションを実行する方法

Node.jsは世代別のガベージコレクションなので、解放したつもりでもメモリが残っている場合がある。そのときは、任意のタイミングでガベージコレクトを行ったあと、メモリのスナップショットを確認する。

ガベージコレクションを確実に走らせたい場合は以下のような処理が必要である。
まず、プログラム中でガベージクレクタを実行したい箇所に次のコードを埋め込む。

if(global.gc) {
  global.gc();
}

gcを使用するにはアプリを起動する際に--expose_gcを指定すること。

node --expose_gc server.js

console.logによるオブジェクトの出力

Console.logを用いることでオブジェクトをコンソールに出力することができるが、この際、一部の内容しか表示されない場合がある。

この場合はutilモジュールを用いることですべての内容を表示させることができる。

const util = require('util');
console.log(util.inspect(obj,false,null));

静的解析

実際にプログラムを実行しないで、リスクのある記述方法を検知することができる。
これらの処理はJenkinsなどで定期的に実行するとよい。

eslintによる静的解析

2020年のnpmのトレンドとしてはeslintが優勢のようである。
https://www.npmtrends.com/jslint-vs-jshint-vs-jscs-vs-eslint

eslintについては以下のページを参照
https://eslint.org/

eslintをコマンドラインから使用する

1. 下記の通りインストールを行う。

npm install eslint --save-dev

※eslintをグローバルにインストールすることも可能ですが、これはお勧めされていません。
https://eslint.org/docs/user-guide/getting-started

2.解析対象のプロジェクトのpackage.jsonが存在することを確認する
存在しない場合は以下のコマンドで作成する。

npm init -y

3.eslintの設定ファイルを作成する。

npx eslint --init

上記のコマンドを実行することで対話形式で設定を行い.eslintrc.{js,yml,json}が作成される。

4.ファイルまたはフォルダを指定することで対象のファイルを解析できる。

npx eslint ~/nodejs/prj

その他の説明については下記を参照

コマンドラインの説明
https://eslint.org/docs/user-guide/command-line-interface

設定ファイルの説明
https://eslint.org/docs/user-guide/configuring

eslintをJenkinsで利用する

1.Warning Next Generationプラグインをインスト―ルする

image.png

2.ジョブの設定を行う
2.1 ビルド中に下記のコマンドを実行して静的解析の結果をXMLに保存する

cd c:\dev\node\
call npx eslint  -f checkstyle c:\dev\node\sample.js > %WORKSPACE%\result.xml || type nul>nul

静的解析の警告が発生した場合eslintは1を返す。Jenkinsはバッチ実行中のコマンドが0以外を返すと中断されるため「|| type nul>nul」でエラーコードをクリアする。

2.2 ビルド後の処理を設定する
「ビルド後の処理」で「Record comppiler warnings and static analysis results」を選択する。
image.png

作成されたXMLをReport file patternに指定する。
image.png

3.ビルドを実行するとレポートが作成される
image.png


gjslintによる静的解析 (2014年時点の情報)

gjslintは指定のコードがGoogle JavaScript Style Guideに違反していないか調べるツールである。

gjslintのインストール方法

gjslintはPythonで動作するので、Pythonがインストールされていることが前提になる。

(1)easy_installを使用できるようにする。

wget http://peak.telecommunity.com/dist/ez_setup.py
python ez_setup.py

(2)gjslintをインストールする

easy_install http://closure-linter.googlecode.com/files/closure_linter-latest.tar.gz 

gjslintの使用方法

使用例:

gjslint --disable 110,1 -r src

--disable コンマ区切りで無視するエラーを指定できる。
-r ディレクトリを再帰的に操作できる。

closure-linter-wrapperによるXML出力

gslintのみでは検査結果をXMLとして保存することはできない。XMLとして出力できないと、jenkinsによる定期ビルドに組み込むことができない。
これを行うためにはclosure-linter-wrapperが必要である。
https://github.com/jmendiara/node-closure-linter-wrapper

(1)closure-linter-wrapperのインストール

npm install -g closure-linter-wrapper

(2)次のようなtest.jsファイルを作成する。

var argv = process.argv;
var gjslint = require('closure-linter-wrapper').gjslint;
var flagsArray = [
  '--nostrict',
  '--nojsdoc',
  '--disable 14'
];
console.log(argv[2] + 'src/*.js');

gjslint({
    src: [
      argv[2] + 'src/*.js'
    ],
    flags: flagsArray
    ,reporter: {
      name: 'gjslint_xml',
      dest: argv[2] + 'gjslint.xml'
    }
  },
  function (err, result) {
  }
);

この例では引数でしたフォルダのsrc以下を解析してgjslint.xmlに出力する。
あまりに大量のデータを一気にgjslint関数に渡すと正常にXMLが作成されないので注意すること。

Jenkinsによるgjslintの集計

Jenkinsによりgjslintを定期的に実行し、その結果を集計することができる。

(1) jslintの結果を集計できるようにViolationsを入手する
Jenkinsの管理 > プラグインマネージャで利用可能タブから「Violations」を指定してインストールする。

(2) Jenkinsでシェルスクリプトを実行するようにして先に作成したclosure-linter-wrapperを使用するスクリプトを実行する

NODE_PATH=/usr/local/lib/node_modules
export NODE_PATH
node ${WORKSPACE}/test.js ${WORKSPACE}/

(3)ビルド後の処理のjslintに出力ファイルを指定しておく。
b0232065_21404268.png

(4)ビルドを行うと次のようなレポートが作成される。
b0232065_21425396.png

b0232065_21430497.png


es6-platoによるコードメトリックスの収集

es6-platoを用いることで、ソースコードの行数や複雑度を計測できる。
https://github.com/the-simian/es6-plato

1.インストール方法

npm install --save-dev es6-plato

2.スクリプトから実行する

node_modules\.bin\es6-plato -r -d 出力フォルダ 解析対象のフォルダ

これにより出力フォルダ以下にHTMLが作成される。
image.png

image.png

Complexityが高いものがバグを発生しやすいので、テストケースの数や、リファクタリングの目安として監視する。
これもjenkinsで日々作成するといい。

単体テストの自動化

ここではnode.jsでのテストの自動化について記述する。ここではサーバーサイドの単体テストの自動化についてのみ記載するものとする。

単体テストを自動化する場合、以下の機能が必要になる。

  • テスト用フレームワーク
  • モック・フェイク
  • カバレッジの計測

テスト用フレームワーク

Mochaは、Node.jsとブラウザーで実行される機能豊富なJavaScriptテストフレームワークであり、非同期テストをシンプルで楽しいものにします。

注意:2020年時点でjestにトレンド的に抜かれたようです
https://www.npmtrends.com/jest-vs-jasmine-vs-mocha-vs-qunit-vs-ava-vs-chai-vs-expect.js-vs-should-vs-power-assert

インストール方法

プロジェクトフォルダにインストールを行う。

npm install --save-dev mocha

テストコードの記述例

testフォルダにテストコードを記載する。

var assert = require('assert');
describe('sample', function () {
  it('syncOK', function () {
    assert.equal(2+2, 4);
  });
  it('syncNG', function () {
    assert.equal(2+2, 3);
  });
  it('asyncOK', function(done) {
    setTimeout(function() {
      assert.equal(2+2, 4);
      done();
    }, 15);
  });
  it('asyncNg', function(done) {
    setTimeout(function() {
      done('ng message');
    }, 15);
  });
});


実行例

下記のコマンドでtestフォルダ中のテストスクリプトを全て実行する。

npx mocha

image.png

Jenkinsとの連携方法

JUnit Reporter for Mochaを使用することでJUnitでのレポートを使用できる。
https://github.com/michaelleeallen/mocha-junit-reporter

npm install mocha-junit-reporter --save-dev

以下のコマンドを実行するとtest-result.xmlが作成される。

mocha --reporter mocha-junit-reporter

Windowsの場合は処理をとめないように以下のような処理を記載することになる。

cd c:\dev\node\
call npx mocha --reporter mocha-junit-reporter --reporter-options mochaFile=%WORKSPACE%\test_result.xml  || type nul>nul

ワークスペースにxmlを格納する場合は「--reporter-options mochaFile=ファイルパス」を利用する。

ビルド後の処理に「JUnitテスト結果の集計」を利用する。

image.png

テスト結果の集計は以下のように表示される。
image.png

モック・フェイク

モックやフェイクを使用することで依存している部品をテスト用に差し替えて実行することが可能になる。

このモックやフェイクの機能はSinon.jsでサポートされている。

Sinon.js
https://sinonjs.org/

インストール

npm install sinon --save-dev

モック対象の関数が以下の通り存在したとする。

calc.js
"use strict";

module.exports = {
  add: ( num1, num2 ) => {
    return num1 + num2;
  }
};

この関数をsinonを使用して偽装した例は以下のとおり。

var assert = require('assert');
var calc = require('../calc');
var sinon = require('sinon');

describe('test3.', function () {
  afterEach(() => {
    // Restore the default sandbox here
    sinon.restore();
  });

  it('stubの例.', function () {
    assert.equal(calc.add(1,3), 4);

    // スタブに置き換える
    sinon.stub(calc, 'add').callsFake(function(x,y) {
      console.log('stub function');
      return x*2 + y * 2;
    });
    assert.equal(calc.add(1,3), 8);

  });
});

時刻の偽装例

現在時刻を偽装する場合は[https://sinonjs.org/releases/v9.0.3/fake-timers/ sinon.useFakeTimers]を使用する。

現在時刻を1999/1/1 12:30:00(JST)にする場合

  it('現在時刻の偽装の例', function () {
    sinon.useFakeTimers({
      now : new Date(1999, 0, 1, 12, 30, 00)
    });
    assert.equal((new Date()).getFullYear(), 1999);
    console.log(new Date());
  });

カバレッジの計測

Istanbulを使用することで、カバレッジを取得することができます。

Istanbul
https://istanbul.js.org/

インストール方法*
node.jsのプロジェクトにIstanbulをインストールするには下記のコマンドを実行する。

npm install --save-dev nyc

実行例
下記のコマンドでテストコードの実行と、カバレッジの計測が行える。

npx nyc mocha

image.png

または以下のコマンドでhtml形式のレポートが作成可能

npx nyc --reporter=html mocha

image.png

image.png

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
What you can do with signing up
143
Help us understand the problem. What are the problem?