Running .jsx from the command-line
Here’s a simplified root .jsx
file I’d like to run to generate some HTML from the command-line.
index.jsx:
// Use import statements:
import * as React from "react";
import { renderToStaticMarkup } from "react-dom/server";
// Use JSX
const App = () => <div>The app</div>;
// Use an API only available in node (and some more JSX):
process.stdout.write(renderToStaticMarkup(<App />));
I’ll use yarn
to install those imported libs, which has the side-effect of creating a package.json
file:
yarn add react react-dom
I want to run index.jsx
directly, without having to transpile then execute as two separate steps. The script doesn’t look particularly special, but does use import
and JSX, two features that cause problems as I’m not using a bundler.
Executing node index.jsx
gives this error (caused by the import
statements):
(node:58928) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
I try creating a package.json
and setting "type": "module"
, and re-run node index.jsx
to get a different error (caused by file extension):
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".jsx" for /...
Renaming index.jsx
to index.js
and executing with node index.js
gives a different error:
const App = () => <div>The app</div>;
^
SyntaxError: Unexpected token '<'
(I get the same error if I try changing the file extension to .mjs
and running node index.mjs
)
At this point it feels like I’ve hit a brick wall with node
, so need to look at alternative solutions.
Before going any further I need to revert my changes: restoring the original filename of index.jsx
, and removing the "type": "module"
property from package.json
.
Setup babel-node
I want to transpile-and-run in one step, which is exactly what babel-node
is designed for.
# Install all libs needed to run babel-node on a file containing JSX:
yarn add -D @babel/core @babel/node @babel/preset-env @babel/preset-react
Create a babel.config.json
file:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
Use npx babel-node index.jsx
to run, and we can see the output:
<div>The app</div>
That’s it; it’s working! We can now iterate and experiment to our heart’s content.