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) を指定しましょう.