Awesome
🦖 Texsaur
A simple jsx to DOM Node
parser.
🚀 Usage
To create a DOM element in JavaScript, we could use document.createElement
:
const div = document.createElement('div');
div.classList.add('example');
div.innerText = 'hello there';
div.addEventListener('click', () => console.log('clicked!'));
Texsaur lets you do this with jsx instead:
import jsx from 'texsaur';
const div = (
<div class="example"
onclick={() => console.log('clicked!')}>
Hello there
</div>
) as HTMLElement;
♻️ Resuability
You can create a reusable component by creating a function:
function Header({ title }: { title: string }) {
return <header>
<h1>{title}</h1>
</header>
}
document.body.appendChild(
<div>
<Header title="Hello there" />
{/* Same as */}
{Header({ title: 'Hello there.' })}
</div>
)
To work with JSX, the function must implement Component
:
interface Component {
(properties?: { [key: string]: any }, children?: Node | Node[]): Element
}
📦 Bundlers
JSX requires a compiler/bundler. Here are a few example set-ups (note: checkout the examples/ directory for corresponding sample projects):
⚡ Vite
In vite.config.js
, add the esbuild.jsx
property:
export default {
esbuild: {
jsxFactory: 'jsx',
jsxFragment: 'jsx.Fragment', // optional - enables fragments (<></>)
}
}
However, if your project contains a tsconfig, vite should read these properties from there as of version 4 - no vite configuration required!
Examples:
💙 Typescript Usage
Texsaur supports a few models of JSX code generation (determined the jsx
property in your tsconfig):
"react"
,"react-jsx"
,- and
"preserve"
.
The differences between these are outlined in the following sections.
Method 1: "jsx": "react"
First, configure your tsconfig.json
:
"compilerOptions": {
"jsx": "react",
"jsxFactory": "jsx",
"jsxFragmentFactory": "jsx.Fragment" // optional - enables fragments (<></>)
}
Then, import Texsaur in any .tsx file:
import jsx from 'texsaur'
const div = <div>Hello there.</div>
Method 2: "jsx": "react-jsx"
This method comes with a few more quirks, but it allows you to drop the import jsx
statements in your tsx
files.
In your tsconfig.json
:
"compilerOptions": {
"moduleResolution": "node16", // or nodenext
"jsx": "react-jsx",
"jsxImportSource": "texsaur"
}
By using node16
module resolution, your package will be able to take advantage of the exports
field in texsaur's package.json. However, this requires you use the file suffix in imports:
import Foo from './components/foo'
// becomes
import Foo from './components/foo.js' // .js even if it's .tsx or .ts
Method 3: "jsx": "preserve"
Please note that this repository does not contain any examples of this, nor have we tested it. In theory, this should work.
Configure your tsconfig.json
:
"compilerOptions": {
"jsx": "preserve",
}
This will output the jsx code as-is. You will need another bundler/compiler (e.g. babel) to transform it before it can be used in a browser.
Declare Custom Elements
Add custom elements to the JSX.IntrinsicElements
interface:
namespace JSX {
interface IntrinsicElements {
['my-element']: HTMLElement // or another type representing your custom element
}
}