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