react.ts provides a way to generate html or xml string from tsx. This is done by class React, and its stringify method.
React.toString is a shortcut to React.stringify('html'), to provide a default toString method.
#! /usr/bin/env deno run -A --unstable
import { React } from '<path to tsx-static/mod.ts>'
export const index = (
<html>
<head>
<title>Index</title>
</head>
<body></body>
</html>
)
Deno.mkdirSync('dist/', { recursive: true })
Deno.writeTextFileSync('dist/index.html', index.stringify('html'))You can write your own build script, use builder.ts, or use (for example, even) a Makefile to automate the building task.
React.stringify can produce string for different document type, which is decided by the first parameter passed to it.
- HTML
- This is to generate valid HTML document. HTML specified self-closing tags will be forced self-closing, and other tags will be forced non-self-closing, no matter they actually have children or not.
- Self closing tags will be like
<br>instead of<br/>
- XML
- This is the stringify mode without any assumption. Tags will be self-closing as long as they have no children, the document will be in valid XML, therefore
<br/>instead of<br>. - This mode will not automatically set
xmlns.
- This is the stringify mode without any assumption. Tags will be self-closing as long as they have no children, the document will be in valid XML, therefore
- XHTML
- This mode tries to generate document that is both valid XML and valid HTML, so that it becomes valid XHTML document.
- Like HTML, only self-closing tags can be self-closing, and self-closing tags are forced to be self-closing.
- Like XML,
<br/>instead of<br>. xmlnswill be set for well-known tags, likehtml,svgandmath.- To generate valid standalone
svgimage without assigningxmlnsmanually, this, instead of XML, is the preferred mode. - XHTML mode may result in slightly bigger document than HTML mode. For HTML document, mode HTML is usually preferred.
React.stringifywill try to detect tag namestyleand attribute namestyle, even in XML mode.- If the content of the tag or attribute is an object, the object will be parsed as a style sheet or style object.
- It will then be stringified by the specific routine for style sheets and styles, instead its own
toStringmethod. - The attribute names of the style object will not be in JavaScript way, and the names are stringified as is without translation. That is to say, you should use
background-colorinstead ofbackgroundColor. This is different from how React (the real React) process things. - Examples of how to use inline style and internal style sheet:
- inline style:
<div style={{ 'background-color': 'white' }} ></div>
- style sheet:
<style> {{ 'html, body': { background: 'white' }, 'div#main': { display: 'block' } }} </style>
- A style sheet entry can be an array. In that case, that entry is expanded to multiple sheets with the same selector. This can be useful for at-rules (like
@font-face).<style> {{ 'div#main p': [ { background: 'white' }, { display: 'block' } ] }} </style>
- Nested style sheet is allowed since
1.1.0. The following example should work exactly the same as above.<style> {{ 'div#main': { p: [ { background: 'white' }, { display: 'block' } ] } }} </style>
- inline style:
-
React.stringifywill automatically translate function attributes into IIFE, with (hopefully) minification applied:<button onclick={() => alert('1')}>click me!</button>
will be translated into
<button onclick="(()=>alert('1'))()">click me!</button>
-
onclickinstead ofonClick, this is the same behavior as how we process style sheets, but different from how (the real) React works. -
<script>tags has a compile-time onlyIIFEattribute, if it is set totrue, all containing functions within this<script>tag will be translated into IIFE.<div onclick={() => console.log(1)}> <script IIFE> {() => console.log(1)} {() => console.log(1)} {() => { console.log(1) console.log(1) console.log(1) console.log(1) }} </script> </div>
will be translated into (the below html fragment is re-formatted for readability)
<div onclick="(() => console.log(1))()"> <script> ;(() => console.log(1))() ;(() => console.log(1))() ;(() => { console.log(1) console.log(1) console.log(1) console.log(1) })() </script> </div>
-
There will be no bundler applied to
<script>tags, since deno treat code inside<script>tag as normal code, and dependencies will not be resolved.- If you want to bundle and import large pieces of script with complex dependencies, consider
script[src]orscript[type="module"]instead. You might useloaders.tsfrombuilderto compile TS code into frontend JavaScript. - If bundling is not what you want,
script[IIFE]might just serve your need.
- If you want to bundle and import large pieces of script with complex dependencies, consider