Skip to content

Commit 14d53fb

Browse files
committed
🎨 add first class debugging support
1 parent 4d7b754 commit 14d53fb

10 files changed

+105
-29
lines changed

packages/react-scripts/bin/react-scripts.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env node
22
var spawn = require('cross-spawn');
3+
var getDebugFlag = require('../utils/getDebugFlag');
34
var script = process.argv[2];
45
var args = process.argv.slice(3);
56

@@ -8,9 +9,14 @@ case 'build':
89
case 'eject':
910
case 'start':
1011
case 'test':
12+
var scriptArgs = [require.resolve('../scripts/' + script)].concat(args);
13+
var debugFlag = getDebugFlag(args);
14+
if (debugFlag) {
15+
scriptArgs.unshift(debugFlag);
16+
}
1117
var result = spawn.sync(
1218
'node',
13-
[require.resolve('../scripts/' + script)].concat(args),
19+
scriptArgs,
1420
{stdio: 'inherit'}
1521
);
1622
process.exit(result.status);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const babelJestDefaultConfig = require('./babelJestDefaultConfig');
2+
const assign = require('object-assign');
3+
module.exports = assign(babelJestDefaultConfig, { sourceMaps: true });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
presets: [require.resolve('babel-preset-react-app')],
3+
babelrc: false
4+
}

packages/react-scripts/config/jest/babelTransform.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,5 @@
77
*/
88

99
const babelJest = require('babel-jest');
10-
11-
module.exports = babelJest.createTransformer({
12-
presets: [require.resolve('babel-preset-react-app')],
13-
babelrc: false
14-
});
10+
const babelJestDebugConfig = require('./babelJestDebugConfig');
11+
module.exports = babelJest.createTransformer(babelJestDebugConfig);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
3+
*
4+
* This source code is licensed under the BSD-style license found in the
5+
* LICENSE file in the root directory of this source tree. An additional grant
6+
* of patent rights can be found in the PATENTS file in the same directory.
7+
*/
8+
9+
const babelJest = require('babel-jest');
10+
const babelJestDebugConfig = require('./babelJestDebugConfig');
11+
module.exports = babelJest.createTransformer(babelJestDebugConfig);

packages/react-scripts/scripts/eject.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ prompt(
5959
path.join('config', 'jest', 'fileTransform.js'),
6060
path.join('scripts', 'build.js'),
6161
path.join('scripts', 'start.js'),
62-
path.join('scripts', 'test.js')
62+
path.join('scripts', 'test.js'),
63+
path.join('utils', 'getDebugFlag.js')
6364
];
6465

6566
// Ensure that the app folder is clean and we won't override any files
@@ -122,11 +123,10 @@ prompt(
122123
console.log(cyan('Configuring package.json'));
123124
// Add Jest config
124125
console.log(' Adding ' + cyan('Jest') + ' configuration');
125-
appPackage.jest = createJestConfig(
126-
filePath => path.join('<rootDir>', filePath),
127-
null,
128-
true
129-
);
126+
appPackage.jest = createJestConfig({
127+
resolve: filePath => path.join('<rootDir>', filePath),
128+
isEjecting: true
129+
});
130130

131131
// Add Babel config
132132

packages/react-scripts/scripts/test.js

+22-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
*/
1010
// @remove-on-eject-end
1111

12+
/**
13+
* Greetings! If you are here attempting to start a debugging session, please
14+
* ensure that your debugger of choice is configured to enable source maps,
15+
* otherwise your code may appear mangled by babel!
16+
*/
1217
process.env.NODE_ENV = 'test';
1318
process.env.PUBLIC_URL = '';
1419

@@ -20,21 +25,32 @@ require('dotenv').config({silent: true});
2025

2126
const jest = require('jest');
2227
const argv = process.argv.slice(2);
28+
const debugFlag = require('../utils/getDebugFlag')(argv);
29+
const isDebug = !!debugFlag;
30+
const isRunInBand = argv.indexOf('--runInBand') > -1 || argv.indexOf('-i') > -1
2331

2432
// Watch unless on CI or in coverage mode
25-
if (!process.env.CI && argv.indexOf('--coverage') < 0) {
33+
if (!process.env.CI && argv.indexOf('--coverage') < 0 && !isDebug) {
2634
argv.push('--watch');
2735
}
2836

37+
// Force debug into single worker
38+
if (isDebug) {
39+
if (!isRunInBand) {
40+
argv.push('--runInBand')
41+
}
42+
argv.splice(argv.indexOf(debugFlag), 1)
43+
}
44+
2945
// @remove-on-eject-begin
3046
// This is not necessary after eject because we embed config into package.json.
3147
const createJestConfig = require('../utils/createJestConfig');
3248
const path = require('path');
3349
const paths = require('../config/paths');
34-
argv.push('--config', JSON.stringify(createJestConfig(
35-
relativePath => path.resolve(__dirname, '..', relativePath),
36-
path.resolve(paths.appSrc, '..'),
37-
false
38-
)));
50+
argv.push('--config', JSON.stringify(createJestConfig({
51+
resolve: relativePath => path.resolve(__dirname, '..', relativePath),
52+
rootDir: path.resolve(paths.appSrc, '..'),
53+
isDebug: isDebug
54+
})));
3955
// @remove-on-eject-end
4056
jest.run(argv);

packages/react-scripts/template/README.md

+15-6
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ You can find the most recent version of this guide [here](https://github.com/fac
4848
- [Disabling jsdom](#disabling-jsdom)
4949
- [Experimental Snapshot Testing](#experimental-snapshot-testing)
5050
- [Editor Integration](#editor-integration)
51+
- [Debugging](#debugging)
5152
- [Developing Components in Isolation](#developing-components-in-isolation)
5253
- [Making a Progressive Web App](#making-a-progressive-web-app)
5354
- [Deployment](#deployment)
@@ -480,7 +481,7 @@ Now you are ready to use the imported React Bootstrap components within your com
480481

481482
Flow is a static type checker that helps you write code with fewer bugs. Check out this [introduction to using static types in JavaScript](https://medium.com/@preethikasireddy/why-use-static-types-in-javascript-part-1-8382da1e0adb) if you are new to this concept.
482483

483-
Recent versions of [Flow](http://flowtype.org/) work with Create React App projects out of the box.
484+
Recent versions of [Flow](http://flowtype.org/) work with Create React App projects out of the box.
484485

485486
To add Flow to a Create React App project, follow these steps:
486487

@@ -938,10 +939,18 @@ This feature is experimental and still [has major usage issues](https://github.c
938939

939940
### Editor Integration
940941

941-
If you use [Visual Studio Code](https://code.visualstudio.com), there is a [Jest extension](https://github.com/orta/vscode-jest) which works with Create React App out of the box. This provides a lot of IDE-like features while using a text editor: showing the status of a test run with potential fail messages inline, starting and stopping the watcher automatically, and offering one-click snapshot updates.
942+
If you use [Visual Studio Code](https://code.visualstudio.com), there is a [Jest extension](https://github.com/orta/vscode-jest) which works with Create React App out of the box. This provides a lot of IDE-like features while using a text editor: showing the status of a test run with potential fail messages inline, starting and stopping the watcher automatically, and offering one-click snapshot updates.
942943

943944
![VS Code Jest Preview](https://cloud.githubusercontent.com/assets/49038/20795349/a032308a-b7c8-11e6-9b34-7eeac781003f.png)
944945

946+
### Debugging
947+
948+
You can easily debug your tests by passing the usual debug flags to `npm test`.
949+
950+
For example:
951+
- Run `npm test -- --debug-brk` to attach the the debugger using your debugger of choice (vscode, webstorm, etc).
952+
- Run `npm test -- debug` to enter the CLI debugger.
953+
945954
## Developing Components in Isolation
946955

947956
Usually, in an app, you have a lot of UI components, and each of them has many different states.
@@ -1173,16 +1182,16 @@ GitHub Pages doesn't support routers that use the HTML5 `pushState` history API
11731182
### Heroku
11741183
11751184
Use the [Heroku Buildpack for Create React App](https://github.com/mars/create-react-app-buildpack).<br>
1176-
You can find instructions in [Deploying React with Zero Configuration](https://blog.heroku.com/deploying-react-with-zero-configuration).
1185+
You can find instructions in [Deploying React with Zero Configuration](https://blog.heroku.com/deploying-react-with-zero-configuration).
11771186
11781187
#### Resolving "Module not found: Error: Cannot resolve 'file' or 'directory'"
11791188
11801189
Sometimes `npm run build` works locally but fails during deploy via Heroku with an error like this:
11811190
1182-
```
1191+
```
11831192
remote: Failed to create a production build. Reason:
1184-
remote: Module not found: Error: Cannot resolve 'file' or 'directory'
1185-
MyDirectory in /tmp/build_1234/src
1193+
remote: Module not found: Error: Cannot resolve 'file' or 'directory'
1194+
MyDirectory in /tmp/build_1234/src
11861195
```
11871196
11881197
This means you need to ensure that the lettercase of the file or directory you `import` matches the one you see on your filesystem or on GitHub.

packages/react-scripts/utils/createJestConfig.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,18 @@
1212
const fs = require('fs');
1313
const paths = require('../config/paths');
1414

15-
module.exports = (resolve, rootDir, isEjecting) => {
15+
module.exports = (opts) => {
16+
const resolve = opts.resolve;
17+
const rootDir = opts.rootDir || null;
18+
const isEjecting = opts.isEjecting || false;
19+
const isDebug = opts.isDebug || false;
20+
1621
// Use this instead of `paths.testsSetup` to avoid putting
1722
// an absolute filename into configuration after ejecting.
1823
const setupTestsFile = fs.existsSync(paths.testsSetup) ? '<rootDir>/src/setupTests.js' : undefined;
19-
24+
const babelTransform = isEjecting
25+
? '<rootDir>/node_modules/babel-jest'
26+
: resolve('config/jest/babelTransform' + (isDebug ? 'Debug' : '') + '.js')
2027
// TODO: I don't know if it's safe or not to just use / as path separator
2128
// in Jest configs. We need help from somebody with Windows to determine this.
2229
const config = {
@@ -29,9 +36,7 @@ module.exports = (resolve, rootDir, isEjecting) => {
2936
testEnvironment: 'node',
3037
testURL: 'http://localhost',
3138
transform: {
32-
'^.+\\.(js|jsx)$': isEjecting ?
33-
'<rootDir>/node_modules/babel-jest'
34-
: resolve('config/jest/babelTransform.js'),
39+
'^.+\\.(js|jsx)$': babelTransform,
3540
'^.+\\.css$': resolve('config/jest/cssTransform.js'),
3641
'^(?!.*\\.(js|jsx|css|json)$)': resolve('config/jest/fileTransform.js'),
3742
},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
const DEBUG_FLAGS = [ 'debug', '--debug-brk', '--inspect' ];
11+
12+
module.exports = function getDebugFlag(argv) {
13+
for (var i in argv) {
14+
if (argv.hasOwnProperty(i)) {
15+
for (var j in DEBUG_FLAGS) {
16+
if (DEBUG_FLAGS.hasOwnProperty(j)) {
17+
if (argv[i] === DEBUG_FLAGS[j]) {
18+
return DEBUG_FLAGS[j];
19+
}
20+
}
21+
}
22+
}
23+
}
24+
return null;
25+
}

0 commit comments

Comments
 (0)