Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document required browserify option "dedupe: false" #93

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ var browserify = require('browserify');
var fs = require('fs');

var files = [ './files/x.js', './files/y.js' ];
var b = browserify(files);
var b = browserify(files, { dedupe: false });
b.plugin('../', { o: [ 'bundle/x.js', 'bundle/y.js' ] });
b.bundle().pipe(fs.createWriteStream('bundle/common.js'));
1 change: 1 addition & 0 deletions example/files/a1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 42
1 change: 1 addition & 0 deletions example/files/a2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 42
3 changes: 2 additions & 1 deletion example/files/x.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var a = require('./a1.js');
var z = require('./z.js');
var w = require('./w.js');
console.log(z(5) * w(2));
console.log(a * z(5) * w(2));
3 changes: 2 additions & 1 deletion example/files/y.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
var a = require('./a2.js');
var z = require('./z.js');
console.log(z(2) + 111);
console.log(a + z(2) + 111);
49 changes: 31 additions & 18 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ module.exports = function f (b, opts) {
.concat(opts._).filter(Boolean);

var needRecords = !files.length;

var outopt = defined(opts.outputs, opts.output, opts.o);

opts.objectMode = true;
opts.raw = true;
opts.rmap = {};
Expand All @@ -44,6 +44,7 @@ module.exports = function f (b, opts) {

function addHooks () {
b.pipeline.get('record').push(through.obj(function(row, enc, next) {
// record entrypoints
if (row.file && needRecords) {
files.push(row.file);
}
Expand All @@ -65,47 +66,59 @@ module.exports = function f (b, opts) {
outputs = [];
}

// utility for creating output streams
function moreOutputs (file) {
if (isarray(outopt)) return [];
if (!outopt) return [];
var xopts = { env: xtend(process.env, { FILE: file }) };
return [ outpipe(outopt, xopts) ];
}

var pipelines = files.reduce(function (acc, x, ix) {
// create a pipeline (labeled-stream-splicer) for every entry file
// with only a packer
var pipelines = files.reduce(function (acc, file, index) {
var pipeline = splicer.obj([
'pack', [ pack(packOpts) ],
'wrap', []
]);

if (ix >= outputs.length) {
outputs.push.apply(outputs, moreOutputs(x));
// if not enough specified outputs, possibly add additional outputs (?)
if (index >= outputs.length) {
outputs.push.apply(outputs, moreOutputs(file));
}
if (outputs[ix]) pipeline.pipe(outputs[ix]);

acc[path.resolve(cwd, x)] = pipeline;
// pipe to output if one exists
if (outputs[index]) pipeline.pipe(outputs[index]);

acc[path.resolve(cwd, file)] = pipeline;
return acc;
}, {});

// Force browser-pack to wrap the common bundle
b._bpack.hasExports = true;

// for tests/debugging
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's also for plugins to hook into factored pipelines. If you have a minification step for example it can be added to the factored pipeline by using this event.

Object.keys(pipelines).forEach(function (id) {
b.emit('factor.pipeline', id, pipelines[id]);
});

// create factor stream
var s = createStream(files, opts);

// connect each factor groups module stream to bundle pipeline
s.on('stream', function (bundle) {
// each group's output stream
bundle.pipe(pipelines[bundle.file]);
});

// add factor stream before pack
b.pipeline.get('pack').unshift(s);

if (needRecords) files = [];

next();
}));

// capture module's relative path. used for recovering entry point pathnames
Copy link
Member

@goto-bus-stop goto-bus-stop Mar 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would keep this comment but probably remove most of the others…tbh, I feel like many of the comments only restate the line and don't actually clarify much.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the comments to stay sane while trying to read through the code which i found unintuitive

b.pipeline.get('label').push(through.obj(function(row, enc, next) {
opts.rmap[row.id] = path.resolve(cwd, row.file);
next(null, row);
Expand All @@ -118,10 +131,10 @@ module.exports = function f (b, opts) {

function createStream (files, opts) {
if (!opts) opts = {};

var fr = new Factor(files, opts);
var parse, dup;

if (opts.objectMode) {
dup = combine(depsTopoSort(), reverse(), fr);
}
Expand All @@ -135,7 +148,7 @@ function createStream (files, opts) {
;
parse.on('error', function (err) { dup.emit('error', err) });
}

fr.on('error', function (err) { dup.emit('error', err) });
fr.on('stream', function (s) {
if (opts.raw) dup.emit('stream', s)
Expand All @@ -150,21 +163,21 @@ function Factor (files, opts) {
var self = this;
if (!(this instanceof Factor)) return new Factor(files, opts);
Transform.call(this, { objectMode: true });

if (!opts) opts = {};
this.basedir = defined(opts.basedir, process.cwd());

this._streams = {};
this._groups = {};
this._buffered = {};

this._ensureCommon = {};
this._files = files.reduce(function (acc, file) {
acc[path.resolve(self.basedir, file)] = true;
return acc;
}, {});
this._rmap = opts.rmap || {};

this._thresholdVal = typeof opts.threshold === "number"
? opts.threshold : 1
;
Expand Down Expand Up @@ -200,9 +213,9 @@ Factor.prototype._transform = function (row, enc, next) {
self._streams[id].push(row);
});
}

next();

function addGroups (gid) {
Object.keys(row.deps || {}).forEach(function (key) {
var file = row.deps[key];
Expand All @@ -215,7 +228,7 @@ Factor.prototype._transform = function (row, enc, next) {

Factor.prototype._flush = function () {
var self = this;

Object.keys(self._streams).forEach(function (key) {
self._streams[key].push(null);
});
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"devDependencies": {
"browser-unpack": "^1.1.1",
"browserify": "^11.0.1",
"browserify": "^16.5.0",
"concat-stream": "^1.4.6",
"mkdirp": "~0.5.0",
"module-deps": "^3.9.0",
Expand Down
29 changes: 17 additions & 12 deletions readme.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = function (n) { return n * 50 }
Now run factor-bundle as a plugin (new in browserify 3.28.0):

``` sh
browserify x.js y.js -p [ factor-bundle -o bundle/x.js -o bundle/y.js ] \
browserify --no-dedupe x.js y.js -p [ factor-bundle -o bundle/x.js -o bundle/y.js ] \
-o bundle/common.js
```

Expand All @@ -54,7 +54,7 @@ $ module-deps x.js y.js | factor-bundle \
or factor out an existing bundle already compiled by browserify:

``` sh
$ browserify x.js y.js > bundle.js
$ browserify --no-dedupe x.js y.js > bundle.js
$ browser-unpack < bundle.js | factor-bundle \
x.js -o bundle/x.js \
y.js -o bundle/y.js \
Expand Down Expand Up @@ -84,13 +84,18 @@ $ cat bundle/common.js bundle/y.js | node
333
```

## usage note

You must disable browserify's dedupe feature in order to use this module.
It can be disabled by providing `{ dedupe: false }` in the js api, or by the `--no-dedup` cli argument.

## command-line outpipe example

We can pipe each output file through some other processes. Here we'll do
minification with uglify compression with gzip:

``` sh
browserify files/*.js \
browserify --no-dedupe files/*.js \
-p [ factor-bundle -o 'uglifyjs -cm | gzip > bundle/`basename $FILE`.gz' ] \
| uglifyjs -cm | gzip > bundle/common.js.gz
```
Expand All @@ -104,7 +109,7 @@ var browserify = require('browserify');
var fs = require('fs');

var files = [ './files/x.js', './files/y.js' ];
var b = browserify(files);
var b = browserify(files, { dedupe: true });
kumavis marked this conversation as resolved.
Show resolved Hide resolved
b.plugin('factor-bundle', { outputs: [ 'bundle/x.js', 'bundle/y.js' ] });
b.bundle().pipe(fs.createWriteStream('bundle/common.js'));
```
Expand All @@ -116,7 +121,7 @@ var browserify = require('browserify');
var concat = require('concat-stream');

var files = [ './files/x.js', './files/y.js' ];
var b = browserify(files);
var b = browserify(files, { dedupe: true });

b.plugin('factor-bundle', { outputs: [ write('x'), write('y') ] });
b.bundle().pipe(write('common'));
Expand All @@ -141,7 +146,7 @@ where OPTIONS are:
-o Output FILE or CMD that maps to a corresponding entry file at the same
index. CMDs are executed with $FILE set to the corresponding input file.
Optionally specify a function that returns a valid value for this argument.

-e Entry file to use, overriding the entry files listed in the original
bundle.

Expand All @@ -159,10 +164,10 @@ the corresponding output file (-o).

Write output to FILE or CMD. CMD is distinguished from FILE by the presence
of one or more `>` or `|` characters. For example, use:

factor-bundle browser/a.js browser/b.js \
-o bundle/a.js -o bundle/b.js

to write to a FILE. And do something like:

factor-bundle browser/*.js \
Expand Down Expand Up @@ -203,10 +208,10 @@ this information is gathered from browserify itself.
The files held in common among `> opts.threshold` (default: 1) bundles will be
output on the `fr` stream itself. The entry-specific bundles are diverted into
each `'stream'` event's output. `opts.threshold` can be a number or a function
`opts.threshold(row, groups)` where `row` is a
[module-deps](https://github.com/substack/module-deps) object and `groups` is
an array of bundles which depend on the row. If the threshold function returns
`true`, that row and all its dependencies will go to the `common` bundle. If
`opts.threshold(row, groups)` where `row` is a
[module-deps](https://github.com/substack/module-deps) object and `groups` is
an array of bundles which depend on the row. If the threshold function returns
`true`, that row and all its dependencies will go to the `common` bundle. If
false, the row (but not its dependencies) will go to each bundle in `groups`.
For example:

Expand Down