Browserifyを使うと、node.jsと同じような書き方ができて便利です。WebPackも人気ですよね。
ですが、node.jsとブラウザでは読み込ませるファイルを分けたいことがよくあります。各環境のロケールを取得するに、ブラウザだと navigator.language
変数をのぞくだけでOKです。デスクトップ環境とかサーバでは os-localeパッケージを使いたいですよね。でもos-localeパッケージをブラウザにバンドルしたくはないです。
それぞれ、次のようなファイルで同じAPIで関数を用意します。
const osLocale = require('os-locale');
module.exports = () => {
return new Promise((resolve, reject) => {
osLocale((err, locale) => {
if (err) return reject(err);
resolve(locale);
});
});
};
module.exports = () => {
return new Promise(resolve => {
resolve(navigator.language);
});
};
これらのファイルを読み分けます。
もちろん設定ファイルを書いたり、コマンドライン引数を駆使すればBrowserifyでもWebPackでも、バンドルからファイルを除外したりできます。でもライブラリとして配布したいパッケージの場合、使われる側でいろいろ設定してもらわないと動かないのは不便です。ライブラリ内だけでこういう設定を完結させたいですよね。
node.jsには module.require()
という関数があり、 require()
の代わりに使うと、node.js上ではファイルのロードができるけど、Browserify/WebPackからは無視される、というのが実現できます。
var locale;
if (module.require) {
locale = module.require('./for_node');
} else {
locale = require('./for_browser');
}
locale().then(lang => {
console.log(lang);
});
$ node main.js
en_US
そのままnode.jsで実行してみます。
$ browserify main.js -o browserify.js
$ node browserify.js
(node:33019) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): ReferenceError: navigator is not defined
BrowserifyとWebPackでconcatしてから実行するとエラーになりました。無事、ブラウザ用のパッケージができました。めでたしめでたし。
$ webpack main.js webpack.js
Hash: a8f46f9fd8813681c2a2
Version: webpack 1.13.2
Time: 73ms
Asset Size Chunks Chunk Names
webpack.js 2.2 kB 0 [emitted] main
[0] ./main.js 176 bytes {0} [built]
[2] ./for_browser.js 109 bytes {0} [built]
+ 1 hidden modules
$ webpack.js
(node:33135) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): ReferenceError: navigator is not defined