Cannot use JSX with nodejs ESM module loader

Viewed 2735

I attempted to run a simple block of code featuring React "render" method , but the browser didn't display the text.

import React from 'react';
import ReactDOM from 'react-dom';

ReactDOM.render(<h1>Hello World</h1>,document.getElementById('root'));

I'm using VS Code as editor therefore I typed the "Run and Debug Node.js" command. It came up with the warning below

(node:3004) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.

Setting "type:module" in the package.json file solved the problem but on the other side another problem arised

(node:18968) ExperimentalWarning: The ESM module loader is experimental.    
warning.js:32
SyntaxError: Unexpected token '<'
 at Loader.moduleStrategy (internal/modules/esm/translators.js:81:18)
 at async link (internal/modules/esm/module_job.js:37:21)

That won't allow me to write any tags whatsover. What am I missing and how can I solve it? Below is the index.html file and the file structure

<html>
    <head>
        <title> React Test</title>
    </head>

    <body>
        <div id="root"></div>
    </body>
</html>

The file structure

3 Answers

JSX isn't a valid JavaScript syntax and it isn't part of any ECMAScript specification as well at the current time. NodeJS supporting ESM does not mean it supports JSX natively.

JSX are expected to be transpiled into a valid JavaScript on build/compile time using tools like babel. If you are using React, the most simple way to do this is to use babel with @babel/preset-react, which will transpile all JSX into React.createElement() calls. You can then run the code generated by babel using node.

To give you a clearer picture, here is a Babel online REPL that you can play with to see how your code are transpiled by babel.

A common setup for react apps that is going to be run on the browser is like:

  1. Use webpack to bundle your app
  2. Configure webpack to use babel-loader so it transpiles your code into something that browsers can run
  3. Use the generated javascript bundle on browser

I don't understand why you have .vscode folder in your src folder and it contains index.html and index.js files.

I think you need to move your index.js file from .vscode folder to src and delete .vscode folder. Or just create a new app with npm.

that folder structure came out after using create-react-app?

btw, try to return the component with React.createElement()

return React.createElement('div', {className: 'shopping-list'},
  React.createElement('h1', /* ... h1 children ... */),
  React.createElement('ul', /* ... ul children ... */)
);

as docs says "The render method returns a description of what you want to see on the screen. React takes the description and displays the result. In particular, render returns a React element, which is a lightweight description of what to render. Most React developers use a special syntax called “JSX” which makes these structures easier to write. The syntax is transformed at build time to React.createElement('div')."

check this out https://reactjs.org/docs/react-api.html#createelement

----- add on You can now import .js file in node v12.x, in 2 steps:

  • after adding the following line in your package.json file:
    // package.json
    {
      "type": "module"
    }
    
  • you need to add --experimental-modules flag when launching the script:
    node --experimental-modules index.js
    

https://nodejs.org/api/esm.html#esm_commonjs_json_and_native_modules

Related