简体   繁体   中英

How Does a React Snippet get Turned into Browser Javascript?

The React getting started page contains the following snippet

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="build/react.js"></script>
    <script src="build/react-dom.js"></script>
    <script src="https://npmcdn.com/babel-core@5.8.38/browser.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

The code included

<script type="text/babel">
  ReactDOM.render(
    <h1>Hello, world!</h1>,
    document.getElementById('example')
  );
</script>    

is not valid browser javascript -- the inline <h1>Hello, world!</h1> would crash if ran in a javascript context, and the <script/> tag has a type of text/babel .

Conceptually, I get that React is using babel , a compiler/transpiler, and that code inside of text/babel will be treated as babel, and transformed by something into valid javascript.

What less clear to me is how this transformation happens, and which part(s) of the above snippet gets transformed by babel, and which parts get transformed by React.

I realize understanding the framework on this level isn't required to use it.

I also realize that an in-depth answer probably goes beyond the scope of a single Stack Overflow answer. While in-depth answers are welcome, all I'm really looking for is the high level overview of which libraries provide which magic in the above snippet, and what I consider magic are javascript features not offered by the browser. ie, something like

  1. Babel scans for text/babel nodes, transforming above snippet into x,y,z, turning the DOM nodes into javascript that looks like X

  2. React takes above and further transforms it in x,y,z ways, leaving browser with old javascript it understands.

but with x,y,z filled in.

The JSX gets transpiled into a function call, which invokes the React.createElement method.

For example the following JSX:

<p>Hello World</p>

Will be transpiled to:

"use strict";

React.createElement(
  "p",
  null,
  "Hello World"
);

To be more specific, what happens during the transpilation step is that the nodes of the Abstract Syntax Three (AST) are traversed and transformed. In other words, Babel takes an AST and traverses through it, adding, updating, and removing nodes as it goes along to eventually generate the React.createElement function call. So to be clear, React doesn't handle the transformation of JSX at all .

To summarize the transpilation process handled by Babel:

  1. Parse; take code and output an AST.
  2. Transform; traverse AST and manipulate nodes.
  3. Generate; take the final AST and turn it back into a string of code.

This also explaines why you always have to have React in scope when using it in combination with JSX, because otherwise the function call will fail.

Babel exposes the JSX transformation functionality via a plugin . Bonus: you can actually modify the function call to which the JSX will be transpiled to via the pragma option. This allows you to use JSX in combination with a different View Library than React, for example deku . You could specify this in your .babelrc file:

{
  "plugins": [
    ["transform-react-jsx", {
      "pragma": "dom" // default pragma is React.createElement
    }]
  ]
}

Additional resources:

  • You can see the transpilation result here .
  • You can visualize the AST here .
  • You can read more about how Babel handles the transpilation here .

JSX in depth by React might help understand that better. But, basically

var app = <YoucComponent/>; //JSX
var app = React.createElement(YourComponent); //JS

You can just do the JS syntax without using JSX just fine, if you don't want to have some transpiler when you develop a React app.

I hope this suffices:

Anything transpiled to ES5 is totally acceptable by your browser. Babel transpiles what you rightfully said is non-js to ES5.

Take a look at the compiled result. Any funky html tags <> have been turned into function calls of the sort: React.createElement("label", {className: "label"}) which is as JS as it gets.

React is a library like any other that contains function like createElement - which does DOM manipulation much like jquery (albeit more optimized with something called a shadow dom)

That's it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM