diff --git a/lib/package.js b/lib/package.js index 351ca220..09fb6ac9 100644 --- a/lib/package.js +++ b/lib/package.js @@ -180,6 +180,7 @@ var basePath = getBasePath(pkg); // main + // NB can add a default package main convention here if (pkgName === normalized && pkg.main) normalized += '/' + (pkg.main.substr(0, 2) == './' ? pkg.main.substr(2) : pkg.main); @@ -295,62 +296,72 @@ var loader = this; // check if we match a packageConfigPaths + // we allow multiple matches for the same package name to enable separate depCache, map and plain config mechanisms if (!sync) { - var pkgPath, pkgConfigPath; + var pkgPath, pkgConfigPaths = []; for (var i = 0; i < this.packageConfigPaths.length; i++) { var p = this.packageConfigPaths[i]; var pPkgLen = Math.max(p.lastIndexOf('*') + 1, p.lastIndexOf('/')); var match = normalized.match(packageConfigPathsRegExps[p] || (packageConfigPathsRegExps[p] = new RegExp('^(' + p.substr(0, pPkgLen).replace(/\*/g, '[^\\/]+') + ')(\/|$)'))); - if (match) { + if (match && (!pkgPath || pkgPath == match[1])) { pkgPath = match[1]; - pkgConfigPath = pkgPath + p.substr(pPkgLen); - break; + pkgConfigPaths.push(pkgPath + p.substr(pPkgLen)); } } - if (pkgPath && !(pkgName && pkgName == pkgPath && loader.packages[pkgName].configured)) { + if (pkgPath) + var curPkgConfig = loader.packages[pkgPath]; + + if (pkgPath && !(curPkgConfig && curPkgConfig.configured)) { return (pkgConfigPromises[pkgPath] || - (pkgConfigPromises[pkgPath] = - loader['fetch']({ name: pkgConfigPath, address: pkgConfigPath, metadata: {} }) - .then(function(source) { - try { - return JSON.parse(source); - } - catch(e) { - throw new Error('Invalid JSON in package configuration file ' + pkgConfigPath); - } - }) - .then(function(cfg) { - // support "systemjs" prefixing - if (cfg.systemjs) - cfg = cfg.systemjs; + (pkgConfigPromises[pkgPath] = Promise.resolve() + .then(function() { + var pkgConfigPromises = []; + for (var i = 0; i < pkgConfigPaths.length; i++) (function(pkgConfigPath) { + pkgConfigPromises.push(loader['fetch']({ name: pkgConfigPath, address: pkgConfigPath, metadata: {} }) + .then(function(source) { + try { + return JSON.parse(source); + } + catch(e) { + throw new Error('Invalid JSON in package configuration file ' + pkgConfigPath); + } + }) + .then(function(cfg) { + // support "systemjs" prefixing + if (cfg.systemjs) + cfg = cfg.systemjs; - // remove any non-system properties if generic config file (eg package.json) - for (var p in cfg) { - if (indexOf.call(packageProperties, p) == -1) - delete cfg[p]; - } + // remove any non-system properties if generic config file (eg package.json) + for (var p in cfg) { + if (indexOf.call(packageProperties, p) == -1) + delete cfg[p]; + } - // support main array - if (cfg.main instanceof Array) - cfg.main = cfg.main[0]; + // support main array + if (cfg.main instanceof Array) + cfg.main = cfg.main[0]; - // deeply-merge (to first level) config with any existing package config - if (pkgName && pkgName == pkgPath) - extendMeta(cfg, loader.packages[pkgPath]); + // deeply-merge (to first level) config with any existing package config + if (curPkgConfig) + extendMeta(cfg, curPkgConfig); - // support external depCache - if (cfg.depCache) - for (var d in cfg.depCache) { - if (d.substr(0, 2) == './') - continue; + // support external depCache + if (cfg.depCache) + for (var d in cfg.depCache) { + if (d.substr(0, 2) == './') + continue; - var dNormalized = loader.normalizeSync(d); - loader.depCache[dNormalized] = (loader.depCache[dNormalized] || []).concat(cfg.depCache[d]); - } + var dNormalized = loader.normalizeSync(d); + loader.depCache[dNormalized] = (loader.depCache[dNormalized] || []).concat(cfg.depCache[d]); + } - loader.packages[pkgPath] = cfg; + curPkgConfig = loader.packages[pkgPath] = cfg; + })); + })(pkgConfigPaths[i]); + + return Promise.all(pkgConfigPromises); }) ) ) diff --git a/test/test.js b/test/test.js index aea679ca..b0eb44d5 100644 --- a/test/test.js +++ b/test/test.js @@ -900,7 +900,7 @@ asyncTest('Package configuration CommonJS config example', function() { 'global-test': 'tests/testpkg/test.ts' }, //packageConfigPaths: ['tests/testpk*.json'], - packageConfigPaths: ['tests/testpkg/system.json'], + packageConfigPaths: ['tests/testpkg/system.json', 'tests/testpkg/depcache.json'], packages: { 'tests/testpkg': { main: './noext', diff --git a/test/tests/testpkg/depcache.json b/test/tests/testpkg/depcache.json new file mode 100644 index 00000000..5a26677c --- /dev/null +++ b/test/tests/testpkg/depcache.json @@ -0,0 +1,5 @@ +{ + "depCache": { + "./dir2/index.json": ["./depcache-test"] + } +} \ No newline at end of file diff --git a/test/tests/testpkg/system.json b/test/tests/testpkg/system.json index 19b31b83..b337b7e5 100644 --- a/test/tests/testpkg/system.json +++ b/test/tests/testpkg/system.json @@ -18,8 +18,5 @@ "./env-module": { "browser": "./env-module-browser.js" } - }, - "depCache": { - "./dir2/index.json": ["./depcache-test"] } } \ No newline at end of file