Archived
143137e2b4
Counter.el defines Counter, CounterPair, and App components with {#if}
conditionals, event handlers, and child component composition.
render.js (generated by elc-ui --target=server) is the Node.js render
script the server calls. app.js (generated by elc-ui --target=web) is the
compiled browser module. hydrate.js attaches the runtime to the
server-rendered DOM without replacing it.
index.html shows the integration point with instructions for injecting
server output and the two CLI commands needed to regenerate both targets.
59 lines
4.9 KiB
JavaScript
59 lines
4.9 KiB
JavaScript
/**
|
|
* el-ui SSR render script — generated by elc-ui --target=server
|
|
* Source: Counter.el
|
|
*
|
|
* Exports:
|
|
* renderToString(componentName, props) -> HTML string
|
|
* renderToDocument(componentName, props, opts) -> full HTML document
|
|
* componentNames -> string[]
|
|
*/
|
|
'use strict';
|
|
|
|
const { renderToString: _rts, renderToDocument: _rtd, parseComponents } = require('../../runtime/src/ssr.js');
|
|
|
|
// Component source embedded at compile time
|
|
const _src = Buffer.from('Ly8gc3NyLWNvdW50ZXIvQ291bnRlci5lbAovLwovLyBBIGNvdW50ZXIgY29tcG9uZW50IHRoYXQgZGVtb25zdHJhdGVzOgovLyAgIC0gU3RhdGUgd2l0aCBpbml0aWFsIHZhbHVlCi8vICAgLSB7I2lmfSBjb25kaXRpb25hbCByZW5kZXJpbmcKLy8gICAtIHsjZWFjaH0gbGlzdCByZW5kZXJpbmcKLy8gICAtIEludGVycG9sYXRpb24KLy8gICAtIEV2ZW50IGJpbmRpbmcKLy8gICAtIFNTUiArIGNsaWVudCBoeWRyYXRpb24KLy8KLy8gUnVuIGBub2RlIHJlbmRlci5qcyBDb3VudGVyYCB0byBzZWUgdGhlIHNlcnZlci1yZW5kZXJlZCBIVE1MLgovLyBPcGVuIGluZGV4Lmh0bWwgaW4gYSBicm93c2VyIHRvIHNlZSB0aGUgZnVsbCBTU1IgKyBoeWRyYXRpb24gbGlmZWN5Y2xlLgoKY29tcG9uZW50IENvdW50ZXIgewogICAgcHJvcHMgewogICAgICAgIGluaXRpYWxWYWx1ZTogSW50ID0gMAogICAgICAgIGxhYmVsOiBTdHJpbmcgPSAiQ291bnRlciIKICAgIH0KCiAgICBzdGF0ZSB7CiAgICAgICAgY291bnQ6IEludCA9IDAKICAgICAgICBoaXN0b3J5OiBTdHJpbmcgPSAiIgogICAgfQoKICAgIGZuIGluY3JlbWVudCgpIC0+IFZvaWQgewogICAgICAgIGNvdW50ID0gY291bnQgKyAxCiAgICAgICAgaGlzdG9yeSA9IGhpc3RvcnkgKyAiKyIgKyBjb3VudCArICIgIgogICAgfQoKICAgIGZuIGRlY3JlbWVudCgpIC0+IFZvaWQgewogICAgICAgIGNvdW50ID0gY291bnQgLSAxCiAgICAgICAgaGlzdG9yeSA9IGhpc3RvcnkgKyAiLSIgKyBjb3VudCArICIgIgogICAgfQoKICAgIGZuIHJlc2V0KCkgLT4gVm9pZCB7CiAgICAgICAgY291bnQgPSAwCiAgICAgICAgaGlzdG9yeSA9ICIiCiAgICB9CgogICAgdGVtcGxhdGUgewogICAgICAgIDxkaXYgY2xhc3M9ImNvdW50ZXIiPgogICAgICAgICAgICA8aDIgY2xhc3M9ImNvdW50ZXItbGFiZWwiPntsYWJlbH08L2gyPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJjb3VudC1kaXNwbGF5Ij4KICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPXtjb3VudCA+IDAgPyAiY291bnQgcG9zaXRpdmUiIDogY291bnQgPCAwID8gImNvdW50IG5lZ2F0aXZlIiA6ICJjb3VudCB6ZXJvIn0+CiAgICAgICAgICAgICAgICAgICAge2NvdW50fQogICAgICAgICAgICAgICAgPC9zcGFuPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgPGRpdiBjbGFzcz0iYnV0dG9ucyI+CiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLWRlY3JlbWVudCIgb246Y2xpY2s9eygpID0+IGRlY3JlbWVudCgpfT4tPC9idXR0b24+CiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPSJidG4gYnRuLXJlc2V0IiBvbjpjbGljaz17KCkgPT4gcmVzZXQoKX0+cmVzZXQ8L2J1dHRvbj4KICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9ImJ0biBidG4taW5jcmVtZW50IiBvbjpjbGljaz17KCkgPT4gaW5jcmVtZW50KCl9Pis8L2J1dHRvbj4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICAgIHsjaWYgaGlzdG9yeSAhPSAiIn0KICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9Imhpc3RvcnkiPgogICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJoaXN0b3J5LWxhYmVsIj5oaXN0b3J5Ojwvc3Bhbj4KICAgICAgICAgICAgICAgICAgICA8Y29kZT57aGlzdG9yeX08L2NvZGU+CiAgICAgICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgICAgey9pZn0KICAgICAgICAgICAgeyNpZiBjb3VudCA9PSAwfQogICAgICAgICAgICAgICAgPHAgY2xhc3M9ImhpbnQiPlByZXNzICsgb3IgLSB0byBiZWdpbi48L3A+CiAgICAgICAgICAgIHsvaWZ9CiAgICAgICAgPC9kaXY+CiAgICB9Cn0KCmNvbXBvbmVudCBDb3VudGVyUGFpciB7CiAgICB0ZW1wbGF0ZSB7CiAgICAgICAgPGRpdiBjbGFzcz0iY291bnRlci1wYWlyIj4KICAgICAgICAgICAgPENvdW50ZXIgbGFiZWw9IkxlZnQiIC8+CiAgICAgICAgICAgIDxDb3VudGVyIGxhYmVsPSJSaWdodCIgLz4KICAgICAgICA8L2Rpdj4KICAgIH0KfQoKY29tcG9uZW50IEFwcCB7CiAgICB0ZW1wbGF0ZSB7CiAgICAgICAgPGRpdiBjbGFzcz0iYXBwIj4KICAgICAgICAgICAgPGhlYWRlciBjbGFzcz0iYXBwLWhlYWRlciI+CiAgICAgICAgICAgICAgICA8aDE+ZWwtdWkgU1NSICsgSHlkcmF0aW9uPC9oMT4KICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJzdWJ0aXRsZSI+U2VydmVyLXJlbmRlcmVkLCBjbGllbnQtaHlkcmF0ZWQgd2l0aCBzcHJlYWRpbmcgYWN0aXZhdGlvbjwvcD4KICAgICAgICAgICAgPC9oZWFkZXI+CiAgICAgICAgICAgIDxtYWluIGNsYXNzPSJhcHAtbWFpbiI+CiAgICAgICAgICAgICAgICA8Q291bnRlciBsYWJlbD0iTWFpbiBDb3VudGVyIiAvPgogICAgICAgICAgICAgICAgPENvdW50ZXJQYWlyIC8+CiAgICAgICAgICAgIDwvbWFpbj4KICAgICAgICA8L2Rpdj4KICAgIH0KfQo=', 'base64').toString('utf8');
|
|
|
|
// Parse component names at module load time
|
|
const _components = parseComponents(_src);
|
|
const componentNames = [..._components.keys()];
|
|
|
|
/**
|
|
* Render a component to an HTML string.
|
|
* @param {string} componentName
|
|
* @param {Object} [props={}]
|
|
* @returns {string}
|
|
*/
|
|
function renderToString(componentName, props = {}) {
|
|
return _rts(_src, componentName, props);
|
|
}
|
|
|
|
/**
|
|
* Render a component inside a full HTML document.
|
|
* @param {string} componentName
|
|
* @param {Object} [props={}]
|
|
* @param {Object} [shellOpts={}]
|
|
* @returns {string}
|
|
*/
|
|
function renderToDocument(componentName, props = {}, shellOpts = {}) {
|
|
return _rtd(_src, componentName, props, shellOpts);
|
|
}
|
|
|
|
module.exports = { renderToString, renderToDocument, componentNames };
|
|
|
|
// CLI mode: node render.js <ComponentName> [propsJson]
|
|
if (require.main === module) {
|
|
const compName = process.argv[2];
|
|
const propsJson = process.argv[3] || '{}';
|
|
if (!compName) {
|
|
console.error('Usage: node render.js <ComponentName> [propsJson]');
|
|
process.exit(1);
|
|
}
|
|
let props = {};
|
|
try { props = JSON.parse(propsJson); } catch (e) {
|
|
console.error('render.js: invalid props JSON:', e.message);
|
|
process.exit(1);
|
|
}
|
|
process.stdout.write(renderToString(compName, props));
|
|
}
|