yak shaving life

遠回りこそが最短の道

JSでモジュール化するならとりあえずこれ、ってやつ

普段書かないNode.jsをたまに書くと、モジュール化のやり方を思い出せなくて困る。

ググると詳細な解説記事がたくさん出て来るが、やり方がいくつかあって結局どれか悩むので、自分用にメモっておく。

基本的には既存コードやライブラリに合わせて書くのがよいが、選択肢は二つ。ES6で追加されたimport/export(ES Modules)か、module.exports/require(CommonJS)のどちらか。2018年時点ではCommonJSで書かれたコードが結構多い気がするので、とりあえずこちらを使うことにする。

// module_sample.js
function hello() {
  return "Hello, Module!";
}

module.exports = hello;
// require_sample.js
function hello() {
  return 'Hello, World!';
}

const module_hello = require('./module_sample.js');

console.log(hello());
console.log(module_hello());
$ node require_sample.js

#=> Hello, World!
#=> Hello, Module!

複数の関数をエクスポートしたいときはオブジェクトのプロパティに突っ込む感じで。

// module_object.js
module.exports = {
  hello() {
    return "Hello, Module Object!";
  },
  bye() {
    return "Bye, Module Object.";
  },
};
// require_sample2.js
function hello() {
  return 'Hello, World!';
}

const module_object = require('./module_object.js');

console.log(hello());
console.log(module_object.hello());
console.log(module_object.bye());
$ node require_sample2.js

#=> Hello, World!
#=> Hello, Module Object!
#=> Bye, Module Object.

その他メモ。

  • オブジェクトのエクスポート時はexports.hello = function(){...} とも書けるけど別にmodule.exportsでいい気がする

  • ブラウザ上のJSでこの構文を使いたい場合はwebpack等が必要

  • ES6ネイティブのES Modulesが近いうち主流になる。すでに有名ライブラリ等はこちらになってきている

  • その他の方法(AMDとか)を使うメリットはおそらくないので使わない