diff --git a/packages/react-scripts/bin/react-scripts.js b/packages/react-scripts/bin/react-scripts.js index 8a1175c99ea..0c5b8ffa6d0 100755 --- a/packages/react-scripts/bin/react-scripts.js +++ b/packages/react-scripts/bin/react-scripts.js @@ -12,18 +12,17 @@ var spawn = require('cross-spawn'); var script = process.argv[2]; -var args = process.argv.slice(3); +var getArgs = require('../scripts/utils/getSubscriptArgs'); switch (script) { case 'build': case 'eject': case 'start': case 'test': - var result = spawn.sync( - 'node', - [require.resolve('../scripts/' + script)].concat(args), - { stdio: 'inherit' } - ); + var scriptFilename = require.resolve('../scripts/' + script); + var result = spawn.sync('node', getArgs(scriptFilename), { + stdio: 'inherit', + }); if (result.signal) { if (result.signal === 'SIGKILL') { console.log( diff --git a/packages/react-scripts/config/jest/babelTransform.js b/packages/react-scripts/config/jest/babelTransform.js index bee55b1b156..10aa80451ab 100644 --- a/packages/react-scripts/config/jest/babelTransform.js +++ b/packages/react-scripts/config/jest/babelTransform.js @@ -13,4 +13,5 @@ const babelJest = require('babel-jest'); module.exports = babelJest.createTransformer({ presets: [require.resolve('babel-preset-react-app')], babelrc: false, + sourceMaps: process.env.REACT_APP_DEBUG_JEST ? 'inline' : false, }); diff --git a/packages/react-scripts/scripts/test.js b/packages/react-scripts/scripts/test.js index 5c395999d97..868af8753d4 100644 --- a/packages/react-scripts/scripts/test.js +++ b/packages/react-scripts/scripts/test.js @@ -8,8 +8,16 @@ * of patent rights can be found in the PATENTS file in the same directory. */ // @remove-on-eject-end + +/** + * Greetings! If you are here attempting to start a debugging session, please + * ensure that your debugger of choice is configured to enable source maps, + * otherwise your code may appear mangled by babel! + */ 'use strict'; +var debugArgs = require('./utils/debugArgs'); + process.env.NODE_ENV = 'test'; process.env.PUBLIC_URL = ''; @@ -27,13 +35,23 @@ process.on('unhandledRejection', err => { require('dotenv').config({ silent: true }); const jest = require('jest'); -const argv = process.argv.slice(2); +let argv = process.argv.slice(2); +const isDebug = !!process.env.REACT_APP_DEBUG_JEST; +const isRunInBand = argv.indexOf('--runInBand') > -1 || argv.indexOf('-i') > -1; // Watch unless on CI or in coverage mode if (!process.env.CI && argv.indexOf('--coverage') < 0) { argv.push('--watch'); } +// Force debug into single worker +if (isDebug) { + if (!isRunInBand) { + argv.push('--runInBand'); + } + argv = debugArgs.removeFrom(argv); +} + // @remove-on-eject-begin // This is not necessary after eject because we embed config into package.json. const createJestConfig = require('./utils/createJestConfig'); diff --git a/packages/react-scripts/scripts/utils/debugArgs.js b/packages/react-scripts/scripts/utils/debugArgs.js new file mode 100644 index 00000000000..2e05b317e6f --- /dev/null +++ b/packages/react-scripts/scripts/utils/debugArgs.js @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +'use strict'; + +const DEBUG_FLAGS = [ + /^debug$/, + /^--debug$/, + /^--debug-brk(=\d+)?$/, + /^--inspect$/, + /^--inspect-brk(=\d+)?$/, +]; + +module.exports = { + _match: function _matchDebugFlags(args, onMatch) { + for (var i in args) { + if (args.hasOwnProperty(i)) { + for (var j in DEBUG_FLAGS) { + if (DEBUG_FLAGS.hasOwnProperty(j)) { + if (args[i].match(DEBUG_FLAGS[j])) { + onMatch(args[i]); + } + } + } + } + } + }, + getFrom: function getDebugFlags(args) { + var matches = []; + this._match(args, function addMatch(arg) { + matches.push(arg); + }); + return matches.length ? matches : null; + }, + removeFrom: function removeDebugFlags(args) { + var matches = this.getFrom(args) || []; + return args.filter(function isNotDebugArg(arg) { + return !matches.some(function isPresent(debugArg) { + return arg === debugArg; + }); + }); + }, +}; diff --git a/packages/react-scripts/scripts/utils/getSubscriptArgs.js b/packages/react-scripts/scripts/utils/getSubscriptArgs.js new file mode 100644 index 00000000000..602e5f6f8b8 --- /dev/null +++ b/packages/react-scripts/scripts/utils/getSubscriptArgs.js @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +'use strict'; + +var debugArgs = require('../utils/debugArgs'); + +module.exports = function getSubscriptArgs(scriptFilename) { + var args = process.argv.slice(3); + var passedDebugArgs; + var nonDebugArgs; + args.unshift(scriptFilename); + passedDebugArgs = debugArgs.getFrom(args); + if (passedDebugArgs) { + process.env.REACT_APP_DEBUG_JEST = 'true'; // :eyes: side-effect + nonDebugArgs = debugArgs.removeFrom(args); + args = passedDebugArgs.concat(nonDebugArgs); + } + return args; +};