From 768bf265e3da22ced48b4291c12143500eb2a373 Mon Sep 17 00:00:00 2001 From: Troy DeMonbreun Date: Fri, 1 Apr 2016 21:26:39 +0000 Subject: [PATCH] New approach for 6062 fix : Show source line number on unknown property warning --- scripts/jest/preprocessor.js | 1 + src/renderers/dom/shared/ReactDOMDebugTool.js | 3 +++ .../__tests__/ReactDOMComponent-test.js | 9 +++++++ .../ReactDOMUnknownPropertyDevtool.js | 27 +++++++++++++------ .../reconciler/instantiateReactComponent.js | 5 ++++ 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/scripts/jest/preprocessor.js b/scripts/jest/preprocessor.js index 29f0d03b06979..616333abe7070 100644 --- a/scripts/jest/preprocessor.js +++ b/scripts/jest/preprocessor.js @@ -36,6 +36,7 @@ var babelOptions = { } ), }], + 'transform-react-jsx-source', ], retainLines: true, }; diff --git a/src/renderers/dom/shared/ReactDOMDebugTool.js b/src/renderers/dom/shared/ReactDOMDebugTool.js index 9fcc3763fadb1..ac7bb10d6dab4 100644 --- a/src/renderers/dom/shared/ReactDOMDebugTool.js +++ b/src/renderers/dom/shared/ReactDOMDebugTool.js @@ -59,6 +59,9 @@ var ReactDOMDebugTool = { onDeleteValueForProperty(node, name) { emitEvent('onDeleteValueForProperty', node, name); }, + onInstantiateReactComponent(instance) { + emitEvent('onInstantiateReactComponent', instance); + }, }; ReactDOMDebugTool.addDevtool(ReactDOMUnknownPropertyDevtool); diff --git a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js index d26c6156e00fb..8f5bd39ad361e 100644 --- a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js +++ b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js @@ -1245,5 +1245,14 @@ describe('ReactDOMComponent', function() { ReactTestUtils.renderIntoDocument(
{}} />); expect(console.error.argsForCall.length).toBe(2); }); + + it('gives source code refs for unknown property warnings', function() { + spyOn(console, 'error'); + ReactDOMServer.renderToString(); + ReactDOMServer.renderToString(
); + expect(console.error.argsForCall.length).toBe(2); + expect(console.error.argsForCall[0][0]).toMatch(/.*\(.*:\d+\)/); + expect(console.error.argsForCall[1][0]).toMatch(/.*\(.*:\d+\)/); + }); }); }); diff --git a/src/renderers/dom/shared/devtools/ReactDOMUnknownPropertyDevtool.js b/src/renderers/dom/shared/devtools/ReactDOMUnknownPropertyDevtool.js index 5adc359063e1e..cb613436cfee2 100644 --- a/src/renderers/dom/shared/devtools/ReactDOMUnknownPropertyDevtool.js +++ b/src/renderers/dom/shared/devtools/ReactDOMUnknownPropertyDevtool.js @@ -17,6 +17,7 @@ var EventPluginRegistry = require('EventPluginRegistry'); var warning = require('warning'); if (__DEV__) { + var cachedSource; var reactProps = { children: true, dangerouslySetInnerHTML: true, @@ -25,7 +26,7 @@ if (__DEV__) { }; var warnedProperties = {}; - var warnUnknownProperty = function(name) { + var warnUnknownProperty = function(name, source) { if (DOMProperty.properties.hasOwnProperty(name) || DOMProperty.isCustomAttribute(name)) { return; } @@ -50,9 +51,10 @@ if (__DEV__) { // logging too much when using transferPropsTo. warning( standardName == null, - 'Unknown DOM property %s. Did you mean %s?', + 'Unknown DOM property %s. Did you mean %s? %s', name, - standardName + standardName, + formatSource(source) ); var registrationName = ( @@ -65,22 +67,31 @@ if (__DEV__) { warning( registrationName == null, - 'Unknown event handler property %s. Did you mean `%s`?', + 'Unknown event handler property %s. Did you mean `%s`? %s', name, - registrationName + registrationName, + formatSource(source) ); }; + + var formatSource = function(source) { + return source ? `(${source.fileName.replace(/^.*[\\\/]/, '')}:${source.lineNumber})` : ''; + }; } var ReactDOMUnknownPropertyDevtool = { onCreateMarkupForProperty(name, value) { - warnUnknownProperty(name); + warnUnknownProperty(name, cachedSource); }, onSetValueForProperty(node, name, value) { - warnUnknownProperty(name); + warnUnknownProperty(name, cachedSource); }, onDeleteValueForProperty(node, name) { - warnUnknownProperty(name); + warnUnknownProperty(name, cachedSource); + }, + onInstantiateReactComponent(instance) { + //Get JSX _source for use in warnings + cachedSource = instance._currentElement ? instance._currentElement._source : null; }, }; diff --git a/src/renderers/shared/reconciler/instantiateReactComponent.js b/src/renderers/shared/reconciler/instantiateReactComponent.js index 796e037b9958b..b0f7cf815d09e 100644 --- a/src/renderers/shared/reconciler/instantiateReactComponent.js +++ b/src/renderers/shared/reconciler/instantiateReactComponent.js @@ -12,6 +12,7 @@ 'use strict'; var ReactCompositeComponent = require('ReactCompositeComponent'); +var ReactDOMInstrumentation = require('ReactDOMInstrumentation'); var ReactEmptyComponent = require('ReactEmptyComponent'); var ReactNativeComponent = require('ReactNativeComponent'); @@ -129,6 +130,10 @@ function instantiateReactComponent(node) { } } + if (__DEV__) { + ReactDOMInstrumentation.debugTool.onInstantiateReactComponent(instance); + } + return instance; }