A simple jsx to DOM Node parser.
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;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
}JSX requires a compiler/bundler. Here are a few example set-ups (note: checkout the examples/ directory for corresponding sample projects):
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:
To use Texsaur with Webpack, use ts-loader and add the following to your webpack.config.js:
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{ test: /tsx?$/, loader: 'ts-loader' },
// ...
]
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
extensionAlias: { '.js': ['.js', '.ts'] }
},
// ...
};See examples/webpack-ts-project for a full setup.
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.
First, configure your tsconfig.json:
Then, import Texsaur in any .tsx file:
import jsx from 'texsaur'
const div = <div>Hello there.</div>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 .tsPlease 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.
Add custom elements to the JSX.IntrinsicElements interface:
namespace JSX {
interface IntrinsicElements {
['my-element']: HTMLElement // or another type representing your custom element
}
}