TSX-static
This is a minimal library for tsx pre-rendering or static site generation.
Usage
mod.ts
: Import React from mod.ts, Write tsx DOM as in React, and useReact.stringify
orReact.toString
to generate string from the DOM.types.dom.d.ts
: Thisd.ts
contains additional type declarations not provided by deno, so that frontend code can survive type check.It is of no use if you are not writing frontend JavaScript inside tsx.
Notice:
types.dom.d.ts
contains only type declarations but no constant declarations. You need sth. likedeclare const document: Document
or
declare const HTMLElement: { prototype: HTMLElement new (): HTMLElement }
to use them.
React.stringify
About Document Types
React.stringify
allow passing a parameter DocType
, which specify what kind of document it is producing.
- 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>
. xmlns
will be set for well-known tags, likehtml
,svg
andmath
.- To generate valid standalone
svg
image without assigningxmlns
manually, 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.
Special treatments for style sheet and inline styles
This behavior may change in future versions.
React.stringify
will try to detect tag namestyle
and 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
toString
method.However 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-color
instead ofbackgroundColor
.style example:
{ 'background-color': 'white' }
inline style example:
<div style={{ 'background-color': 'white' }} ></div>
style sheet example:
<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.
<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>
Special treatment for script tag and inline event handlers
React.stringify
will automatically translate function attributes into IIFE, and minification will be applied after that.- This is to say,will be translated into
<button onclick={() => alert('1')}>click me!</button>
<button onclick="(()=>alert('1'))()">click me!</button>
- Notice:
onclick
instead ofonClick
. <script>
tags are given a compile-time onlyIIFE
attributes, if it is set totrue
, all containing functions within this<script>
tag will be translated into IIFE.- There will be no bundler applied to
<script>
tags, and dependencies will not be resolved. If you want to import large pieces of script with complex dependencies, please usescript[src]
orscript[type="module"]
instead.
dist/index.html
Example: How to create a tsx page, render it with tsx-static, and write it into #! /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 or use (for example, even) a Makefile to automate the later part.
Why this project, and what it plans to be
There are already some SSG and pre-rendering libraries, but most of them are not "fully" static. This library will stringify the whole document so that there will be no client-side jsx presence by default, and therefore there will be no server-side rendering.
Another good thing about this project, is that it won't get in your way. Unlike frameworks like preact and next.js, this project only helps you deal with tsx and will do nothing else:
- It won't assume how you resolve dependencies.
- It won't assume how you bundle things.
- It won't assume how
dist/
(orpublic/
) should looks like. - And, it won't assume there should be a webpack.
It gives the control, from webpack
or create-whatever-app
, back to you.