diff --git a/lib/trace.js b/lib/trace.js index 0111fee..133b540 100644 --- a/lib/trace.js +++ b/lib/trace.js @@ -730,95 +730,104 @@ Trace.prototype.inlineConditions = function(tree, loader, traceOpts) { var conditionalResolutions = {}; var importsSystemEnv = false; - // for each conditional in the tree, work out its substitution - Object.keys(tree) - .filter(function(m) { - return tree[m] && tree[m].conditional; - }) - .forEach(function(c) { - var branches = Trace.getConditionalResolutions(tree[c].conditional, canonicalConditionalEnv, canonicalInlineConditionals).branches; + // get the list of all conditional dependencies in the tree + var allConditionals = []; + Object.keys(tree).forEach(function(m) { + if (!tree[m] || tree[m].conditional) + return; - if (branches.length > 1) - throw new TypeError('Error building condition ' + c + '. ' + inconsistencyErrorMsg); - if (branches.length == 0) - throw new TypeError('No exact resolution found at all for condition ' + c + '.'); + Object.keys(tree[m].depMap).forEach(function(d) { + var dep = tree[m].depMap[d]; - conditionalResolutions[c] = branches[0]; + if (dep.match(/#[\:\?\{]/)) { + if (allConditionals.indexOf(dep) === -1) + allConditionals.push(dep); + } + }); }); - // resolve any chained conditionals - Object.keys(conditionalResolutions).forEach(function(c) { - var resolution = conditionalResolutions[c]; + // determine the conditional resolutions + return Promise.all(allConditionals.map(function(c) { + return self.getLoadRecord(c, traceOpts) + .then(function(load) { + var branches = Trace.getConditionalResolutions(load.conditional, canonicalConditionalEnv, canonicalInlineConditionals).branches; - var seen = []; - while (conditionalResolutions[resolution] && seen.indexOf(resolution) == -1) { - seen.push(resolution); - resolution = conditionalResolutions[resolution]; - conditionalResolutions[c] = resolution; - } - if (seen.indexOf(resolution) != -1) - throw new Error('Circular conditional resolution ' + seen.join(' -> ') + ' -> ' + resolution); - }); + if (branches.length === 1) + conditionalResolutions[c] = branches[0]; + }); + })) + .then(function() { + // resolve any chained conditionals + Object.keys(conditionalResolutions).forEach(function(c) { + var resolution = conditionalResolutions[c]; + + var seen = []; + while (conditionalResolutions[resolution] && seen.indexOf(resolution) == -1) { + seen.push(resolution); + resolution = conditionalResolutions[resolution]; + conditionalResolutions[c] = resolution; + } + if (seen.indexOf(resolution) != -1) + throw new Error('Circular conditional resolution ' + seen.join(' -> ') + ' -> ' + resolution); + }); - // finally we do a deep clone of the tree, applying the conditional resolutions as we go - // if we have a dependency on a condition not in the tree, we throw as it would be an unresolved external - var inlinedTree = {}; - Object.keys(tree).forEach(function(m) { - var load = tree[m]; + // finally we do a deep clone of the tree, applying the conditional resolutions as we go + // if we have a dependency on a condition not in the tree, we throw as it would be an unresolved external + var inlinedTree = {}; + Object.keys(tree).forEach(function(m) { + var load = tree[m]; - if (typeof load == 'boolean') { - inlinedTree[m] = load; - return; - } + if (typeof load == 'boolean') { + inlinedTree[m] = load; + return; + } - if (load.conditional) - return; + if (load.conditional) + return; - var clonedLoad = extend({}, load); - clonedLoad.depMap = {}; - Object.keys(load.depMap).forEach(function(d) { - var normalizedDep = load.depMap[d]; + var clonedLoad = extend({}, load); + clonedLoad.depMap = {}; + Object.keys(load.depMap).forEach(function(d) { + var normalizedDep = load.depMap[d]; - normalizedDep = conditionalResolutions[normalizedDep] || normalizedDep; + normalizedDep = conditionalResolutions[normalizedDep] || normalizedDep; - if (normalizedDep == '@system-env') - importsSystemEnv = true; + if (normalizedDep == '@system-env') + importsSystemEnv = true; - if (normalizedDep.indexOf(/#[\:\?\{]/) != -1) - throw new Error('Unable to inline conditional dependency ' + normalizedDep + '. Try including the ' + d + ' dependency of ' + load.name + ' in the build.'); + clonedLoad.depMap[d] = normalizedDep; + }); - clonedLoad.depMap[d] = normalizedDep; + inlinedTree[m] = clonedLoad; }); - inlinedTree[m] = clonedLoad; - }); - - // if we explicitly import from the system environment, then we need to build it into a static build - // this is normally excluded as it is a system module in SystemJS but won't be available in static - // builds which is exactly what this function acts on - if (importsSystemEnv) { - inlinedTree['@system-env'] = { - name: '@system-env', - path: null, - metadata: { - format: 'json' - }, - deps: [], - depMap: {}, - source: JSON.stringify({ - production: canonicalInlineConditionals['@system-env|production'], - browser: canonicalInlineConditionals['@system-env|browser'], - node: canonicalInlineConditionals['@system-env|node'], - dev: canonicalInlineConditionals['@system-env|dev'], - default: true - }), - fresh: true, - timestamp: null, - configHash: loader.configHash, - }; - } + // if we explicitly import from the system environment, then we need to build it into a static build + // this is normally excluded as it is a system module in SystemJS but won't be available in static + // builds which is exactly what this function acts on + if (importsSystemEnv) { + inlinedTree['@system-env'] = { + name: '@system-env', + path: null, + metadata: { + format: 'json' + }, + deps: [], + depMap: {}, + source: JSON.stringify({ + production: canonicalInlineConditionals['@system-env|production'], + browser: canonicalInlineConditionals['@system-env|browser'], + node: canonicalInlineConditionals['@system-env|node'], + dev: canonicalInlineConditionals['@system-env|dev'], + default: true + }), + fresh: true, + timestamp: null, + configHash: loader.configHash, + }; + } - return inlinedTree; + return inlinedTree; + }); }); }); };