parcel-bundler / parcel

The zero configuration build tool for the web. 📦🚀

Home Page:https://parceljs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Transpiling JSX with debug info enabled (__source props)

xpl opened this issue · comments

Hello, thanks for the great project! Much better than Webpack. I am now developing a nice-looking alternative to react-error-overlay that could be used with Parcel:


(https://github.com/xpl/panic-overlay)

It is written in VanillaJS (i.e. bare DOM API) and not tied to React. However, there is a problem. Suppose the following JSX:

function App () {
    return <h1 style="">Oops!</h1>
}

It contains a subtle error (a style prop shouldn't be a string but an object) — and that error resolves only in run-time within a ReactDOM.render call, producing a totally undecipherable call stack:

However, if you use create-react-app, it displays the correct location of the error in the console, despite that the error occurs in a completely different location:

The above error occurred in the <h1> component:
    in h1 (at index.js:39)

It seems that it is accomplished by injecting a debug information into objects passed to React.createElement calls (I suppose it happens somewhere in Babel by some of its plugins):

function App () {
    return React.createElement ('h1', { style: '',  __source: { fileName: 'index.js', lineNumber: 39 } }, 'Oops!')
}

This way ReactDOM.render could figure the actual code locations where those JSX elements were instantiated, and add these locations to the error messages. The support for that __source property was added to React quite a while ago (see facebook/react#4596)

I could have easily implemented the parsing of these React-specific callstacks from its error messages... but it seems that the parcel index.html command does not generate that debug info in the transpiled JSX.

Maybe there is some option to enable it? Without that __source metainfo, displaying sane error messages for React projects would be an impossible task...

By default parcel only runs the @babel/plugin-transform-react-jsx plugin.
The __source prop is provided by the @babel/plugin-transform-react-jsx-source plugin.
@babel/preset-react runs that one as well, if the development option is set to true: (source: https://github.com/babel/babel/blob/master/packages/babel-preset-react/src/index.js)

This should work for you:

{
	"presets: ['@babel/preset-env', ['@babel/preset-react', {development: true}]]
}

@mischnic Thanks for pointing that out — I've tried adding that to .babelrc and it looks like it did the trick:

function HelloWorld () {
    return <h1>Hello world!</h1>
}

...has been transpiled to:

var _jsxFileName = "/Users/mac/parcel-dev-test/index.js";

function HelloWorld() {
  return React.createElement("h1", {
    __source: {
      fileName: _jsxFileName,
      lineNumber: 2
    },
    __self: this
  }, "Hello world!");
}

Is there any chance that outputting the JSX debug info would be enabled in Parcel by default (when running in the dev server mode)? As Parcel is marketed as "zero-configuration"... :)

I understand that it might hurt the performance (making Parcel not so "blazingly fast"), so if the performance is an issue, then no problem. But it would be nice to not having to create that .babelrc config each time.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs.