compiler pipeline
从版本5以来, browserify暴露出内部的编译流程, 作为一个 labeled-stream-splicer 实例.
这意味着转换操作可以直接从内部流程线添加或删除. 这个流程线为高级自定义提供了一个干净 的接口, 例如监视文件更改或者根据入口分析输出分割至多个打包文件.
例如, 我们可以将内建的以整数为基准的模块命名方案替换掉, 换成Hashed IDs的命名方案. 通过注入一个pass-through, 在deps已经计算好整个源代码的哈希值之后. 然后我们可以利用计算 好的哈希值创建我们自己的命名方案, 并将内建的命名方案替换掉:
var browserify = require('browserify');var through = require('through2');var shasum = require('shasum');var b = browserify('./main.js');var hashes = {};var hasher = through.obj(function (row, enc, next) { hashes[row.id] = shasum(row.source); this.push(row); next();});b.pipeline.get('deps').push(hasher);var labeler = through.obj(function (row, enc, next) { row.id = hashes[row.id]; Object.keys(row.deps).forEach(function (key) { row.deps[key] = hashes[row.deps[key]]; }); this.push(row); next();});b.pipeline.get('label').splice(0, 1, labeler);b.bundle().pipe(process.stdout);
现在, 我们得到了基于文本内容的哈希值命名方案, 而不是整数ID:
$ node bundle.js(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})({"5f0a0e3a143f2356582f58a70f385f4bde44f04b":[function(require,module,exports){var foo = require('./foo.js');var bar = require('./bar.js');console.log(foo(3) + bar(4));},{"./bar.js":"cba5983117ae1d6699d85fc4d54eb589d758f12b","./foo.js":"736100869ec2e44f7cfcf0dc6554b055e117c53c"}],"cba5983117ae1d6699d85fc4d54eb589d758f12b":[function(require,module,exports){module.exports = function (n) { return n * 100 };},{}],"736100869ec2e44f7cfcf0dc6554b055e117c53c":[function(require,module,exports){module.exports = function (n) { return n + 1 };},{}]},{},["5f0a0e3a143f2356582f58a70f385f4bde44f04b"]);
注意, 内建的命名方案做了一些其他的事情, 例如检查外部依赖(external), 排除文件(exclude), 所以如果你依赖这些特性的话, 将整个命名方案替换掉会很困难. 这个例子只是简单的演示你可以 修改内部的编译器流水线.