npm で管理している package のライセンス一覧の作成を支援する license-list を作成した

license-list というライブラリを作成し、npm で初めて公開しました。

license-list

npm で管理している package のライセンス一覧を作成するためのヘルパーライブラリです。

github.com

以下のような形で利用できます。

import licenseList from 'license-list';

licenseList('.', { dev: false }).then((packages) => {
  const pkgInfo = packages['license-list@0.1.0'];
  console.log(pkgInfo);
});

一応コマンドも用意してあります。

$ $(npm bin)/license-list .

仕組み

read-installed で node_modules 以下の package を取得した後、整形して返すだけの単純なライブラリです。

license-checkerlicensify を参考に作成しました。

初めて取り組んだこと

  • npm での公開
  • ES2015 以降で記述
    • babel で変換
  • mocha, power-assert を使ったテスト
  • travis によるテスト

備考

yarn で package を管理している場合は、yarn licenses という便利なコマンドが提供されているので、そちらを利用すると良いと思います。

yarnpkg.com

browserify, babelify, watchify が遅い時の注意点

browserify, babelify, watchify

browserify, babelify, watchifyを組み合わせて使う場合,transform の位置に注意しないと(ファイルの変更をせずに書き込みした場合でも)トランスパイルの度に遅くなっていきます.

watchify\babelify bundle() 内で transform(babelify) transform: [babelify]
plugin: [watchify] 遅い 速い
watchify() 遅い 速い

遅くなるパターン

watchify でファイル監視を行う場合,bundler.on('update', bundle); のように update イベントでトランスパイルを行うように設定します.
このとき,transformbundle() 内で実行してしまうと,トランスパイルの度に遅くなっていきます.

plugin: [watchify]bundle() 内で transform(babelify) で計測

// sample1.js
const babelify = require('babelify');
const browserify = require('browserify');
const watchify = require('watchify');
const fs = require('fs');

const bundler = browserify('src/js/index.js', {
  cache: {},
  packageCache: {},
  plugin: [watchify],
});

const bundle = () => {
  return bundler.transform(babelify) // <- bundle() 内に transform(babelify) にあるため遅くなる
    .bundle()
    .pipe(fs.createWriteStream('dest/js/bundle.js'));
};
bundler.on('log', (msg) => console.log(msg));
bundler.on('update', bundle);

bundle();

// 計測
let count = 0;
let max = 10;
const code = `
import add from './add';
console.log(add(1, 2));
`;
const writeFile = () => {
  setTimeout(function() { 
    fs.writeFileSync('src/js/index.js', code, 'utf8');
    count += 1;
    if (count < max) {
      writeFile();
    }
  }, 1000);
};
writeFile();
$ node sample1.js
911 bytes written (0.21 seconds)
913 bytes written (0.06 seconds)
913 bytes written (0.06 seconds)
913 bytes written (0.07 seconds)
913 bytes written (0.09 seconds)
913 bytes written (0.11 seconds)
913 bytes written (0.13 seconds)
913 bytes written (0.15 seconds)
913 bytes written (0.21 seconds)
913 bytes written (0.21 seconds)
913 bytes written (0.22 seconds)
^C

watchify()bundle() 内で transform(babelify) で計測

// sample2.js
const babelify = require('babelify');
const browserify = require('browserify');
const watchify = require('watchify');
const fs = require('fs');

const bundler = watchify(browserify('src/js/index.js', {
  cache: {},
  packageCache: {},
}));

const bundle = () => {
  return bundler.transform(babelify) // <- bundle() 内に transform(babelify) にあるため遅くなる
    .bundle()
    .pipe(fs.createWriteStream('dest/js/bundle.js'));
};

bundler.on('log', (msg) => console.log(msg));
bundler.on('update', bundle);

bundle();

// 計測
let count = 0;
let max = 10;
const code = `
import add from './add';
console.log(add(1, 2));
`;
const writeFile = () => {
  setTimeout(function() { 
    fs.writeFileSync('src/js/index.js', code, 'utf8');
    count += 1;
    if (count < max) {
      writeFile();
    }
  }, 1000);
};
writeFile();
$ node sample2.js
911 bytes written (0.21 seconds)
913 bytes written (0.06 seconds)
913 bytes written (0.06 seconds)
913 bytes written (0.08 seconds)
913 bytes written (0.09 seconds)
913 bytes written (0.11 seconds)
913 bytes written (0.13 seconds)
913 bytes written (0.15 seconds)
913 bytes written (0.20 seconds)
913 bytes written (0.24 seconds)
913 bytes written (0.25 seconds)
^C

遅くならないパターン

transform の指定位置を bundle() 外にすると,トランスパイルの度に遅くなりません.

plugin: [watchify]transform: [babelify] で計測

// sample3.js
const babelify = require('babelify');
const browserify = require('browserify');
const watchify = require('watchify');
const fs = require('fs');

const bundler = browserify('src/js/index.js', {
  cache: {},
  packageCache: {},
  plugin: [watchify],
  transform: [babelify], // <- bundle() 外で transform: [babelify] を指定すれば遅くならない
});

// もしくは,bundle() 外で transform(babelify) でも良い
// bundler.transform(babelify);

const bundle = () => {
  return bundler.bundle()
    .pipe(fs.createWriteStream('dest/js/bundle.js'));
};

bundler.on('log', (msg) => console.log(msg));
bundler.on('update', bundle);

bundle();

// 計測
let count = 0;
let max = 10;
const code = `
import add from './add';
console.log(add(1, 2));
`;
const writeFile = () => {
  setTimeout(function() { 
    fs.writeFileSync('src/js/index.js', code, 'utf8');
    count += 1;
    if (count < max) {
      writeFile();
    }
  }, 1000);
};
writeFile();
$ node sample3.js
911 bytes written (0.25 seconds)
911 bytes written (0.02 seconds)
911 bytes written (0.03 seconds)
911 bytes written (0.03 seconds)
911 bytes written (0.01 seconds)
911 bytes written (0.02 seconds)
911 bytes written (0.01 seconds)
911 bytes written (0.02 seconds)
911 bytes written (0.01 seconds)
911 bytes written (0.01 seconds)
911 bytes written (0.01 seconds)
^C

watchify()transform: [babelify] で計測

// sample4.js
const babelify = require('babelify');
const browserify = require('browserify');
const watchify = require('watchify');
const fs = require('fs');

const bundler = watchify(browserify('src/js/index.js', {
  cache: {},
  packageCache: {},
  transform: [babelify], // <- bundle() 外で transform: [babelify] を指定すれば遅くならない
}));

// もしくは,bundle() 外で transform(babelify) でも良い
// bundler.transform(babelify);

const bundle = () => {
  return bundler.bundle()
    .pipe(fs.createWriteStream('dest/js/bundle.js'));
};

bundler.on('log', (msg) => console.log(msg));
bundler.on('update', bundle);

bundle();

// 計測
let count = 0;
let max = 10;
const code = `
import add from './add';
console.log(add(1, 2));
`;
const writeFile = () => {
  setTimeout(function() { 
    fs.writeFileSync('src/js/index.js', code, 'utf8');
    count += 1;
    if (count < max) {
      writeFile();
    }
  }, 1000);
};
writeFile();
$ node sample4.js
911 bytes written (0.22 seconds)
911 bytes written (0.03 seconds)
911 bytes written (0.03 seconds)
911 bytes written (0.02 seconds)
911 bytes written (0.02 seconds)
911 bytes written (0.02 seconds)
911 bytes written (0.01 seconds)
911 bytes written (0.02 seconds)
911 bytes written (0.01 seconds)
911 bytes written (0.01 seconds)
911 bytes written (0.01 seconds)
^C

まとめ

transform: [babelify] を用いるか,bundle() の外で bundler.transform(babelify) を指定しましょう.