Can I use inline HTML in a script as below by using a library like jsx:
React renders JSX html syntax to JS using functions such as React.createElement (among others for Fragments and so on). But that all boils down to the @babel/plugin-transform-react-jsx plugin which does the transpiling of this:
return(<div id="hello">Hello World</div>)
into this...
return React.createElement('div', {id: 'hello'}, 'Hello World');
However you can replace React.createElement with you're own function to do this. You can read more on that here: https://babeljs.io/docs/en/next/babel-plugin-transform-react-jsx.html
You should also look at libraries which do exactly this such as nervjs, jsx-render and deku. All of these use a JSX html syntax without react. Some (such as jsx-render) are only focused on converting JSX to the final JS, which might be what you're looking for.
The author of that package wrote an article on it here: https://itnext.io/lessons-learned-using-jsx-without-react-bbddb6c28561
Also Typescript can do this if you use that...but I've no first hand experience with it.
To sum up
You can do it without React, but not without Babel or Typescript.
It looks like the dom-chef package can do this. From the readme:
- No API, JSX gets auto transformed into actual DOM elements.
// babel.config.js const plugins = [ [ '@babel/plugin-transform-react-jsx', { pragma: 'h', pragmaFrag: 'DocumentFragment', } ] ]; // ...
const {h} = require('dom-chef'); const handleClick = e => { // <a> was clicked }; const el = ( <div class="header"> <a href="#" class="link" onClick={handleClick}>Download</a> </div> ); document.body.appendChild(el);
I was looking for something like this myself. A way to write Components and JSX like for simple projects. Didn't find one that I liked so I've built this: https://github.com/SagiMedina/Aviya#aviya Have a look, maybe it will answer your problem as well.
I was able to write JSX files and inject them into an HTML page using a 'fake' React file.
no-react.js
/**
* Include this script in your HTML to use JSX compiled code without React.
*/
const React = {
createElement: function (tag, attrs, children) {
var element = document.createElement(tag);
for (let name in attrs) {
if (name && attrs.hasOwnProperty(name)) {
let value = attrs[name];
if (value === true) {
element.setAttribute(name, name);
} else if (value !== false && value != null) {
element.setAttribute(name, value.toString());
}
}
}
for (let i = 2; i < arguments.length; i++) {
let child = arguments[i];
element.appendChild(
child.nodeType == null ?
document.createTextNode(child.toString()) : child);
}
return element;
}
};
Then compile your jsx.
test.jsx
const title = "Hello World";
document.getElementById('app').appendChild(
<div>
<h1>{title}</h1>
<h2>This is a template written in TSX, then compiled to JSX by tsc (the Typescript compiler), and finally
injected into a web page using a script</h2>
</div>
);
Resulting compiled 'test.js'
var title = "Hello World";
document.querySelector('#app').appendChild(React.createElement("div", null,
React.createElement("h1", null, title),
React.createElement("h2", null, "This is a template written in TSX, then compiled to JSX by tsc (the Typescript compiler), and finally" + " " + "injected into a web page")));
And finally, the HTML page that includes both scripts.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>no-react</title>
<script src="no-react.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
<script src="test.js"></script>
Jsx parse the return (<div>test html code</div>);
to something like this return React.createElement('div', {...});
then if you don't using react.js
, then browser will not know what React
is and trigger an error.
You can have a look at documentation: in-browser JSX transform, and also see Babel documentation
You can achieve what you want, but it is discouraged in production...