UNPKG

8.54 kBJavaScriptView Raw
1var browserify = require('../');
2var path = require('path');
3var spawn = require('child_process').spawn;
4var parseShell = require('shell-quote').parse;
5var insertGlobals = require('insert-module-globals');
6var duplexer = require('duplexer2');
7var subarg = require('subarg');
8var glob = require('glob');
9var Readable = require('readable-stream').Readable;
10var xtend = require('xtend');
11
12module.exports = function (args, opts) {
13 var argv = subarg(args, {
14 'boolean': [
15 'deps', 'pack', 'ig', 'dg', 'im', 'd', 'list', 'builtins',
16 'commondir', 'bare', 'full-paths', 'bundle-external', 'bf',
17 'node', 'preserve-symlinks'
18 ],
19 string: [ 's', 'r', 'u', 'x', 't', 'i', 'o', 'e', 'c', 'it' ],
20 alias: {
21 ig: [ 'insert-globals', 'fast' ],
22 dg: [ 'detect-globals', 'detectGlobals', 'dg' ],
23 bf: [ 'browser-field', 'browserField' ],
24 im: 'ignore-missing',
25 it: 'ignore-transform',
26 igv: 'insert-global-vars',
27 d: 'debug',
28 s: 'standalone',
29 noParse: [ 'noparse' ],
30 'full-paths': [ 'fullpaths', 'fullPaths' ],
31 r: 'require',
32 u: 'exclude',
33 x: 'external',
34 t: 'transform',
35 i: 'ignore',
36 o: 'outfile',
37 e: 'entry',
38 c: 'command',
39 bare: 'bear'
40 },
41 'default': {
42 ig: false,
43 im: false,
44 dg: true,
45 d: false,
46 builtins: true,
47 commondir: true,
48 'bundle-external': true,
49 bf: true,
50 dedupe: true,
51 node: false
52 }
53 });
54
55 var entries = argv._.concat(argv.entry)
56 .filter(Boolean).map(function (entry) {
57 if (entry === '-') {
58 var s = process.stdin;
59 if (typeof s.read === 'function') return s;
60 // only needed for 0.8, remove at some point later:
61 var rs = Readable().wrap(s);
62 s.resume();
63 return rs;
64 }
65 return entry;
66 });
67
68 if (argv.igv) {
69 var insertGlobalVars = {};
70 var wantedGlobalVars = argv.igv.split(',');
71 Object.keys(insertGlobals.vars).forEach(function (x) {
72 if (wantedGlobalVars.indexOf(x) === -1) {
73 insertGlobalVars[x] = undefined;
74 }
75 });
76 }
77
78 var ignoreTransform = argv['ignore-transform'] || argv.it;
79 var b = browserify(xtend({
80 node: argv.node,
81 bare: argv.bare,
82 noParse: Array.isArray(argv.noParse) ? argv.noParse : [argv.noParse],
83 extensions: [].concat(argv.extension).filter(Boolean).map(function (extension) {
84 if (extension.charAt(0) != '.') {
85 return '.' + extension;
86 } else {
87 return extension
88 }
89 }),
90 ignoreTransform: [].concat(ignoreTransform).filter(Boolean),
91 entries: entries,
92 fullPaths: argv['full-paths'],
93 builtins: argv.builtins === false ? false : undefined,
94 commondir: argv.commondir === false ? false : undefined,
95 bundleExternal: argv['bundle-external'],
96 basedir: argv.basedir,
97 browserField: argv.browserField,
98 transformKey: argv['transform-key'] ? ['browserify', argv['transform-key']] : undefined,
99 dedupe: argv['dedupe'],
100 preserveSymlinks: argv['preserve-symlinks'],
101
102 detectGlobals: argv.detectGlobals,
103 insertGlobals: argv['insert-globals'] || argv.ig,
104 insertGlobalVars: insertGlobalVars,
105 ignoreMissing: argv['ignore-missing'] || argv.im,
106 debug: argv['debug'] || argv.d,
107 standalone: argv['standalone'] || argv.s
108 }, opts));
109 function error (msg) {
110 var e = new Error(msg);
111 process.nextTick(function () { b.emit('error', e) });
112 }
113 b.argv = argv;
114 [].concat(argv.p).concat(argv.plugin).filter(Boolean)
115 .forEach(function (p) {
116 var pf = p, pOpts = {};
117 if (typeof p === 'object') {
118 pf = p._.shift(), pOpts = p;
119 }
120 b.plugin(pf, pOpts);
121 })
122 ;
123
124 [].concat(argv.ignore).filter(Boolean)
125 .forEach(function (i) {
126 b._pending ++;
127 glob(i, function (err, files) {
128 if (err) return b.emit('error', err);
129 if (files.length === 0) {
130 b.ignore(i);
131 }
132 else {
133 files.forEach(function (file) { b.ignore(file) });
134 }
135 if (--b._pending === 0) b.emit('_ready');
136 });
137 })
138 ;
139
140 [].concat(argv.exclude).filter(Boolean)
141 .forEach(function (u) {
142 b.exclude(u);
143
144 b._pending ++;
145 glob(u, function (err, files) {
146 if (err) return b.emit('error', err);
147 files.forEach(function (file) { b.exclude(file) });
148 if (--b._pending === 0) b.emit('_ready');
149 });
150 })
151 ;
152
153 [].concat(argv.require).filter(Boolean)
154 .forEach(function (r) {
155 var xs = splitOnColon(r);
156 b.require(xs[0], { expose: xs.length === 1 ? xs[0] : xs[1] })
157 })
158 ;
159
160 // resolve any external files and add them to the bundle as externals
161 [].concat(argv.external).filter(Boolean)
162 .forEach(function (x) {
163 var xs = splitOnColon(x);
164 if (xs.length === 2) {
165 add(xs[0], { expose: xs[1] });
166 }
167 else if (/\*/.test(x)) {
168 b.external(x);
169 glob(x, function (err, files) {
170 files.forEach(function (file) {
171 add(file, {});
172 });
173 });
174 }
175 else add(x, {});
176
177 function add (x, opts) {
178 if (/^[\/.]/.test(x)) b.external(path.resolve(x), opts)
179 else b.external(x, opts)
180 }
181 })
182 ;
183
184 [].concat(argv.transform)
185 .filter(Boolean)
186 .forEach(function (t) { addTransform(t) })
187 ;
188
189 [].concat(argv.g).concat(argv['global-transform'])
190 .filter(Boolean)
191 .forEach(function (t) {
192 addTransform(t, { global: true });
193 })
194 ;
195
196 function addTransform (t, opts) {
197 if (typeof t === 'string' || typeof t === 'function') {
198 b.transform(opts, t);
199 }
200 else if (t && typeof t === 'object') {
201 if (!t._[0] || typeof t._[0] !== 'string') {
202 return error(
203 'expected first parameter to be a transform string'
204 );
205 }
206 if (opts) Object.keys(opts).forEach(function (key) {
207 t[key] = opts[key];
208 });
209 b.transform(t, t._.shift());
210 }
211 else error('unexpected transform of type ' + typeof t);
212 }
213
214 [].concat(argv.command).filter(Boolean)
215 .forEach(function (c) {
216 var cmd = parseShell(c);
217 b.transform(function (file) {
218 var env = Object.keys(process.env).reduce(function (acc, key) {
219 acc[key] = process.env[key];
220 return acc;
221 }, {});
222 env.FILENAME = file;
223 var ps = spawn(cmd[0], cmd.slice(1), { env: env });
224 var error = '';
225 ps.stderr.on('data', function (buf) { error += buf });
226
227 ps.on('exit', function (code) {
228 if (code === 0) return;
229 console.error([
230 'error running source transform command: ' + c,
231 error.split('\n').join('\n '),
232 ''
233 ].join('\n'));
234 process.exit(1);
235 });
236 return duplexer(ps.stdin, ps.stdout);
237 });
238 })
239 ;
240
241 if (argv.standalone === '') {
242 error('--standalone requires an export name argument');
243 return b;
244 }
245
246 return b;
247};
248
249function splitOnColon (f) {
250 var pos = f.lastIndexOf(':');
251 if (pos == -1) {
252 return [f]; // No colon
253 } else {
254 if ((/[a-zA-Z]:[\\/]/.test(f)) && (pos == 1)){
255 return [f]; // Windows path and colon is part of drive name
256 } else {
257 return [f.substr(0, pos), f.substr(pos + 1)];
258 }
259 }
260}