Search code examples
jsxdenooak

Use JSX as view engine in Oak


I'm trying to create a simple html page with Deno and Oak.
As view engine I like to use JSX to generate the actual html.
Here is a simple example, but this fails because JSX is converted to React.createElement and React is not available.

But do I need to import the full React library now? Is that even possible?
(I don't need hooks)

import { Application } from "https://deno.land/x/[email protected]/mod.ts";
import page from "./page.jsx";

const app = new Application();

app.use((ctx) => {
  ctx.response.body = page();
});

await app.listen({ port: 8000 });

page.jsx

export default function() {
    return(<div>TEST</div>)
}

Solution

  • I solved it like this:

    deps.ts

    export { Application } from "https://deno.land/x/[email protected]/mod.ts";
    export { h } from "https://cdn.skypack.dev/preact";
    export { render } from "https://cdn.skypack.dev/[email protected]";
    

    home.jsx

    /** @jsx h */
    import {h} from './deps.ts';
    
    export default function () {
        return <div>TEST</div>
    }   
    

    The JSX pragma is to replace React with h (hyperscript).
    You can also use a tsconfig.json like below:

    {
        "compilerOptions": {
            "jsxFactory": "h",
        }
    }
    

    You have to load it like this: deno run --config ./tsconfig.json ...

    server.js

    import { Application, render } from "./deps.ts";
    import home from "./home.jsx";
    
    const app = new Application();
    
    const respond = function (ctx, vdom) {
      ctx.response.type = "html";
      ctx.response.body = render(vdom(), {}, {pretty: true});
    };
    
    app.use((ctx) => {
      respond(ctx, home);
    });
    
    await app.listen({ port: 8000 });
    

    Here is more information about using JSX in Deno.