Browserify 5.0から--standaloneでderequireはされなくなった
Browserify 5.0.0では、 基盤となる変換処理の部分に色々変更がありました。(特にtransform周りが大きく変わって変換にhookする処理が色々できるようになった)
ChangeLogの一番下にちょこっと書いてありますが、--standalone
を付けて単体のライブラリとして配布向けにビルドするときに、
derequireがされなくなりました。
derequire has been taken out of core, which should speed up –standalone.
そもそもderequireとは何かというと、 requireという関数を使うライブラリ等との衝突を避けるためにリネーム処理をするモジュールのことです。
v4とv5のstandaloneオプションの違い
例としてazu/get-html-titleを standaloneなライブラリとしてビルドしたいと思います。
browserify v4以下の場合の場合は以下のようにgetHTMLTitle
という関数を使える形にした
ライブラリとしてビルドすると以下のようになります。
# browserify v4以下の場合
browserify -s getHTMLTitle index.js
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.getHTMLTitle=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
"use strict";
module.exports = _dereq_("./lib/get-title-html");
},{"./lib/get-title-html":2}],2:[function(_dereq_,module,exports){
"use strict";
var titleRegExp = /<title[^>]*>([^<]+)<\/title>/i;
function getHTMLTitle(content) {
if (content == null) {
return undefined;
}
var match = content.match(titleRegExp);
return match && match[1];
}
module.exports = getHTMLTitle;
},{}]},{},[1])
(1)
});
以下の部分を見ると、require
ではなくderequireされて無害な文字列に置換されていることが分かります。
(require.jsなどはrequire
を単純に見るのでそのままだと衝突してしまうのを回避するため?)
module.exports = _dereq_("./lib/get-title-html");
これが、browserify v5からは以下のような出力になります。
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.getHTMLTitle=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
"use strict";
module.exports = require("./lib/get-title-html");
},{"./lib/get-title-html":2}],2:[function(require,module,exports){
"use strict";
var titleRegExp = /<title[^>]*>([^<]+)<\/title>/i;
function getHTMLTitle(content) {
if (content == null) {
return undefined;
}
var match = content.match(titleRegExp);
return match && match[1];
}
module.exports = getHTMLTitle;
},{}]},{},[1])(1)
});
require
がそのまま残っていることがわかると思います。
なぜderequireしていたのか
require
という関数を持つライブラリなどと衝突するのを回避するため(require.jsとか?)
なぜderequireしなくなったか
遅い。
ビルドしたものをASTにパースして置換するので、-s
つけるだけで10倍ぐらい遅くなってた。
これからもderequireしたい
に書いてあるように、別途derequireをいれて、 ビルドしたものに対してderequireをかける
$ npm install -g derequire
$ browserify main.js --standalone Foo | derequire > bundle.js
gulp等でやる場合は以下のようなpluginを使用すればいいと思います。
お知らせ欄
JavaScript Primerの書籍版がAmazonで購入できます。
JavaScriptに関する最新情報は週一でJSer.infoを更新しています。
GitHub Sponsorsでの支援を募集しています。