This commit is contained in:
guybedford 2015-06-23 00:14:10 +02:00
parent 4b6a3700d4
commit 4ad4490ccb
10 changed files with 291 additions and 111 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/* /*
* SystemJS v0.18.1 * SystemJS v0.18.2
*/ */
(function() { (function() {
function bootstrap() {(function(__global) { function bootstrap() {(function(__global) {
@ -41,8 +41,15 @@ function bootstrap() {(function(__global) {
var newErr; var newErr;
if (err instanceof Error) { if (err instanceof Error) {
var newErr = new Error(err.message, err.fileName, err.lineNumber); var newErr = new Error(err.message, err.fileName, err.lineNumber);
newErr.message = err.message + '\n\t' + msg; if (isBrowser) {
newErr.stack = err.stack; newErr.message = err.message + '\n\t' + msg;
newErr.stack = err.stack;
}
else {
// node errors only look correct with the stack modified
newErr.message = err.message;
newErr.stack = err.stack + '\n\t' + msg;
}
} }
else { else {
newErr = err + '\n\t' + msg; newErr = err + '\n\t' + msg;
@ -86,7 +93,13 @@ function bootstrap() {(function(__global) {
throw new TypeError('No environment baseURI'); throw new TypeError('No environment baseURI');
} }
var URL = typeof __global.URL == 'function' && __global.URL || URLPolyfill; var URL = __global.URL;
try {
new URL('test:///').protocol == 'test:';
}
catch(e) {
URL = URLPolyfill;
}
/* /*
********************************************************************************************* *********************************************************************************************
@ -892,6 +905,10 @@ function logloads(loads) {
} }
function doEnsureEvaluated() {} function doEnsureEvaluated() {}
function transpile() {
throw new TypeError('ES6 transpilation is only provided in the dev module loader build.');
}
})();/* })();/*
********************************************************************************************* *********************************************************************************************
@ -1191,7 +1208,7 @@ SystemJSLoader.prototype.config = function(cfg) {
var v = cfg[c]; var v = cfg[c];
var normalizeProp = false, normalizeValArray = false; var normalizeProp = false, normalizeValArray = false;
if (c == 'baseURL' || c == 'map' || c == 'packages' || c == 'bundles') if (c == 'baseURL' || c == 'map' || c == 'packages' || c == 'bundles' || c == 'paths')
continue; continue;
if (typeof v != 'object' || v instanceof Array) { if (typeof v != 'object' || v instanceof Array) {
@ -2140,7 +2157,12 @@ hookConstructor(function(constructor) {
return require.call(loader, names, callback, errback, module.id); return require.call(loader, names, callback, errback, module.id);
} }
contextualRequire.toUrl = function(name) { contextualRequire.toUrl = function(name) {
return loader.normalizeSync(name, module.id); // normalize without defaultJSExtensions
var defaultJSExtension = loader.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js';
var url = loader.normalizeSync(name, module.id);
if (defaultJSExtension && url.substr(url.length - 3, 3) == '.js')
url = url.substr(0, url.length - 3);
return url;
}; };
depValues.splice(requireIndex, 0, contextualRequire); depValues.splice(requireIndex, 0, contextualRequire);
} }
@ -2338,9 +2360,13 @@ hook('normalize', function(normalize) {
* './vendor/another.js': './another/index.js', * './vendor/another.js': './another/index.js',
* // test.js / test -> lib/test.js * // test.js / test -> lib/test.js
* './test.js': './lib/test.js', * './test.js': './lib/test.js',
* } * },
* } * env: {
* } * 'browser': {
* main: 'browser.js'
* }
* }
* }
* }; * };
* *
* Then: * Then:
@ -2380,6 +2406,43 @@ hook('normalize', function(normalize) {
} }
} }
function getPackageConfig(loader, pkgName) {
var pkgConfig = loader.packages[pkgName];
if (!pkgConfig.env)
return Promise.resolve(pkgConfig);
// check environment conditions
// default environment condition is '@env' in package or '@system-env' globally
return loader['import'](pkgConfig.map['@env'] || '@system-env', pkgName)
.then(function(env) {
// derived config object
var pkg = {};
for (var p in pkgConfig)
if (p !== 'map' & p !== 'env')
pkg[p] = pkgConfig[p];
pkg.map = {};
for (var p in pkgConfig.map)
pkg.map[p] = pkgConfig.map[p];
for (var e in pkgConfig.env) {
if (env[e]) {
var envConfig = pkgConfig.env[e];
if (envConfig.main)
pkg.main = envConfig.main;
for (var m in envConfig.map)
pkg.map[m] = envConfig.map[m];
}
}
// store the derived environment config so we have this cached for next time
loader.packages[pkgName] = pkg;
return pkg;
});
}
function applyMap(map, name) { function applyMap(map, name) {
var bestMatch, bestMatchLength = 0; var bestMatch, bestMatchLength = 0;
@ -2396,6 +2459,8 @@ hook('normalize', function(normalize) {
return map[bestMatch] + name.substr(bestMatch.length); return map[bestMatch] + name.substr(bestMatch.length);
} }
SystemJSLoader.prototype.normalizeSync = SystemJSLoader.prototype.normalize;
hook('normalize', function(normalize) { hook('normalize', function(normalize) {
return function(name, parentName) { return function(name, parentName) {
// apply contextual package map first // apply contextual package map first
@ -2431,46 +2496,51 @@ hook('normalize', function(normalize) {
var pkgName = getPackage.call(this, normalized); var pkgName = getPackage.call(this, normalized);
if (pkgName) { if (pkgName) {
var pkg = this.packages[pkgName]; return getPackageConfig(this, pkgName)
.then(function(pkg) {
// main
if (pkgName === normalized && pkg.main)
normalized += '/' + (pkg.main.substr(0, 2) == './' ? pkg.main.substr(2) : pkg.main);
// main if (normalized.substr(pkgName.length) == '/')
if (pkgName === normalized && pkg.main) return normalized;
normalized += '/' + (pkg.main.substr(0, 2) == './' ? pkg.main.substr(2) : pkg.main);
// defaultExtension & defaultJSExtension // defaultExtension & defaultJSExtension
// if we have meta for this package, don't do defaultExtensions // if we have meta for this package, don't do defaultExtensions
var defaultExtension = ''; var defaultExtension = '';
if (!pkg.meta || !pkg.meta[normalized.substr(pkgName.length + 1)]) { if (!pkg.meta || !pkg.meta[normalized.substr(pkgName.length + 1)]) {
// apply defaultExtension // apply defaultExtension
if (pkg.defaultExtension) { if (pkg.defaultExtension) {
if (normalized.split('/').pop().indexOf('.') == -1) if (normalized.split('/').pop().indexOf('.') == -1)
defaultExtension = '.' + pkg.defaultExtension; defaultExtension = '.' + pkg.defaultExtension;
}
// apply defaultJSExtensions if defaultExtension not set
else if (defaultJSExtension) {
defaultExtension = '.js';
}
} }
// apply defaultJSExtensions if defaultExtension not set
else if (defaultJSExtension) {
defaultExtension = '.js';
}
}
// apply submap checking without then with defaultExtension // apply submap checking without then with defaultExtension
var subPath = '.' + normalized.substr(pkgName.length); var subPath = '.' + normalized.substr(pkgName.length);
var mapped = applyMap(pkg.map, subPath) || defaultExtension && applyMap(pkg.map, subPath + defaultExtension); var mapped = applyMap(pkg.map, subPath) || defaultExtension && applyMap(pkg.map, subPath + defaultExtension);
if (mapped) if (mapped)
normalized = mapped.substr(0, 2) == './' ? pkgName + mapped.substr(1) : mapped; normalized = mapped.substr(0, 2) == './' ? pkgName + mapped.substr(1) : mapped;
else else
normalized += defaultExtension; normalized += defaultExtension;
return normalized;
});
} }
// add back defaultJSExtension if not a package // add back defaultJSExtension if not a package
else if (defaultJSExtension) { if (defaultJSExtension)
normalized += '.js'; normalized += '.js';
}
return normalized; return normalized;
}; };
}); });
SystemJSLoader.prototype.normalizeSync = SystemJSLoader.prototype.normalize;
hook('locate', function(locate) { hook('locate', function(locate) {
return function(load) { return function(load) {
var loader = this; var loader = this;
@ -2558,7 +2628,7 @@ hook('normalize', function(normalize) {
argumentName = loader.normalizeSync(argumentName, parentName); argumentName = loader.normalizeSync(argumentName, parentName);
pluginName = loader.normalizeSync(pluginName, parentName); pluginName = loader.normalizeSync(pluginName, parentName);
if (defaultExtension) if (defaultExtension && argumentName.substr(argumentName.length - 3, 3) == '.js')
argumentName = argumentName.substr(0, argumentName.length - 3); argumentName = argumentName.substr(0, argumentName.length - 3);
return argumentName + '!' + pluginName; return argumentName + '!' + pluginName;
@ -2570,7 +2640,7 @@ hook('normalize', function(normalize) {
]) ])
.then(function(normalized) { .then(function(normalized) {
argumentName = normalized[0]; argumentName = normalized[0];
if (defaultExtension) if (defaultExtension && argumentName.substr(argumentName.length - 3, 3) == '.js')
argumentName = argumentName.substr(0, argumentName.length - 3); argumentName = argumentName.substr(0, argumentName.length - 3);
return argumentName + '!' + normalized[1]; return argumentName + '!' + normalized[1];
}); });
@ -3021,6 +3091,17 @@ hook('normalize', function(normalize) {
var conditionalRegEx = /#\{[^\}]+\}|#\?.+$/; var conditionalRegEx = /#\{[^\}]+\}|#\?.+$/;
hookConstructor(function(constructor) {
return function() {
constructor.call(this);
// standard environment module, starting small as backwards-compat matters!
this.set('@system-env', this.newModule({
browser: isBrowser
}));
};
});
hook('normalize', function(normalize) { hook('normalize', function(normalize) {
return function(name, parentName, parentAddress) { return function(name, parentName, parentAddress) {
var loader = this; var loader = this;
@ -3096,7 +3177,7 @@ System.constructor = SystemJSLoader; // -- exporting --
// auto-load Promise and URL polyfills if needed in the browser // auto-load Promise and URL polyfills if needed in the browser
try { try {
var hasURL = typeof URLPolyfill != 'undefined' || typeof URL != 'undefined' && new URL('test:///').protocol == 'test:'; var hasURL = typeof URLPolyfill != 'undefined' || new URL('test:///').protocol == 'test:';
} }
catch(e) {} catch(e) {}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
/* /*
* SystemJS v0.18.1 * SystemJS v0.18.2
*/ */
(function(__global) { (function(__global) {
@ -40,8 +40,15 @@
var newErr; var newErr;
if (err instanceof Error) { if (err instanceof Error) {
var newErr = new Error(err.message, err.fileName, err.lineNumber); var newErr = new Error(err.message, err.fileName, err.lineNumber);
newErr.message = err.message + '\n\t' + msg; if (isBrowser) {
newErr.stack = err.stack; newErr.message = err.message + '\n\t' + msg;
newErr.stack = err.stack;
}
else {
// node errors only look correct with the stack modified
newErr.message = err.message;
newErr.stack = err.stack + '\n\t' + msg;
}
} }
else { else {
newErr = err + '\n\t' + msg; newErr = err + '\n\t' + msg;
@ -85,7 +92,13 @@
throw new TypeError('No environment baseURI'); throw new TypeError('No environment baseURI');
} }
var URL = typeof __global.URL == 'function' && __global.URL || URLPolyfill; var URL = __global.URL;
try {
new URL('test:///').protocol == 'test:';
}
catch(e) {
URL = URLPolyfill;
}
/* /*
********************************************************************************************* *********************************************************************************************
@ -891,6 +904,10 @@ function logloads(loads) {
} }
function doEnsureEvaluated() {} function doEnsureEvaluated() {}
function transpile() {
throw new TypeError('ES6 transpilation is only provided in the dev module loader build.');
}
})();/* })();/*
********************************************************************************************* *********************************************************************************************

6
dist/system.js vendored

File diff suppressed because one or more lines are too long

2
dist/system.js.map vendored

File diff suppressed because one or more lines are too long

192
dist/system.src.js vendored
View File

@ -1,5 +1,5 @@
/* /*
* SystemJS v0.18.1 * SystemJS v0.18.2
*/ */
(function() { (function() {
function bootstrap() {(function(__global) { function bootstrap() {(function(__global) {
@ -41,8 +41,15 @@ function bootstrap() {(function(__global) {
var newErr; var newErr;
if (err instanceof Error) { if (err instanceof Error) {
var newErr = new Error(err.message, err.fileName, err.lineNumber); var newErr = new Error(err.message, err.fileName, err.lineNumber);
newErr.message = err.message + '\n\t' + msg; if (isBrowser) {
newErr.stack = err.stack; newErr.message = err.message + '\n\t' + msg;
newErr.stack = err.stack;
}
else {
// node errors only look correct with the stack modified
newErr.message = err.message;
newErr.stack = err.stack + '\n\t' + msg;
}
} }
else { else {
newErr = err + '\n\t' + msg; newErr = err + '\n\t' + msg;
@ -86,7 +93,13 @@ function bootstrap() {(function(__global) {
throw new TypeError('No environment baseURI'); throw new TypeError('No environment baseURI');
} }
var URL = typeof __global.URL == 'function' && __global.URL || URLPolyfill; var URL = __global.URL;
try {
new URL('test:///').protocol == 'test:';
}
catch(e) {
URL = URLPolyfill;
}
/* /*
********************************************************************************************* *********************************************************************************************
@ -892,6 +905,10 @@ function logloads(loads) {
} }
function doEnsureEvaluated() {} function doEnsureEvaluated() {}
function transpile() {
throw new TypeError('ES6 transpilation is only provided in the dev module loader build.');
}
})();/* })();/*
********************************************************************************************* *********************************************************************************************
@ -1150,8 +1167,23 @@ var __exec;
'\n//# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(load.metadata.sourceMap))) || '') '\n//# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(load.metadata.sourceMap))) || '')
} }
// Web Worker and Chrome Extensions use original ESML eval
// this may lead to some global module execution differences (eg var not defining onto global)
if (isWorker || isBrowser && window.chrome && window.chrome.extension) {
__exec = function(load) {
try {
preExec(this);
new Function(getSource(load)).call(__global);
postExec();
}
catch(e) {
throw addToError(e, 'Evaluating ' + load.address);
}
};
}
// use script injection eval to get identical global script behaviour // use script injection eval to get identical global script behaviour
if (typeof document != 'undefined') { else if (typeof document != 'undefined') {
var head; var head;
var scripts = document.getElementsByTagName('script'); var scripts = document.getElementsByTagName('script');
@ -1177,20 +1209,6 @@ var __exec;
throw e; throw e;
} }
} }
// Web Worker uses original ESML eval
// this may lead to some global module execution differences (eg var not defining onto global)
else if (isWorker) {
__exec = function(load) {
try {
preExec(this);
new Function(getSource(load)).call(__global);
postExec();
}
catch(e) {
throw addToError(e, 'Evaluating ' + load.address);
}
};
}
else { else {
// global scoped eval for node // global scoped eval for node
var vmModule = 'vm'; var vmModule = 'vm';
@ -1445,7 +1463,7 @@ SystemJSLoader.prototype.config = function(cfg) {
var v = cfg[c]; var v = cfg[c];
var normalizeProp = false, normalizeValArray = false; var normalizeProp = false, normalizeValArray = false;
if (c == 'baseURL' || c == 'map' || c == 'packages' || c == 'bundles') if (c == 'baseURL' || c == 'map' || c == 'packages' || c == 'bundles' || c == 'paths')
continue; continue;
if (typeof v != 'object' || v instanceof Array) { if (typeof v != 'object' || v instanceof Array) {
@ -2643,7 +2661,12 @@ hookConstructor(function(constructor) {
return require.call(loader, names, callback, errback, module.id); return require.call(loader, names, callback, errback, module.id);
} }
contextualRequire.toUrl = function(name) { contextualRequire.toUrl = function(name) {
return loader.normalizeSync(name, module.id); // normalize without defaultJSExtensions
var defaultJSExtension = loader.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js';
var url = loader.normalizeSync(name, module.id);
if (defaultJSExtension && url.substr(url.length - 3, 3) == '.js')
url = url.substr(0, url.length - 3);
return url;
}; };
depValues.splice(requireIndex, 0, contextualRequire); depValues.splice(requireIndex, 0, contextualRequire);
} }
@ -2918,9 +2941,13 @@ hook('normalize', function(normalize) {
* './vendor/another.js': './another/index.js', * './vendor/another.js': './another/index.js',
* // test.js / test -> lib/test.js * // test.js / test -> lib/test.js
* './test.js': './lib/test.js', * './test.js': './lib/test.js',
* } * },
* } * env: {
* } * 'browser': {
* main: 'browser.js'
* }
* }
* }
* }; * };
* *
* Then: * Then:
@ -2960,6 +2987,43 @@ hook('normalize', function(normalize) {
} }
} }
function getPackageConfig(loader, pkgName) {
var pkgConfig = loader.packages[pkgName];
if (!pkgConfig.env)
return Promise.resolve(pkgConfig);
// check environment conditions
// default environment condition is '@env' in package or '@system-env' globally
return loader['import'](pkgConfig.map['@env'] || '@system-env', pkgName)
.then(function(env) {
// derived config object
var pkg = {};
for (var p in pkgConfig)
if (p !== 'map' & p !== 'env')
pkg[p] = pkgConfig[p];
pkg.map = {};
for (var p in pkgConfig.map)
pkg.map[p] = pkgConfig.map[p];
for (var e in pkgConfig.env) {
if (env[e]) {
var envConfig = pkgConfig.env[e];
if (envConfig.main)
pkg.main = envConfig.main;
for (var m in envConfig.map)
pkg.map[m] = envConfig.map[m];
}
}
// store the derived environment config so we have this cached for next time
loader.packages[pkgName] = pkg;
return pkg;
});
}
function applyMap(map, name) { function applyMap(map, name) {
var bestMatch, bestMatchLength = 0; var bestMatch, bestMatchLength = 0;
@ -2976,6 +3040,8 @@ hook('normalize', function(normalize) {
return map[bestMatch] + name.substr(bestMatch.length); return map[bestMatch] + name.substr(bestMatch.length);
} }
SystemJSLoader.prototype.normalizeSync = SystemJSLoader.prototype.normalize;
hook('normalize', function(normalize) { hook('normalize', function(normalize) {
return function(name, parentName) { return function(name, parentName) {
// apply contextual package map first // apply contextual package map first
@ -3011,46 +3077,51 @@ hook('normalize', function(normalize) {
var pkgName = getPackage.call(this, normalized); var pkgName = getPackage.call(this, normalized);
if (pkgName) { if (pkgName) {
var pkg = this.packages[pkgName]; return getPackageConfig(this, pkgName)
.then(function(pkg) {
// main
if (pkgName === normalized && pkg.main)
normalized += '/' + (pkg.main.substr(0, 2) == './' ? pkg.main.substr(2) : pkg.main);
// main if (normalized.substr(pkgName.length) == '/')
if (pkgName === normalized && pkg.main) return normalized;
normalized += '/' + (pkg.main.substr(0, 2) == './' ? pkg.main.substr(2) : pkg.main);
// defaultExtension & defaultJSExtension // defaultExtension & defaultJSExtension
// if we have meta for this package, don't do defaultExtensions // if we have meta for this package, don't do defaultExtensions
var defaultExtension = ''; var defaultExtension = '';
if (!pkg.meta || !pkg.meta[normalized.substr(pkgName.length + 1)]) { if (!pkg.meta || !pkg.meta[normalized.substr(pkgName.length + 1)]) {
// apply defaultExtension // apply defaultExtension
if (pkg.defaultExtension) { if (pkg.defaultExtension) {
if (normalized.split('/').pop().indexOf('.') == -1) if (normalized.split('/').pop().indexOf('.') == -1)
defaultExtension = '.' + pkg.defaultExtension; defaultExtension = '.' + pkg.defaultExtension;
}
// apply defaultJSExtensions if defaultExtension not set
else if (defaultJSExtension) {
defaultExtension = '.js';
}
} }
// apply defaultJSExtensions if defaultExtension not set
else if (defaultJSExtension) {
defaultExtension = '.js';
}
}
// apply submap checking without then with defaultExtension // apply submap checking without then with defaultExtension
var subPath = '.' + normalized.substr(pkgName.length); var subPath = '.' + normalized.substr(pkgName.length);
var mapped = applyMap(pkg.map, subPath) || defaultExtension && applyMap(pkg.map, subPath + defaultExtension); var mapped = applyMap(pkg.map, subPath) || defaultExtension && applyMap(pkg.map, subPath + defaultExtension);
if (mapped) if (mapped)
normalized = mapped.substr(0, 2) == './' ? pkgName + mapped.substr(1) : mapped; normalized = mapped.substr(0, 2) == './' ? pkgName + mapped.substr(1) : mapped;
else else
normalized += defaultExtension; normalized += defaultExtension;
return normalized;
});
} }
// add back defaultJSExtension if not a package // add back defaultJSExtension if not a package
else if (defaultJSExtension) { if (defaultJSExtension)
normalized += '.js'; normalized += '.js';
}
return normalized; return normalized;
}; };
}); });
SystemJSLoader.prototype.normalizeSync = SystemJSLoader.prototype.normalize;
hook('locate', function(locate) { hook('locate', function(locate) {
return function(load) { return function(load) {
var loader = this; var loader = this;
@ -3138,7 +3209,7 @@ hook('normalize', function(normalize) {
argumentName = loader.normalizeSync(argumentName, parentName); argumentName = loader.normalizeSync(argumentName, parentName);
pluginName = loader.normalizeSync(pluginName, parentName); pluginName = loader.normalizeSync(pluginName, parentName);
if (defaultExtension) if (defaultExtension && argumentName.substr(argumentName.length - 3, 3) == '.js')
argumentName = argumentName.substr(0, argumentName.length - 3); argumentName = argumentName.substr(0, argumentName.length - 3);
return argumentName + '!' + pluginName; return argumentName + '!' + pluginName;
@ -3150,7 +3221,7 @@ hook('normalize', function(normalize) {
]) ])
.then(function(normalized) { .then(function(normalized) {
argumentName = normalized[0]; argumentName = normalized[0];
if (defaultExtension) if (defaultExtension && argumentName.substr(argumentName.length - 3, 3) == '.js')
argumentName = argumentName.substr(0, argumentName.length - 3); argumentName = argumentName.substr(0, argumentName.length - 3);
return argumentName + '!' + normalized[1]; return argumentName + '!' + normalized[1];
}); });
@ -3601,6 +3672,17 @@ hook('normalize', function(normalize) {
var conditionalRegEx = /#\{[^\}]+\}|#\?.+$/; var conditionalRegEx = /#\{[^\}]+\}|#\?.+$/;
hookConstructor(function(constructor) {
return function() {
constructor.call(this);
// standard environment module, starting small as backwards-compat matters!
this.set('@system-env', this.newModule({
browser: isBrowser
}));
};
});
hook('normalize', function(normalize) { hook('normalize', function(normalize) {
return function(name, parentName, parentAddress) { return function(name, parentName, parentAddress) {
var loader = this; var loader = this;
@ -3676,7 +3758,7 @@ System.constructor = SystemJSLoader; // -- exporting --
// auto-load Promise and URL polyfills if needed in the browser // auto-load Promise and URL polyfills if needed in the browser
try { try {
var hasURL = typeof URLPolyfill != 'undefined' || typeof URL != 'undefined' && new URL('test:///').protocol == 'test:'; var hasURL = typeof URLPolyfill != 'undefined' || new URL('test:///').protocol == 'test:';
} }
catch(e) {} catch(e) {}

View File

@ -1,6 +1,6 @@
{ {
"name": "systemjs", "name": "systemjs",
"version": "0.18.1", "version": "0.18.2",
"description": "System loader extension for flexible AMD & CommonJS support", "description": "System loader extension for flexible AMD & CommonJS support",
"repository": { "repository": {
"type": "git", "type": "git",
@ -9,7 +9,7 @@
"author": "Guy Bedford", "author": "Guy Bedford",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"es6-module-loader": "^0.17.1", "es6-module-loader": "^0.17.2",
"when": "^3.7.2" "when": "^3.7.2"
}, },
"devDependencies": { "devDependencies": {