1 | var browserify = require('../');
|
2 | var path = require('path');
|
3 | var spawn = require('child_process').spawn;
|
4 | var parseShell = require('shell-quote').parse;
|
5 | var insertGlobals = require('insert-module-globals');
|
6 | var duplexer = require('duplexer2');
|
7 | var subarg = require('subarg');
|
8 | var glob = require('glob');
|
9 | var Readable = require('readable-stream').Readable;
|
10 | var xtend = require('xtend');
|
11 |
|
12 | module.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 |
|
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 |
|
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 |
|
249 | function splitOnColon (f) {
|
250 | var pos = f.lastIndexOf(':');
|
251 | if (pos == -1) {
|
252 | return [f];
|
253 | } else {
|
254 | if ((/[a-zA-Z]:[\\/]/.test(f)) && (pos == 1)){
|
255 | return [f];
|
256 | } else {
|
257 | return [f.substr(0, pos), f.substr(pos + 1)];
|
258 | }
|
259 | }
|
260 | }
|