Skip to content

Commit 443ef71

Browse files
committed
Fail the build for console.error/warn() where we can't read the stack
1 parent c9f834b commit 443ef71

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

packages/react-is/src/ReactIs.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ export function isAsyncMode(object: any) {
8787
if (__DEV__) {
8888
if (!hasWarnedAboutDeprecatedIsAsyncMode) {
8989
hasWarnedAboutDeprecatedIsAsyncMode = true;
90-
console.warn(
90+
// Using console['warn'] to evade Babel and ESLint
91+
console['warn'](
9192
'The ReactIs.isAsyncMode() alias has been deprecated, ' +
9293
'and will be removed in React 17+. Update your code to use ' +
9394
'ReactIs.isConcurrentMode() instead. It has the exact same API.',

scripts/babel/transform-replace-console-calls.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const helperModuleImports = require('@babel/helper-module-imports');
1010

1111
module.exports = function replaceConsoleCalls(babel) {
1212
let consoleErrors = new WeakMap();
13-
function getConsoleError(path, file, opts) {
13+
function getConsoleError(path, file) {
1414
if (!consoleErrors.has(file)) {
1515
consoleErrors.set(
1616
file,
@@ -26,7 +26,7 @@ module.exports = function replaceConsoleCalls(babel) {
2626
}
2727

2828
let consoleWarns = new WeakMap();
29-
function getConsoleWarn(path, file, opts) {
29+
function getConsoleWarn(path, file) {
3030
if (!consoleWarns.has(file)) {
3131
consoleWarns.set(
3232
file,
@@ -53,11 +53,27 @@ module.exports = function replaceConsoleCalls(babel) {
5353
return;
5454
}
5555
if (path.get('callee').matchesPattern('console.error')) {
56-
const id = getConsoleError(path, pass.file, this.opts);
56+
if (this.opts.shouldError) {
57+
throw path.buildCodeFrameError(
58+
"This module has no access to the React object, so it can't " +
59+
'use console.error() with automatically appended stack. ' +
60+
"As a workaround, you can use console['error'] which won't " +
61+
'be transformed.'
62+
);
63+
}
64+
const id = getConsoleError(path, pass.file);
5765
path.node.callee = id;
5866
}
5967
if (path.get('callee').matchesPattern('console.warn')) {
60-
const id = getConsoleWarn(path, pass.file, this.opts);
68+
if (this.opts.shouldError) {
69+
throw path.buildCodeFrameError(
70+
"This module has no access to the React object, so it can't " +
71+
'use console.warn() with automatically appended stack. ' +
72+
"As a workaround, you can use console['warn'] which won't " +
73+
'be transformed.'
74+
);
75+
}
76+
const id = getConsoleWarn(path, pass.file);
6177
path.node.callee = id;
6278
}
6379
},

scripts/rollup/build.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,15 @@ function getBabelConfig(
121121
presets: [],
122122
plugins: [],
123123
};
124-
if (isDevelopment && canAccessReactObject) {
124+
if (isDevelopment) {
125125
options.plugins.push(
126126
// Turn console.error/warn() into a custom wrapper
127-
require('../babel/transform-replace-console-calls')
127+
[
128+
require('../babel/transform-replace-console-calls'),
129+
{
130+
shouldError: !canAccessReactObject,
131+
},
132+
]
128133
);
129134
}
130135
if (updateBabelOptions) {

0 commit comments

Comments
 (0)