1 | var Promise = require('bluebird');
|
2 |
|
3 | var System = require('systemjs');
|
4 |
|
5 | var asp = require('bluebird').promisify;
|
6 | var fs = require('fs');
|
7 | var path = require('path');
|
8 |
|
9 | var extend = require('./utils').extend;
|
10 |
|
11 | var attachCompilers = require('./compile').attachCompilers;
|
12 | var compileTree = require('./compile').compileTree;
|
13 | var compileLoad = require('./compile').compileLoad;
|
14 | var pluginBundleHook = require('./compile').pluginBundleHook;
|
15 | var writeOutputs = require('./output').writeOutputs;
|
16 |
|
17 | var traceExpression = require('./arithmetic').traceExpression;
|
18 |
|
19 | var Trace = require('./trace');
|
20 |
|
21 | var getCanonicalName = require('./utils').getCanonicalName;
|
22 |
|
23 | var fromFileURL = require('./utils').fromFileURL;
|
24 | var toFileURL = require('./utils').toFileURL;
|
25 |
|
26 | var createHash = require('crypto').createHash;
|
27 | var getFormatHint = require('./utils').getFormatHint;
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 | function Builder(baseURL, cfg) {
|
37 | if (typeof baseURL == 'object') {
|
38 | cfg = baseURL;
|
39 | baseURL = null;
|
40 | }
|
41 |
|
42 | this.loader = null;
|
43 | this.resetConfig = function() {};
|
44 |
|
45 | this.reset();
|
46 |
|
47 | if (baseURL)
|
48 | this.config({ baseURL: baseURL });
|
49 |
|
50 |
|
51 |
|
52 | if (typeof cfg == 'object')
|
53 | this.config(cfg, true, !!baseURL);
|
54 | else if (typeof cfg == 'string')
|
55 | this.loadConfigSync(cfg, true, !!baseURL);
|
56 | }
|
57 |
|
58 |
|
59 |
|
60 | Builder.prototype.invalidate = function(invalidationModuleName) {
|
61 | var loader = this.loader;
|
62 |
|
63 | var invalidated = [];
|
64 |
|
65 | var self = this;
|
66 |
|
67 |
|
68 | invalidationModuleName = loader.decanonicalize(invalidationModuleName);
|
69 |
|
70 |
|
71 | var invalidationWildcardIndex = invalidationModuleName.indexOf('*');
|
72 | if (invalidationModuleName.lastIndexOf('*') != invalidationWildcardIndex)
|
73 | throw new TypeError('Only a single wildcard supported for invalidation.');
|
74 |
|
75 | if (invalidationWildcardIndex != -1) {
|
76 | var wildcardLHS = invalidationModuleName.substr(0, invalidationWildcardIndex);
|
77 | var wildcardRHS = invalidationModuleName.substr(invalidationWildcardIndex + 1);
|
78 | }
|
79 |
|
80 | function matchesInvalidation(moduleName) {
|
81 | if (moduleName == invalidationModuleName)
|
82 | return true;
|
83 |
|
84 | if (invalidationWildcardIndex == -1)
|
85 | return false;
|
86 |
|
87 | return moduleName.substr(0, invalidationWildcardIndex) == wildcardLHS
|
88 | && moduleName.substr(moduleName.length - wildcardRHS.length) == wildcardRHS;
|
89 | }
|
90 |
|
91 |
|
92 | var traceCache = this.cache.trace;
|
93 | Object.keys(traceCache).forEach(function(canonical) {
|
94 | var moduleName = loader.decanonicalize(canonical);
|
95 | if (matchesInvalidation(moduleName)) {
|
96 | if (traceCache[canonical])
|
97 | invalidated.push(moduleName);
|
98 | traceCache[canonical] = undefined;
|
99 | }
|
100 | });
|
101 |
|
102 |
|
103 | var pluginLoader = loader.pluginLoader;
|
104 | Object.keys(pluginLoader._loader.modules).forEach(function(moduleName) {
|
105 | if (matchesInvalidation(moduleName)) {
|
106 | invalidated.push(moduleName);
|
107 | pluginLoader.delete(moduleName);
|
108 | }
|
109 | });
|
110 |
|
111 |
|
112 | loader.defined = {};
|
113 |
|
114 |
|
115 |
|
116 |
|
117 | return invalidated;
|
118 | };
|
119 |
|
120 | Builder.prototype.reset = function(baseLoader) {
|
121 | baseLoader = baseLoader || this.loader || System;
|
122 |
|
123 | var loader = this.loader = new baseLoader.constructor();
|
124 |
|
125 | loader.builder = this;
|
126 |
|
127 | loader.config({ build: true });
|
128 |
|
129 | loader.import = function(name) {
|
130 | return Promise.reject(new Error('Unable to import "' + name + '".\nThe incorrect instance of System is being used to System.import.'));
|
131 | };
|
132 |
|
133 |
|
134 | loader._loader.loadedTranspilerRuntime = true;
|
135 |
|
136 | var pluginLoader = loader.pluginLoader = new baseLoader.constructor();
|
137 | pluginLoader.config({ build: true });
|
138 |
|
139 | loader.constructor = pluginLoader.constructor = baseLoader.constructor;
|
140 | loader.baseURL = pluginLoader.baseURL = baseLoader.baseURL;
|
141 |
|
142 | loader.normalize = pluginLoader.normalize = baseLoader.normalize;
|
143 | loader.normalizeSync = pluginLoader.normalizeSync = baseLoader.normalizeSync;
|
144 |
|
145 |
|
146 | loader.originalHooks = baseLoader.originalHooks || {
|
147 | locate: baseLoader.locate,
|
148 | fetch: baseLoader.fetch,
|
149 | translate: baseLoader.translate,
|
150 | instantiate: baseLoader.instantiate
|
151 | };
|
152 |
|
153 | loader.locate = pluginLoader.locate = loader.originalHooks.locate;
|
154 | loader.fetch = pluginLoader.fetch = loader.originalHooks.fetch;
|
155 | loader.translate = pluginLoader.translate = loader.originalHooks.translate;
|
156 | loader.instantiate = pluginLoader.instantiate = loader.originalHooks.instantiate;
|
157 |
|
158 | var loaderConfig = loader.config;
|
159 | loader.config = function(cfg) {
|
160 |
|
161 | loader.pluginLoader.config(cfg);
|
162 | var lCfg = extend({}, cfg);
|
163 | loaderConfig.call(this, lCfg);
|
164 | loader.configHash = generateConfigHash(loader);
|
165 | };
|
166 |
|
167 | this.getCanonicalName = getCanonicalName.bind(null, this.loader);
|
168 | this.loader.getCanonicalName = this.loader.pluginLoader.getCanonicalName = this.getCanonicalName;
|
169 |
|
170 | attachCompilers(loader);
|
171 |
|
172 | var builder = this;
|
173 |
|
174 |
|
175 | var loaderFetch = loader.fetch;
|
176 | var cachedFetch = function(load) {
|
177 | return Promise.resolve(loaderFetch.call(this, load))
|
178 | .then(function(source) {
|
179 |
|
180 | return asp(fs.stat)(fromFileURL(load.address))
|
181 | .then(function(stats) {
|
182 | load.metadata.timestamp = stats.mtime.getTime();
|
183 | return source;
|
184 | }, function(err) {
|
185 |
|
186 | if (err.code == 'ENOENT' && load.metadata.loader)
|
187 | return source;
|
188 | throw err;
|
189 | });
|
190 | });
|
191 | };
|
192 |
|
193 | loader.fetch = function(load) {
|
194 | if (builder.fetch)
|
195 | return Promise.resolve(builder.fetch.call(this, load, cachedFetch.bind(this)));
|
196 | else
|
197 | return cachedFetch.call(this, load);
|
198 | };
|
199 |
|
200 |
|
201 |
|
202 |
|
203 |
|
204 | var loaderNormalize = loader.normalize;
|
205 | loader.normalize = function(name, parentName, parentAddress) {
|
206 | var pkgConditional;
|
207 | var pkgConditionalIndex = name.indexOf('/#:');
|
208 | if (pkgConditionalIndex != -1) {
|
209 | pkgConditional = name.substr(pkgConditionalIndex);
|
210 | name = name.substr(0, pkgConditionalIndex + 1);
|
211 | }
|
212 | return loaderNormalize.call(this, name, parentName, parentAddress)
|
213 | .then(function(normalized) {
|
214 | if (pkgConditional)
|
215 | normalized = normalized + pkgConditional;
|
216 | return normalized;
|
217 | });
|
218 | };
|
219 |
|
220 | var loaderNormalizeSync = loader.normalizeSync;
|
221 | loader.normalizeSync = function(name, parentName, parentAddress) {
|
222 | var pkgConditional;
|
223 | var pkgConditionalIndex = name.indexOf('#:');
|
224 | if (pkgConditionalIndex != -1) {
|
225 | pkgConditional = name.substr(pkgConditionalIndex);
|
226 | name = name.substr(0, pkgConditionalIndex) + '/';
|
227 | }
|
228 | var normalized = loaderNormalizeSync.call(this, name, parentName, parentAddress);
|
229 | if (pkgConditional)
|
230 | normalized = normalized.substr(0, normalized.length - 1) + pkgConditional;
|
231 | return normalized;
|
232 | };
|
233 |
|
234 |
|
235 | this.resetConfig();
|
236 |
|
237 |
|
238 | this.setCache(this.cache || {});
|
239 |
|
240 |
|
241 | var traceCache = this.cache.trace;
|
242 | Object.keys(traceCache).forEach(function(canonical) {
|
243 | if (traceCache[canonical])
|
244 | traceCache[canonical].fresh = false;
|
245 | });
|
246 | };
|
247 |
|
248 | function generateConfigHash(loader) {
|
249 | return createHash('md5')
|
250 | .update(JSON.stringify({
|
251 | paths: loader.paths,
|
252 | packages: loader.packages,
|
253 | meta: loader.meta,
|
254 | map: loader.map
|
255 | }))
|
256 | .digest('hex');
|
257 | }
|
258 |
|
259 | Builder.prototype.setCache = function(cacheObj) {
|
260 | this.cache = {
|
261 | compile: cacheObj.compile || {},
|
262 | trace: cacheObj.trace || {}
|
263 | };
|
264 | this.cache.compile.encodings = this.cache.compile.encodings || {};
|
265 | this.cache.compile.loads = this.cache.compile.loads || {};
|
266 | this.tracer = new Trace(this.loader, this.cache.trace);
|
267 | };
|
268 |
|
269 | Builder.prototype.getCache = function() {
|
270 | return this.cache;
|
271 | };
|
272 |
|
273 | Builder.prototype.clearCache = function() {
|
274 | this.setCache({});
|
275 | };
|
276 |
|
277 | function executeConfigFile(saveForReset, ignoreBaseURL, configPath, source) {
|
278 | var self = this;
|
279 |
|
280 |
|
281 | var configLoader = Object.create(this.loader);
|
282 | configLoader.config = function(cfg) {
|
283 | self.config(cfg, saveForReset, ignoreBaseURL);
|
284 | };
|
285 |
|
286 |
|
287 |
|
288 |
|
289 | var context = Object.create(global);
|
290 | context.SystemJS = context.System = configLoader;
|
291 | context.global = context;
|
292 | if (process.versions.node && process.versions.node.split('.')[0] < 6)
|
293 | context.GLOBAL = context.root = context;
|
294 |
|
295 |
|
296 | var Module = require('module');
|
297 | var m = new Module(configPath);
|
298 | m.filename = configPath;
|
299 | m.paths = Module._nodeModulePaths(path.dirname(configPath));
|
300 | context.require = m.require.bind(m);
|
301 | require('vm').runInNewContext(source.toString(), context);
|
302 | }
|
303 |
|
304 | Builder.prototype.loadConfig = function(configFile, saveForReset, ignoreBaseURL) {
|
305 | return asp(fs.readFile)(configFile)
|
306 | .then(executeConfigFile.bind(this, saveForReset, ignoreBaseURL, configFile));
|
307 | };
|
308 |
|
309 | Builder.prototype.loadConfigSync = function(configFile, saveForReset, ignoreBaseURL) {
|
310 | var source = fs.readFileSync(configFile);
|
311 | executeConfigFile.call(this, saveForReset, ignoreBaseURL, configFile, source);
|
312 | };
|
313 |
|
314 |
|
315 | Builder.prototype.config = function(config, saveForReset, ignoreBaseURL) {
|
316 | var cfg = {};
|
317 | for (var p in config) {
|
318 | if (ignoreBaseURL && p == 'baseURL' || p == 'bundles' || p == 'depCache')
|
319 | continue;
|
320 | cfg[p] = config[p];
|
321 | }
|
322 | this.loader.config(cfg);
|
323 | if (saveForReset) {
|
324 |
|
325 | var curReset = this.resetConfig;
|
326 | this.resetConfig = function() {
|
327 | curReset.call(this);
|
328 | this.loader.config(cfg);
|
329 | };
|
330 | }
|
331 | };
|
332 |
|
333 |
|
334 |
|
335 |
|
336 | function processTraceOpts(options, defaults) {
|
337 | var opts = {
|
338 |
|
339 | outputESM: true,
|
340 | sourceMaps: false,
|
341 |
|
342 |
|
343 | browser: undefined,
|
344 | node: undefined,
|
345 | production: undefined,
|
346 | dev: undefined,
|
347 | conditions: {
|
348 | '@system-env|default': true,
|
349 | '@system-env|~default': false
|
350 | },
|
351 | inlineConditions: {},
|
352 | traceRuntimePlugin: true,
|
353 |
|
354 |
|
355 | tracePackageConfig: false,
|
356 |
|
357 |
|
358 |
|
359 | excludeURLs: true,
|
360 | externals: []
|
361 | };
|
362 |
|
363 |
|
364 | if (typeof options == 'object') {
|
365 | if (typeof options.browser == 'boolean' || typeof options.node == 'boolean') {
|
366 |
|
367 | if (typeof options.browser == 'boolean' && typeof options.node != 'boolean')
|
368 | options.node = !options.browser;
|
369 |
|
370 | else if (typeof options.node == 'boolean' && typeof options.browser != 'boolean')
|
371 | options.browser = !options.node;
|
372 | }
|
373 |
|
374 |
|
375 | if ('development' in options)
|
376 | options.dev = options.development;
|
377 | if (typeof options.dev == 'boolean' || typeof options.production == 'boolean') {
|
378 | if (typeof options.production != 'boolean')
|
379 | options.production = !options.dev;
|
380 | if (typeof options.dev != 'boolean')
|
381 | options.dev = !options.production;
|
382 | }
|
383 | }
|
384 |
|
385 | extend(opts, defaults);
|
386 | extend(opts, options);
|
387 |
|
388 |
|
389 | if (opts.globalDeps)
|
390 | opts.externals = opts.externals.concat(Object.keys(opts.globalDeps));
|
391 |
|
392 |
|
393 | if (typeof opts.browser == 'boolean') {
|
394 |
|
395 |
|
396 |
|
397 |
|
398 | opts.conditions['@system-env|browser'] = opts.browser;
|
399 | opts.conditions['@system-env|~browser'] = opts.browser === true ? opts.node : !opts.browser;
|
400 | opts.conditions['@system-env|node'] = opts.node;
|
401 | opts.conditions['@system-env|~node'] = opts.node === true ? opts.browser : !opts.node;
|
402 | }
|
403 | if (typeof opts.production == 'boolean') {
|
404 | opts.conditions['@system-env|production'] = opts.production;
|
405 | opts.conditions['@system-env|~production'] = opts.dev;
|
406 | opts.conditions['@system-env|dev'] = opts.dev;
|
407 | opts.conditions['@system-env|~dev'] = opts.production;
|
408 | }
|
409 |
|
410 | if (typeof opts.inlineConditions == 'object')
|
411 | extend(opts.conditions, opts.inlineConditions);
|
412 | else if (opts.inlineConditions === true)
|
413 | opts.inlineConditions = opts.conditions;
|
414 | else
|
415 | opts.inlineConditions = {};
|
416 |
|
417 | return opts;
|
418 | }
|
419 |
|
420 | Builder.prototype.trace = function(expression, opts) {
|
421 | if (opts && opts.config)
|
422 | this.config(opts.config);
|
423 |
|
424 | var traceOpts = processTraceOpts(opts);
|
425 | var self = this;
|
426 | return canonicalizeConditions(self.loader, traceOpts)
|
427 | .then(function() {
|
428 | return setExternals(this, traceOpts.externals);
|
429 | })
|
430 | .then(function() {
|
431 | return traceExpression(self, expression, traceOpts);
|
432 | });
|
433 | };
|
434 |
|
435 | Builder.prototype.traceConditionalEnv = function(expression, opts) {
|
436 | var traceOpts = processTraceOpts(opts);
|
437 |
|
438 | var self = this;
|
439 |
|
440 | return canonicalizeConditions(self.loader, traceOpts)
|
441 | .then(function() {
|
442 | return self.trace(expression, traceOpts);
|
443 | })
|
444 | .then(function(tree) {
|
445 | return Trace.getConditionalEnv(self, tree, traceOpts);
|
446 | });
|
447 | }
|
448 |
|
449 | function processCompileOpts(options, defaults) {
|
450 |
|
451 |
|
452 | options = options || {};
|
453 | if ('sfxFormat' in options) {
|
454 | console.warn('SystemJS Builder "sfxFormat" is deprecated and has been renamed to "format".');
|
455 | options.format = options.sfxFormat;
|
456 | }
|
457 | if ('sfxEncoding' in options) {
|
458 | console.warn('SystemJS Builder "sfxEncoding" is deprecated and has been renamed to "encodeNames".');
|
459 | options.encodeNames = sfxEncoding;
|
460 | }
|
461 | if ('sfxGlobals' in options) {
|
462 | console.warn('SystemJS Builder "sfxGlobals" is deprecated and has been renamed to "globalDeps".');
|
463 | options.globalDeps = options.sfxGlobals;
|
464 | }
|
465 | if ('sfxGlobalName' in options) {
|
466 | console.warn('SystemJS Builder "sfxGlobalName" is deprecated and has been renamed to "globalName".');
|
467 | options.globalName = options.sfxGlobalName;
|
468 | }
|
469 |
|
470 | var opts = {
|
471 | entryPoints: [],
|
472 | normalize: false,
|
473 | anonymous: false,
|
474 |
|
475 | systemGlobal: 'System',
|
476 |
|
477 | buildConfig: false,
|
478 | inlinePlugins: true,
|
479 | static: false,
|
480 | encodeNames: undefined,
|
481 |
|
482 | sourceMaps: false,
|
483 | lowResSourceMaps: false,
|
484 |
|
485 |
|
486 |
|
487 |
|
488 | runtime: false,
|
489 | format: 'umd',
|
490 | globalDeps: {},
|
491 | globalName: null,
|
492 | exportDefault: false,
|
493 |
|
494 |
|
495 |
|
496 |
|
497 | formatHint: false,
|
498 |
|
499 |
|
500 |
|
501 | production: undefined,
|
502 |
|
503 |
|
504 | rollup: true
|
505 | };
|
506 |
|
507 | extend(opts, defaults);
|
508 | extend(opts, options);
|
509 |
|
510 | if (options.encodeNames && !('encodeNames' in defaults))
|
511 | throw new Error('encodeNames is only supported for buildStatic.');
|
512 |
|
513 | if (typeof opts.production != 'boolean')
|
514 | opts.production = !opts.development;
|
515 |
|
516 | if (opts.static) {
|
517 | if (opts.encodeNames !== false)
|
518 | opts.encodeNames = true;
|
519 |
|
520 | if (options.runtime !== false)
|
521 | opts.runtime = true;
|
522 |
|
523 |
|
524 | opts.systemGlobal = '$__System';
|
525 |
|
526 |
|
527 | opts.normalize = true;
|
528 | }
|
529 |
|
530 | return opts;
|
531 | }
|
532 |
|
533 | Builder.prototype.compile = function(moduleNameOrLoad, outFile, opts) {
|
534 | if (outFile && typeof outFile == 'object') {
|
535 | opts = outFile;
|
536 | outFile = undefined;
|
537 | }
|
538 |
|
539 | if (opts && opts.config)
|
540 | this.config(opts.config);
|
541 |
|
542 | var self = this;
|
543 |
|
544 | var traceOpts = processTraceOpts(opts, { tracePackageConfig: false, browser: true, node: false, production: true, dev: false, outputESM: false });
|
545 |
|
546 | return Promise.resolve()
|
547 | .then(function() {
|
548 | return canonicalizeConditions(self.loader, traceOpts);
|
549 | })
|
550 | .then(function() {
|
551 | if (typeof moduleNameOrLoad != 'string')
|
552 | return moduleNameOrLoad;
|
553 | return self.loader.normalize(moduleNameOrLoad)
|
554 | .then(function(moduleName) {
|
555 | if (!opts || opts.cache !== true)
|
556 | self.invalidate(moduleName);
|
557 | return self.tracer.getLoadRecord(getCanonicalName(self.loader, moduleName), traceOpts);
|
558 | });
|
559 | })
|
560 | .then(function(load) {
|
561 | var compileOpts = processCompileOpts(opts, { normalize: false, anonymous: true });
|
562 | var outputOpts = processOutputOpts(opts, { outFile: outFile });
|
563 |
|
564 | return Promise.resolve()
|
565 | .then(function() {
|
566 | return compileLoad(self.loader, load, processCompileOpts(opts, { normalize: false, anonymous: true }), self.cache.compile);
|
567 | })
|
568 | .then(function(output) {
|
569 | if (load.metadata.loader)
|
570 | return pluginBundleHook(self.loader, [load], compileOpts, outputOpts)
|
571 | .then(function(bundleOutput) {
|
572 | return [output].concat(bundleOutput.outputs);
|
573 | });
|
574 |
|
575 | return [output];
|
576 | })
|
577 | .then(function(outputs) {
|
578 | return writeOutputs(outputs, self.loader.baseURL, outputOpts);
|
579 | });
|
580 | });
|
581 | };
|
582 |
|
583 | function processOutputOpts(options, defaults) {
|
584 | var opts = {
|
585 | outFile: undefined,
|
586 |
|
587 | minify: false,
|
588 | uglify: undefined,
|
589 | mangle: true,
|
590 |
|
591 | sourceMaps: false,
|
592 | sourceMapContents: undefined
|
593 | };
|
594 |
|
595 | extend(opts, defaults);
|
596 | extend(opts, options);
|
597 |
|
598 | opts.uglify = opts.uglify || {};
|
599 | opts.uglify.compress = opts.uglify.compress || {};
|
600 | opts.uglify.beautify = opts.uglify.beautify || {};
|
601 |
|
602 |
|
603 | if (opts.globalDefs && !('global_defs' in opts.uglify.compress))
|
604 | opts.uglify.compress.global_defs = opts.globalDefs;
|
605 | if (opts.ascii && !('ascii' in opts.uglify.beautify))
|
606 | opts.uglify.beautify.ascii_only = opts.ascii;
|
607 | delete opts.globalDefs;
|
608 | delete opts.ascii;
|
609 |
|
610 | if (!('dead_code' in opts.uglify.compress))
|
611 | opts.uglify.compress.dead_code = true;
|
612 | if (!('warnings' in opts.uglify.compress))
|
613 | opts.uglify.compress.warnings = false;
|
614 |
|
615 |
|
616 | if (opts.sourceMapContents === undefined)
|
617 | opts.sourceMapContents = opts.sourceMaps == 'inline';
|
618 |
|
619 | if (opts.sourceMapContents)
|
620 | opts.uglify.sourceMapIncludeSources = true;
|
621 |
|
622 | return opts;
|
623 | }
|
624 |
|
625 | function setExternals(builder, externals) {
|
626 | if (!externals)
|
627 | return Promise.resolve();
|
628 | var externalMeta;
|
629 | return Promise.all(externals.map(function(external) {
|
630 | externalMeta = externalMeta || {};
|
631 | return builder.loader.normalize(external)
|
632 | .then(function(normalizedExternal) {
|
633 | externalMeta[normalizedExternal] = { build: false };
|
634 | });
|
635 | }))
|
636 | .then(function() {
|
637 | if (externalMeta)
|
638 | builder.config({
|
639 | meta: externalMeta
|
640 | });
|
641 | });
|
642 | }
|
643 |
|
644 | function canonicalizeConditions(loader, traceOpts) {
|
645 | return Promise.resolve(Trace.toCanonicalConditionalEnv(loader, traceOpts.conditions))
|
646 | .then(function(canonicalConditionalEnv) {
|
647 | traceOpts.conditions = canonicalConditionalEnv;
|
648 |
|
649 | return Trace.toCanonicalConditionalEnv(loader, traceOpts.inlineConditions);
|
650 | })
|
651 | .then(function(canonicalInlineConditionalEnv) {
|
652 | traceOpts.inlineConditions = canonicalInlineConditionalEnv;
|
653 |
|
654 | return traceOpts;
|
655 | });
|
656 | }
|
657 |
|
658 |
|
659 | Builder.prototype.bundle = function(expressionOrTree, outFile, opts) {
|
660 | if (outFile && typeof outFile === 'object') {
|
661 | opts = outFile;
|
662 | outFile = undefined;
|
663 | }
|
664 |
|
665 | var self = this;
|
666 |
|
667 | if (opts && opts.config)
|
668 | this.config(opts.config);
|
669 |
|
670 | var outputOpts = processOutputOpts(opts, { outFile: outFile });
|
671 |
|
672 | var traceOpts = processTraceOpts(opts, { tracePackageConfig: true, browser: true, node: false, production: true, dev: false });
|
673 |
|
674 | var compileOpts = processCompileOpts(opts);
|
675 |
|
676 |
|
677 | if (opts && opts.fetch)
|
678 | this.fetch = opts.fetch;
|
679 |
|
680 | return Promise.resolve()
|
681 | .then(function() {
|
682 | return canonicalizeConditions(self.loader, traceOpts);
|
683 | })
|
684 | .then(function() {
|
685 | if (typeof expressionOrTree != 'string' && !(expressionOrTree instanceof Array))
|
686 | return expressionOrTree;
|
687 |
|
688 | return setExternals(self, traceOpts.externals)
|
689 | .then(function() {
|
690 | return traceExpression(self, expressionOrTree, traceOpts);
|
691 | });
|
692 | })
|
693 | .then(function(tree) {
|
694 | return Promise.resolve()
|
695 | .then(function() {
|
696 | if (compileOpts.inlineConditions)
|
697 | return self.tracer.inlineConditions(tree, self.loader, traceOpts);
|
698 | return tree;
|
699 | })
|
700 | .then(function(tree) {
|
701 | return compileTree(self.loader, tree, traceOpts, compileOpts, outputOpts, self.cache.compile)
|
702 | .then(function(compiled) {
|
703 | return writeOutputs(compiled.outputs, self.loader.baseURL, outputOpts)
|
704 | .then(function(output) {
|
705 | output.modules = compiled.modules;
|
706 | output.entryPoints = compiled.entryPoints;
|
707 | output.tree = tree;
|
708 | output.assetList = compiled.assetList;
|
709 | if (outputOpts.outFile) {
|
710 | try {
|
711 | output.bundleName = self.getCanonicalName(toFileURL(path.resolve(outputOpts.outFile)));
|
712 | }
|
713 | catch(e) {}
|
714 | }
|
715 | return output;
|
716 | });
|
717 | });
|
718 | });
|
719 | });
|
720 | };
|
721 |
|
722 |
|
723 | Builder.prototype.buildStatic = function(expressionOrTree, outFile, opts) {
|
724 | if (outFile && typeof outFile === 'object') {
|
725 | opts = outFile;
|
726 | outFile = undefined;
|
727 | }
|
728 |
|
729 | var self = this;
|
730 |
|
731 | if (opts && opts.config)
|
732 | this.config(opts.config);
|
733 |
|
734 |
|
735 |
|
736 | var entryPoints;
|
737 | if (typeof expressionOrTree == 'string')
|
738 | entryPoints = [expressionOrTree.split(/ [\+\&\-] /)[0]];
|
739 | else if (expressionOrTree instanceof Array)
|
740 | entryPoints = expressionOrTree[0];
|
741 | else
|
742 | entryPoints = [];
|
743 |
|
744 | if (entryPoints[0] && entryPoints[0].indexOf('*') != -1)
|
745 | entryPoints = [];
|
746 |
|
747 | var outputOpts = processOutputOpts(opts, { outFile: outFile });
|
748 |
|
749 | var traceOpts = processTraceOpts(opts, { tracePackageConfig: false, production: true, dev: false });
|
750 | var compileOpts = processCompileOpts(opts, { static: true, entryPoints: entryPoints, encodeNames: true });
|
751 | var inlineMap;
|
752 |
|
753 |
|
754 | if (opts && opts.fetch)
|
755 | this.fetch = opts.fetch;
|
756 |
|
757 | return Promise.resolve()
|
758 | .then(function() {
|
759 | return canonicalizeConditions(self.loader, traceOpts);
|
760 | })
|
761 | .then(function() {
|
762 | if (typeof expressionOrTree != 'string' && !(expressionOrTree instanceof Array))
|
763 | return expressionOrTree;
|
764 |
|
765 | return setExternals(self, traceOpts.externals)
|
766 | .then(function() {
|
767 | return traceExpression(self, expressionOrTree, traceOpts);
|
768 | });
|
769 | })
|
770 | .then(function(tree) {
|
771 |
|
772 | return self.tracer.inlineConditions(tree, self.loader, traceOpts)
|
773 | .then(function(inlinedTree) {
|
774 | if (!compileOpts.rollup)
|
775 | return compileTree(self.loader, inlinedTree, traceOpts, compileOpts, outputOpts, self.cache.compile);
|
776 |
|
777 | var rollupTree = require('./rollup').rollupTree;
|
778 |
|
779 |
|
780 | return rollupTree(self.loader, inlinedTree, [], traceOpts, compileOpts, outputOpts)
|
781 | .then(function(rolledUp) {
|
782 | inlineMap = rolledUp.inlineMap;
|
783 |
|
784 |
|
785 | if (rolledUp.tree)
|
786 | return compileTree(self.loader, rolledUp.tree, traceOpts, compileOpts, outputOpts, self.cache.compile);
|
787 |
|
788 |
|
789 | else if (rolledUp.outputs)
|
790 | return {
|
791 | outputs: (compileOpts.formatHint ? [getFormatHint(compileOpts)] : []).concat(rolledUp.outputs),
|
792 | assetList: rolledUp.assetList
|
793 | };
|
794 | })
|
795 | .then(function(compiled) {
|
796 | return {
|
797 | modules: Object.keys(tree).filter(function(m) {
|
798 | return tree[m] && !tree[m].conditional;
|
799 | }),
|
800 | assetList: compiled.assetList || [],
|
801 | outputs: compiled.outputs
|
802 | };
|
803 | })
|
804 | })
|
805 | .then(function(compiled) {
|
806 | return writeOutputs(compiled.outputs, self.loader.baseURL, outputOpts)
|
807 | .then(function(output) {
|
808 | if (inlineMap)
|
809 | output.inlineMap = inlineMap;
|
810 | output.assetList = compiled.assetList;
|
811 | output.modules = compiled.modules;
|
812 | output.tree = tree;
|
813 | return output;
|
814 | });
|
815 | });
|
816 | });
|
817 | };
|
818 |
|
819 | Builder.prototype.build = function() {
|
820 | console.warn('builder.build is deprecated. Using builder.bundle instead.');
|
821 | return this.bundle.apply(this, arguments);
|
822 | };
|
823 | Builder.prototype.buildSFX = function() {
|
824 | console.warn('builder.buildSFX is deprecated. Using builder.buildStatic instead.');
|
825 | return this.buildStatic.apply(this, arguments);
|
826 | };
|
827 | Builder.prototype.buildTree = function() {
|
828 | console.warn('builder.buildTree is deprecated. Using builder.bundle instead, which takes both a tree object or expression string.');
|
829 | return this.bundle.apply(this, arguments);
|
830 | };
|
831 |
|
832 |
|
833 | Builder.prototype.getDepCache = function(tree) {
|
834 | var depCache = {};
|
835 | Object.keys(tree).forEach(function(moduleName) {
|
836 | var load = tree[moduleName];
|
837 | if (load && load.deps && load.deps.length)
|
838 | depCache[moduleName] = load.deps.map(function(dep) {
|
839 | return dep;
|
840 | });
|
841 | });
|
842 | return depCache;
|
843 | };
|
844 |
|
845 | Builder.prototype.getDeferredImports = function(tree) {
|
846 | var getDeferredImports = require('./get-deferred-imports');
|
847 | return getDeferredImports(this, tree);
|
848 | }
|
849 |
|
850 |
|
851 | Builder.prototype.intersectTrees = require('./arithmetic').intersectTrees;
|
852 | Builder.prototype.addTrees = require('./arithmetic').addTrees;
|
853 | Builder.prototype.subtractTrees = require('./arithmetic').subtractTrees;
|
854 |
|
855 | module.exports = Builder;
|