1 | var path = require('path');
|
2 | var mdeps = require('module-deps');
|
3 | var depsSort = require('deps-sort');
|
4 | var bpack = require('browser-pack');
|
5 | var insertGlobals = require('insert-module-globals');
|
6 | var syntaxError = require('syntax-error');
|
7 |
|
8 | var builtins = require('./lib/builtins.js');
|
9 |
|
10 | var splicer = require('labeled-stream-splicer');
|
11 | var through = require('through2');
|
12 | var concat = require('concat-stream');
|
13 |
|
14 | var inherits = require('inherits');
|
15 | var EventEmitter = require('events').EventEmitter;
|
16 | var xtend = require('xtend');
|
17 | var isArray = Array.isArray;
|
18 | var defined = require('defined');
|
19 | var has = require('has');
|
20 | var sanitize = require('htmlescape').sanitize;
|
21 | var shasum = require('shasum');
|
22 |
|
23 | var bresolve = require('browser-resolve');
|
24 | var resolve = require('resolve');
|
25 |
|
26 | var readonly = require('read-only-stream');
|
27 |
|
28 | module.exports = Browserify;
|
29 | inherits(Browserify, EventEmitter);
|
30 |
|
31 | var fs = require('fs');
|
32 | var path = require('path');
|
33 | var cachedPathRelative = require('cached-path-relative');
|
34 |
|
35 | var paths = {
|
36 | empty: path.join(__dirname, 'lib/_empty.js')
|
37 | };
|
38 |
|
39 | function Browserify (files, opts) {
|
40 | var self = this;
|
41 | if (!(this instanceof Browserify)) return new Browserify(files, opts);
|
42 | if (!opts) opts = {};
|
43 |
|
44 | if (typeof files === 'string' || isArray(files) || isStream(files)) {
|
45 | opts = xtend(opts, { entries: [].concat(opts.entries || [], files) });
|
46 | }
|
47 | else opts = xtend(files, opts);
|
48 |
|
49 | if (opts.node) {
|
50 | opts.bare = true;
|
51 | opts.browserField = false;
|
52 | }
|
53 | if (opts.bare) {
|
54 | opts.builtins = false;
|
55 | opts.commondir = false;
|
56 | if (opts.insertGlobalVars === undefined) {
|
57 | opts.insertGlobalVars = {}
|
58 | Object.keys(insertGlobals.vars).forEach(function (name) {
|
59 | if (name !== '__dirname' && name !== '__filename') {
|
60 | opts.insertGlobalVars[name] = undefined;
|
61 | }
|
62 | })
|
63 | }
|
64 | }
|
65 |
|
66 | self._options = opts;
|
67 | if (opts.noparse) opts.noParse = opts.noparse;
|
68 |
|
69 | if (opts.basedir !== undefined && typeof opts.basedir !== 'string') {
|
70 | throw new Error('opts.basedir must be either undefined or a string.');
|
71 | }
|
72 |
|
73 | opts.dedupe = opts.dedupe === false ? false : true;
|
74 |
|
75 | self._external = [];
|
76 | self._exclude = [];
|
77 | self._ignore = [];
|
78 | self._expose = {};
|
79 | self._hashes = {};
|
80 | self._pending = 0;
|
81 | self._transformOrder = 0;
|
82 | self._transformPending = 0;
|
83 | self._transforms = [];
|
84 | self._entryOrder = 0;
|
85 | self._ticked = false;
|
86 | self._bresolve = opts.browserField === false
|
87 | ? function (id, opts, cb) {
|
88 | if (!opts.basedir) opts.basedir = path.dirname(opts.filename)
|
89 | resolve(id, opts, cb)
|
90 | }
|
91 | : bresolve
|
92 | ;
|
93 | self._syntaxCache = {};
|
94 |
|
95 | var ignoreTransform = [].concat(opts.ignoreTransform).filter(Boolean);
|
96 | self._filterTransform = function (tr) {
|
97 | if (isArray(tr)) {
|
98 | return ignoreTransform.indexOf(tr[0]) === -1;
|
99 | }
|
100 | return ignoreTransform.indexOf(tr) === -1;
|
101 | };
|
102 |
|
103 | self.pipeline = self._createPipeline(opts);
|
104 |
|
105 | [].concat(opts.transform).filter(Boolean).filter(self._filterTransform)
|
106 | .forEach(function (tr) {
|
107 | self.transform(tr);
|
108 | });
|
109 |
|
110 | [].concat(opts.entries).filter(Boolean).forEach(function (file) {
|
111 | self.add(file, { basedir: opts.basedir });
|
112 | });
|
113 |
|
114 | [].concat(opts.require).filter(Boolean).forEach(function (file) {
|
115 | self.require(file, { basedir: opts.basedir });
|
116 | });
|
117 |
|
118 | [].concat(opts.plugin).filter(Boolean).forEach(function (p) {
|
119 | self.plugin(p, { basedir: opts.basedir });
|
120 | });
|
121 | }
|
122 |
|
123 | Browserify.prototype.require = function (file, opts) {
|
124 | var self = this;
|
125 | if (isArray(file)) {
|
126 | file.forEach(function (x) {
|
127 | if (typeof x === 'object') {
|
128 | self.require(x.file, xtend(opts, x));
|
129 | }
|
130 | else self.require(x, opts);
|
131 | });
|
132 | return this;
|
133 | }
|
134 |
|
135 | if (!opts) opts = {};
|
136 | var basedir = defined(opts.basedir, self._options.basedir, process.cwd());
|
137 | var expose = opts.expose;
|
138 | if (file === expose && /^[\.]/.test(expose)) {
|
139 | expose = '/' + relativePath(basedir, expose);
|
140 | }
|
141 | if (expose === undefined && this._options.exposeAll) {
|
142 | expose = true;
|
143 | }
|
144 | if (expose === true) {
|
145 | expose = '/' + relativePath(basedir, file);
|
146 | }
|
147 |
|
148 | if (isStream(file)) {
|
149 | self._pending ++;
|
150 | var order = self._entryOrder ++;
|
151 | file.pipe(concat(function (buf) {
|
152 | var filename = opts.file || file.file || path.join(
|
153 | basedir,
|
154 | '_stream_' + order + '.js'
|
155 | );
|
156 | var id = file.id || expose || filename;
|
157 | if (expose || opts.entry === false) {
|
158 | self._expose[id] = filename;
|
159 | }
|
160 | if (!opts.entry && self._options.exports === undefined) {
|
161 | self._bpack.hasExports = true;
|
162 | }
|
163 | var rec = {
|
164 | source: buf.toString('utf8'),
|
165 | entry: defined(opts.entry, false),
|
166 | file: filename,
|
167 | id: id
|
168 | };
|
169 | if (rec.entry) rec.order = order;
|
170 | if (rec.transform === false) rec.transform = false;
|
171 | self.pipeline.write(rec);
|
172 |
|
173 | if (-- self._pending === 0) self.emit('_ready');
|
174 | }));
|
175 | return this;
|
176 | }
|
177 |
|
178 | var row;
|
179 | if (typeof file === 'object') {
|
180 | row = xtend(file, opts);
|
181 | }
|
182 | else if (!opts.entry && isExternalModule(file)) {
|
183 |
|
184 | row = xtend(opts, { id: expose || file, file: file });
|
185 | }
|
186 | else {
|
187 | row = xtend(opts, { file: path.resolve(basedir, file) });
|
188 | }
|
189 |
|
190 | if (!row.id) {
|
191 | row.id = expose || row.file;
|
192 | }
|
193 | if (expose || !row.entry) {
|
194 |
|
195 |
|
196 | row.expose = row.id;
|
197 | }
|
198 |
|
199 | if (opts.external) return self.external(file, opts);
|
200 | if (row.entry === undefined) row.entry = false;
|
201 |
|
202 | if (!row.entry && self._options.exports === undefined) {
|
203 | self._bpack.hasExports = true;
|
204 | }
|
205 |
|
206 | if (row.entry) row.order = self._entryOrder ++;
|
207 |
|
208 | if (opts.transform === false) row.transform = false;
|
209 | self.pipeline.write(row);
|
210 | return self;
|
211 | };
|
212 |
|
213 | Browserify.prototype.add = function (file, opts) {
|
214 | var self = this;
|
215 | if (!opts) opts = {};
|
216 | if (isArray(file)) {
|
217 | file.forEach(function (x) { self.add(x, opts) });
|
218 | return this;
|
219 | }
|
220 | return this.require(file, xtend({ entry: true, expose: false }, opts));
|
221 | };
|
222 |
|
223 | Browserify.prototype.external = function (file, opts) {
|
224 | var self = this;
|
225 | if (isArray(file)) {
|
226 | file.forEach(function (f) {
|
227 | if (typeof f === 'object') {
|
228 | self.external(f, xtend(opts, f));
|
229 | }
|
230 | else self.external(f, opts)
|
231 | });
|
232 | return this;
|
233 | }
|
234 | if (file && typeof file === 'object' && typeof file.bundle === 'function') {
|
235 | var b = file;
|
236 | self._pending ++;
|
237 |
|
238 | var bdeps = {};
|
239 | var blabels = {};
|
240 |
|
241 | b.on('label', function (prev, id) {
|
242 | self._external.push(id);
|
243 |
|
244 | if (prev !== id) {
|
245 | blabels[prev] = id;
|
246 | self._external.push(prev);
|
247 | }
|
248 | });
|
249 |
|
250 | b.pipeline.get('deps').push(through.obj(function (row, enc, next) {
|
251 | bdeps = xtend(bdeps, row.deps);
|
252 | this.push(row);
|
253 | next();
|
254 | }));
|
255 |
|
256 | self.on('dep', function (row) {
|
257 | Object.keys(row.deps).forEach(function (key) {
|
258 | var prev = bdeps[key];
|
259 | if (prev) {
|
260 | var id = blabels[prev];
|
261 | if (id) {
|
262 | row.indexDeps[key] = id;
|
263 | }
|
264 | }
|
265 | });
|
266 | });
|
267 |
|
268 | b.pipeline.get('label').once('end', function () {
|
269 | if (-- self._pending === 0) self.emit('_ready');
|
270 | });
|
271 | return this;
|
272 | }
|
273 |
|
274 | if (!opts) opts = {};
|
275 | var basedir = defined(opts.basedir, process.cwd());
|
276 | this._external.push(file);
|
277 | this._external.push('/' + relativePath(basedir, file));
|
278 | return this;
|
279 | };
|
280 |
|
281 | Browserify.prototype.exclude = function (file, opts) {
|
282 | if (!opts) opts = {};
|
283 | if (isArray(file)) {
|
284 | var self = this;
|
285 | file.forEach(function(file) {
|
286 | self.exclude(file, opts);
|
287 | });
|
288 | return this;
|
289 | }
|
290 | var basedir = defined(opts.basedir, process.cwd());
|
291 | this._exclude.push(file);
|
292 | this._exclude.push('/' + relativePath(basedir, file));
|
293 | return this;
|
294 | };
|
295 |
|
296 | Browserify.prototype.ignore = function (file, opts) {
|
297 | if (!opts) opts = {};
|
298 | if (isArray(file)) {
|
299 | var self = this;
|
300 | file.forEach(function(file) {
|
301 | self.ignore(file, opts);
|
302 | });
|
303 | return this;
|
304 | }
|
305 | var basedir = defined(opts.basedir, process.cwd());
|
306 |
|
307 |
|
308 | if (file[0] === '.') {
|
309 | this._ignore.push(path.resolve(basedir, file));
|
310 | }
|
311 | else {
|
312 | this._ignore.push(file);
|
313 | }
|
314 | return this;
|
315 | };
|
316 |
|
317 | Browserify.prototype.transform = function (tr, opts) {
|
318 | var self = this;
|
319 | if (typeof opts === 'function' || typeof opts === 'string') {
|
320 | tr = [ opts, tr ];
|
321 | }
|
322 | if (isArray(tr)) {
|
323 | opts = tr[1];
|
324 | tr = tr[0];
|
325 | }
|
326 |
|
327 |
|
328 | if (typeof tr === 'string' && !self._filterTransform(tr)) {
|
329 | return this;
|
330 | }
|
331 |
|
332 | function resolved () {
|
333 | self._transforms[order] = rec;
|
334 | -- self._pending;
|
335 | if (-- self._transformPending === 0) {
|
336 | self._transforms.forEach(function (transform) {
|
337 | self.pipeline.write(transform);
|
338 | });
|
339 |
|
340 | if (self._pending === 0) {
|
341 | self.emit('_ready');
|
342 | }
|
343 | }
|
344 | }
|
345 |
|
346 | if (!opts) opts = {};
|
347 | opts._flags = '_flags' in opts ? opts._flags : self._options;
|
348 |
|
349 | var basedir = defined(opts.basedir, this._options.basedir, process.cwd());
|
350 | var order = self._transformOrder ++;
|
351 | self._pending ++;
|
352 | self._transformPending ++;
|
353 |
|
354 | var rec = {
|
355 | transform: tr,
|
356 | options: opts,
|
357 | global: opts.global
|
358 | };
|
359 |
|
360 | if (typeof tr === 'string') {
|
361 | var topts = {
|
362 | basedir: basedir,
|
363 | paths: (self._options.paths || []).map(function (p) {
|
364 | return path.resolve(basedir, p);
|
365 | })
|
366 | };
|
367 | resolve(tr, topts, function (err, res) {
|
368 | if (err) return self.emit('error', err);
|
369 | rec.transform = res;
|
370 | resolved();
|
371 | });
|
372 | }
|
373 | else process.nextTick(resolved);
|
374 | return this;
|
375 | };
|
376 |
|
377 | Browserify.prototype.plugin = function (p, opts) {
|
378 | if (isArray(p)) {
|
379 | opts = p[1];
|
380 | p = p[0];
|
381 | }
|
382 | if (!opts) opts = {};
|
383 | var basedir = defined(opts.basedir, this._options.basedir, process.cwd());
|
384 | if (typeof p === 'function') {
|
385 | p(this, opts);
|
386 | }
|
387 | else {
|
388 | var pfile = resolve.sync(String(p), { basedir: basedir })
|
389 | var f = require(pfile);
|
390 | if (typeof f !== 'function') {
|
391 | throw new Error('plugin ' + p + ' should export a function');
|
392 | }
|
393 | f(this, opts);
|
394 | }
|
395 | return this;
|
396 | };
|
397 |
|
398 | Browserify.prototype._createPipeline = function (opts) {
|
399 | var self = this;
|
400 | if (!opts) opts = {};
|
401 | this._mdeps = this._createDeps(opts);
|
402 | this._mdeps.on('file', function (file, id) {
|
403 | pipeline.emit('file', file, id);
|
404 | self.emit('file', file, id);
|
405 | });
|
406 | this._mdeps.on('package', function (pkg) {
|
407 | pipeline.emit('package', pkg);
|
408 | self.emit('package', pkg);
|
409 | });
|
410 | this._mdeps.on('transform', function (tr, file) {
|
411 | pipeline.emit('transform', tr, file);
|
412 | self.emit('transform', tr, file);
|
413 | });
|
414 |
|
415 | var dopts = {
|
416 | index: !opts.fullPaths && !opts.exposeAll,
|
417 | dedupe: opts.dedupe,
|
418 | expose: this._expose
|
419 | };
|
420 | this._bpack = bpack(xtend(opts, { raw: true }));
|
421 |
|
422 | var pipeline = splicer.obj([
|
423 | 'record', [ this._recorder() ],
|
424 | 'deps', [ this._mdeps ],
|
425 | 'json', [ this._json() ],
|
426 | 'unbom', [ this._unbom() ],
|
427 | 'unshebang', [ this._unshebang() ],
|
428 | 'syntax', [ this._syntax() ],
|
429 | 'sort', [ depsSort(dopts) ],
|
430 | 'dedupe', [ this._dedupe() ],
|
431 | 'label', [ this._label(opts) ],
|
432 | 'emit-deps', [ this._emitDeps() ],
|
433 | 'debug', [ this._debug(opts) ],
|
434 | 'pack', [ this._bpack ],
|
435 | 'wrap', []
|
436 | ]);
|
437 | if (opts.exposeAll) {
|
438 | var basedir = defined(opts.basedir, process.cwd());
|
439 | pipeline.get('deps').push(through.obj(function (row, enc, next) {
|
440 | if (self._external.indexOf(row.id) >= 0) return next();
|
441 | if (self._external.indexOf(row.file) >= 0) return next();
|
442 |
|
443 | if (isAbsolutePath(row.id)) {
|
444 | row.id = '/' + relativePath(basedir, row.file);
|
445 | }
|
446 | Object.keys(row.deps || {}).forEach(function (key) {
|
447 | row.deps[key] = '/' + relativePath(basedir, row.deps[key]);
|
448 | });
|
449 | this.push(row);
|
450 | next();
|
451 | }));
|
452 | }
|
453 | return pipeline;
|
454 | };
|
455 |
|
456 | Browserify.prototype._createDeps = function (opts) {
|
457 | var self = this;
|
458 | var mopts = xtend(opts);
|
459 | var basedir = defined(opts.basedir, process.cwd());
|
460 |
|
461 |
|
462 |
|
463 | mopts.expose = this._expose;
|
464 | mopts.extensions = [ '.js', '.json' ].concat(mopts.extensions || []);
|
465 | self._extensions = mopts.extensions;
|
466 |
|
467 | mopts.transform = [];
|
468 | mopts.transformKey = defined(opts.transformKey, [ 'browserify', 'transform' ]);
|
469 | mopts.postFilter = function (id, file, pkg) {
|
470 | if (opts.postFilter && !opts.postFilter(id, file, pkg)) return false;
|
471 | if (self._external.indexOf(file) >= 0) return false;
|
472 | if (self._exclude.indexOf(file) >= 0) return false;
|
473 |
|
474 |
|
475 | if (pkg && pkg.browserify && pkg.browserify.transform) {
|
476 |
|
477 | pkg.browserify.transform = [].concat(pkg.browserify.transform)
|
478 | .filter(Boolean)
|
479 | .filter(self._filterTransform);
|
480 | }
|
481 | return true;
|
482 | };
|
483 | mopts.filter = function (id) {
|
484 | if (opts.filter && !opts.filter(id)) return false;
|
485 | if (self._external.indexOf(id) >= 0) return false;
|
486 | if (self._exclude.indexOf(id) >= 0) return false;
|
487 | if (opts.bundleExternal === false && isExternalModule(id)) {
|
488 | return false;
|
489 | }
|
490 | return true;
|
491 | };
|
492 | mopts.resolve = function (id, parent, cb) {
|
493 | if (self._ignore.indexOf(id) >= 0) return cb(null, paths.empty, {});
|
494 |
|
495 | self._bresolve(id, parent, function (err, file, pkg) {
|
496 | if (file && self._ignore.indexOf(file) >= 0) {
|
497 | return cb(null, paths.empty, {});
|
498 | }
|
499 | if (file && self._ignore.length) {
|
500 | var nm = file.replace(/\\/g, '/').split('/node_modules/')[1];
|
501 | if (nm) {
|
502 | nm = nm.split('/')[0];
|
503 | if (self._ignore.indexOf(nm) >= 0) {
|
504 | return cb(null, paths.empty, {});
|
505 | }
|
506 | }
|
507 | }
|
508 |
|
509 | if (file) {
|
510 | var ex = '/' + relativePath(basedir, file);
|
511 | if (self._external.indexOf(ex) >= 0) {
|
512 | return cb(null, ex);
|
513 | }
|
514 | if (self._exclude.indexOf(ex) >= 0) {
|
515 | return cb(null, ex);
|
516 | }
|
517 | if (self._ignore.indexOf(ex) >= 0) {
|
518 | return cb(null, paths.empty, {});
|
519 | }
|
520 | }
|
521 | if (err) cb(err, file, pkg)
|
522 | else if (file) {
|
523 | if (opts.preserveSymlinks && parent.id !== self._mdeps.top.id) {
|
524 | return cb(err, path.resolve(file), pkg, file)
|
525 | }
|
526 |
|
527 | fs.realpath(file, function (err, res) {
|
528 | cb(err, res, pkg, file);
|
529 | });
|
530 | } else cb(err, null, pkg)
|
531 | });
|
532 | };
|
533 |
|
534 | if (opts.builtins === false) {
|
535 | mopts.modules = {};
|
536 | self._exclude.push.apply(self._exclude, Object.keys(builtins));
|
537 | }
|
538 | else if (opts.builtins && isArray(opts.builtins)) {
|
539 | mopts.modules = {};
|
540 | opts.builtins.forEach(function (key) {
|
541 | mopts.modules[key] = builtins[key];
|
542 | });
|
543 | }
|
544 | else if (opts.builtins && typeof opts.builtins === 'object') {
|
545 | mopts.modules = opts.builtins;
|
546 | }
|
547 | else mopts.modules = xtend(builtins);
|
548 |
|
549 | Object.keys(builtins).forEach(function (key) {
|
550 | if (!has(mopts.modules, key)) self._exclude.push(key);
|
551 | });
|
552 |
|
553 | mopts.globalTransform = [];
|
554 | if (!this._bundled) {
|
555 | this.once('bundle', function () {
|
556 | self.pipeline.write({
|
557 | transform: globalTr,
|
558 | global: true,
|
559 | options: {}
|
560 | });
|
561 | });
|
562 | }
|
563 |
|
564 | var no = [].concat(opts.noParse).filter(Boolean);
|
565 | var absno = no.filter(function(x) {
|
566 | return typeof x === 'string';
|
567 | }).map(function (x) {
|
568 | return path.resolve(basedir, x);
|
569 | });
|
570 |
|
571 | function globalTr (file) {
|
572 | if (opts.detectGlobals === false) return through();
|
573 |
|
574 | if (opts.noParse === true) return through();
|
575 | if (no.indexOf(file) >= 0) return through();
|
576 | if (absno.indexOf(file) >= 0) return through();
|
577 |
|
578 | var parts = file.replace(/\\/g, '/').split('/node_modules/');
|
579 | for (var i = 0; i < no.length; i++) {
|
580 | if (typeof no[i] === 'function' && no[i](file)) {
|
581 | return through();
|
582 | }
|
583 | else if (no[i] === parts[parts.length-1].split('/')[0]) {
|
584 | return through();
|
585 | }
|
586 | else if (no[i] === parts[parts.length-1]) {
|
587 | return through();
|
588 | }
|
589 | }
|
590 |
|
591 | if (opts.commondir === false && opts.builtins === false) {
|
592 | opts.insertGlobalVars = xtend({
|
593 | __dirname: function(file, basedir) {
|
594 | var dir = path.dirname(path.relative(basedir, file));
|
595 | return 'require("path").join(__dirname,' + dir.split(path.sep).map(JSON.stringify).join(',') + ')';
|
596 | },
|
597 | __filename: function(file, basedir) {
|
598 | var filename = path.relative(basedir, file);
|
599 | return 'require("path").join(__dirname,' + filename.split(path.sep).map(JSON.stringify).join(',') + ')';
|
600 | }
|
601 | }, opts.insertGlobalVars);
|
602 | }
|
603 |
|
604 | var vars = xtend({
|
605 | process: function () { return "require('_process')" },
|
606 | }, opts.insertGlobalVars);
|
607 |
|
608 | if (opts.bundleExternal === false) {
|
609 | vars.process = undefined;
|
610 | vars.buffer = undefined;
|
611 | }
|
612 |
|
613 | return insertGlobals(file, xtend(opts, {
|
614 | debug: opts.debug,
|
615 | always: opts.insertGlobals,
|
616 | basedir: opts.commondir === false && isArray(opts.builtins)
|
617 | ? '/'
|
618 | : opts.basedir || process.cwd()
|
619 | ,
|
620 | vars: vars
|
621 | }));
|
622 | }
|
623 | return mdeps(mopts);
|
624 | };
|
625 |
|
626 | Browserify.prototype._recorder = function (opts) {
|
627 | var self = this;
|
628 | var ended = false;
|
629 | this._recorded = [];
|
630 |
|
631 | if (!this._ticked) {
|
632 | process.nextTick(function () {
|
633 | self._ticked = true;
|
634 | self._recorded.forEach(function (row) {
|
635 | stream.push(row);
|
636 | });
|
637 | if (ended) stream.push(null);
|
638 | });
|
639 | }
|
640 |
|
641 | var stream = through.obj(write, end);
|
642 | return stream;
|
643 |
|
644 | function write (row, enc, next) {
|
645 | self._recorded.push(row);
|
646 | if (self._ticked) this.push(row);
|
647 | next();
|
648 | }
|
649 | function end () {
|
650 | ended = true;
|
651 | if (self._ticked) this.push(null);
|
652 | }
|
653 | };
|
654 |
|
655 | Browserify.prototype._json = function () {
|
656 | return through.obj(function (row, enc, next) {
|
657 | if (/\.json$/.test(row.file)) {
|
658 | row.source = 'module.exports=' + sanitize(row.source);
|
659 | }
|
660 | this.push(row);
|
661 | next();
|
662 | });
|
663 | };
|
664 |
|
665 | Browserify.prototype._unbom = function () {
|
666 | return through.obj(function (row, enc, next) {
|
667 | if (/^\ufeff/.test(row.source)) {
|
668 | row.source = row.source.replace(/^\ufeff/, '');
|
669 | }
|
670 | this.push(row);
|
671 | next();
|
672 | });
|
673 | };
|
674 |
|
675 | Browserify.prototype._unshebang = function () {
|
676 | return through.obj(function (row, enc, next) {
|
677 | if (/^#!/.test(row.source)) {
|
678 | row.source = row.source.replace(/^#![^\n]*\n/, '');
|
679 | }
|
680 | this.push(row);
|
681 | next();
|
682 | });
|
683 | };
|
684 |
|
685 | Browserify.prototype._syntax = function () {
|
686 | var self = this;
|
687 | return through.obj(function (row, enc, next) {
|
688 | var h = shasum(row.source);
|
689 | if (typeof self._syntaxCache[h] === 'undefined') {
|
690 | var err = syntaxError(row.source, row.file || row.id);
|
691 | if (err) return this.emit('error', err);
|
692 | self._syntaxCache[h] = true;
|
693 | }
|
694 | this.push(row);
|
695 | next();
|
696 | });
|
697 | };
|
698 |
|
699 | Browserify.prototype._dedupe = function () {
|
700 | return through.obj(function (row, enc, next) {
|
701 | if (!row.dedupeIndex && row.dedupe) {
|
702 | row.source = 'arguments[4]['
|
703 | + JSON.stringify(row.dedupe)
|
704 | + '][0].apply(exports,arguments)'
|
705 | ;
|
706 | row.nomap = true;
|
707 | }
|
708 | else if (row.dedupeIndex) {
|
709 | row.source = 'arguments[4]['
|
710 | + JSON.stringify(row.dedupeIndex)
|
711 | + '][0].apply(exports,arguments)'
|
712 | ;
|
713 | row.nomap = true;
|
714 | }
|
715 | if (row.dedupeIndex && row.indexDeps) {
|
716 | row.indexDeps.dup = row.dedupeIndex;
|
717 | }
|
718 | this.push(row);
|
719 | next();
|
720 | });
|
721 | };
|
722 |
|
723 | Browserify.prototype._label = function (opts) {
|
724 | var self = this;
|
725 | var basedir = defined(opts.basedir, process.cwd());
|
726 |
|
727 | return through.obj(function (row, enc, next) {
|
728 | var prev = row.id;
|
729 |
|
730 | if (self._external.indexOf(row.id) >= 0) return next();
|
731 | if (self._external.indexOf('/' + relativePath(basedir, row.id)) >= 0) {
|
732 | return next();
|
733 | }
|
734 | if (self._external.indexOf(row.file) >= 0) return next();
|
735 |
|
736 | if (row.index) row.id = row.index;
|
737 |
|
738 | self.emit('label', prev, row.id);
|
739 | if (row.indexDeps) row.deps = row.indexDeps || {};
|
740 |
|
741 | Object.keys(row.deps).forEach(function (key) {
|
742 | if (self._expose[key]) {
|
743 | row.deps[key] = key;
|
744 | return;
|
745 | }
|
746 |
|
747 | var afile = path.resolve(path.dirname(row.file), key);
|
748 | var rfile = '/' + relativePath(basedir, afile);
|
749 | if (self._external.indexOf(rfile) >= 0) {
|
750 | row.deps[key] = rfile;
|
751 | }
|
752 | if (self._external.indexOf(afile) >= 0) {
|
753 | row.deps[key] = rfile;
|
754 | }
|
755 | if (self._external.indexOf(key) >= 0) {
|
756 | row.deps[key] = key;
|
757 | return;
|
758 | }
|
759 |
|
760 | for (var i = 0; i < self._extensions.length; i++) {
|
761 | var ex = self._extensions[i];
|
762 | if (self._external.indexOf(rfile + ex) >= 0) {
|
763 | row.deps[key] = rfile + ex;
|
764 | break;
|
765 | }
|
766 | }
|
767 | });
|
768 |
|
769 | if (row.entry || row.expose) {
|
770 | self._bpack.standaloneModule = row.id;
|
771 | }
|
772 | this.push(row);
|
773 | next();
|
774 | });
|
775 | };
|
776 |
|
777 | Browserify.prototype._emitDeps = function () {
|
778 | var self = this;
|
779 | return through.obj(function (row, enc, next) {
|
780 | self.emit('dep', row);
|
781 | this.push(row);
|
782 | next();
|
783 | })
|
784 | };
|
785 |
|
786 | Browserify.prototype._debug = function (opts) {
|
787 | var basedir = defined(opts.basedir, process.cwd());
|
788 | return through.obj(function (row, enc, next) {
|
789 | if (opts.debug) {
|
790 | row.sourceRoot = 'file://localhost';
|
791 | row.sourceFile = relativePath(basedir, row.file);
|
792 | }
|
793 | this.push(row);
|
794 | next();
|
795 | });
|
796 | };
|
797 |
|
798 | Browserify.prototype.reset = function (opts) {
|
799 | if (!opts) opts = {};
|
800 | var hadExports = this._bpack.hasExports;
|
801 | this.pipeline = this._createPipeline(xtend(opts, this._options));
|
802 | this._bpack.hasExports = hadExports;
|
803 | this._entryOrder = 0;
|
804 | this._bundled = false;
|
805 | this.emit('reset');
|
806 | };
|
807 |
|
808 | Browserify.prototype.bundle = function (cb) {
|
809 | var self = this;
|
810 | if (cb && typeof cb === 'object') {
|
811 | throw new Error(
|
812 | 'bundle() no longer accepts option arguments.\n'
|
813 | + 'Move all option arguments to the browserify() constructor.'
|
814 | );
|
815 | }
|
816 | if (this._bundled) {
|
817 | var recorded = this._recorded;
|
818 | this.reset();
|
819 | recorded.forEach(function (x) {
|
820 | self.pipeline.write(x);
|
821 | });
|
822 | }
|
823 | var output = readonly(this.pipeline);
|
824 | if (cb) {
|
825 | output.on('error', cb);
|
826 | output.pipe(concat(function (body) {
|
827 | cb(null, body);
|
828 | }));
|
829 | }
|
830 |
|
831 | function ready () {
|
832 | self.emit('bundle', output);
|
833 | self.pipeline.end();
|
834 | }
|
835 |
|
836 | if (this._pending === 0) ready();
|
837 | else this.once('_ready', ready);
|
838 |
|
839 | this._bundled = true;
|
840 | return output;
|
841 | };
|
842 |
|
843 | function isStream (s) { return s && typeof s.pipe === 'function' }
|
844 | function isAbsolutePath (file) {
|
845 | var regexp = process.platform === 'win32' ?
|
846 | /^\w:/ :
|
847 | /^\
|
848 | return regexp.test(file);
|
849 | }
|
850 | function isExternalModule (file) {
|
851 | var regexp = process.platform === 'win32' ?
|
852 | /^(\.|\w:)/ :
|
853 | /^[\/.]/;
|
854 | return !regexp.test(file);
|
855 | }
|
856 | function relativePath (from, to) {
|
857 |
|
858 | return cachedPathRelative(from, to).replace(/\\/g, '/');
|
859 | }
|