Last active
July 30, 2019 10:01
-
-
Save mizchi/e928b223dbce3a17e80d6d1a843ea8c0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { h } from "preact"; | |
import { useState, useEffect } from "preact/hooks"; | |
import renderPreactToString from "preact-render-to-string"; | |
import ts from "typescript"; | |
import * as rollup from "rollup"; | |
import virtual from "rollup-plugin-virtual"; | |
async function renderToString(component: any, props: any) { | |
return renderPreactToString(h(component, props)); | |
} | |
async function compile(jsSource: string, props: any) { | |
const tsCompiled = ts.transpileModule(jsSource, { | |
compilerOptions: { | |
target: ts.ScriptTarget.ES5, | |
module: ts.ModuleKind.ES2015, | |
jsx: ts.JsxEmit.React, | |
jsxFactory: "h" | |
} | |
}); | |
const bundle = await rollup.rollup({ | |
input: "index.js", | |
plugins: [ | |
virtual({ | |
"index.js": tsCompiled.outputText, | |
preact: ` | |
export const h = __helpers.h; | |
`, | |
// preact: preactSource, | |
"preact/hooks": ` | |
export const useState = __helpers.useState; | |
export const useEffect = __helpers.useEffect; | |
` | |
}) | |
] | |
}); | |
const out = await bundle.generate({ | |
format: "iife", | |
sourcemap: false, | |
name: "$$out" | |
}); | |
const code = out.output[0].code; | |
const expr = code.replace("var $$out =", ""); | |
const func = new Function("__helpers", "return " + expr); | |
const CompiledComponent = func({ h, useEffect, useState }); | |
const html = await renderToString(CompiledComponent, props); | |
console.log("html", html); | |
return { | |
html, | |
props, | |
code: expr | |
}; | |
} | |
const sampleSource = ` | |
/** @jsx h */ | |
import { h } from "preact"; | |
import { useState, useEffect } from "preact/hooks"; | |
export default (props: { count: number }) => { | |
const [value, setValue] = useState(0); | |
useEffect(() => { | |
const id = setInterval(() => { | |
setValue(value + 2); | |
}, 1000); | |
return () => clearInterval(id); | |
}, [value]); | |
return ( | |
<div> | |
hello, {props.count} | |
</div> | |
); | |
} | |
`; | |
compile(sampleSource, { count: 3 }).then(ret => { | |
console.log(ret); | |
}); | |
// {"html":"<div>hello, 3</div>","props":{"count":3},"code":" (function () {\n 'use strict';\n\n const h = __helpers.h;\n\n const useState = __helpers.useState;\n const useEffect = __helpers.useEffect;\n\n /** @jsx h */\n var _virtual_index = (function (props) {\n var _a = useState(0), value = _a[0], setValue = _a[1];\n useEffect(function () {\n var id = setInterval(function () {\n setValue(value + 2);\n }, 1000);\n return function () { return clearInterval(id); };\n }, [value]);\n return (h(\"div\", null,\n \"hello, \",\n props.count));\n });\n\n return _virtual_index;\n\n}());\n"} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment