isomorphic javascript is a technology used to speedup rendering on browser, it can be used a pure version that is server-side-rendering (ssr) to generate template from a react app
Motivation: Create a presentation template to be converted to pdf and configurable with data: produce formatted documents.
This is the way the piece of server generated code and client app can work together, using renderToString
from:
import { renderToString } from ‘react-dom/server’;
the rendered html contains references to the window.STATE, hydrate is used to “undry” the app (sort of bring it to life).
But by using renderToStaticMarkup
from:
import { renderToStaticMarkup } from ‘react-dom/server’;
it is possible to render directly to html markup, without any additional information: pure html.
note
The trick is on the use of:
require("@babel/register");
for transpilling the jsx to javascript transparently.
Here is a src/template.js code:
require("@babel/register"); let fs = require('fs'); const decoratedStyle = (content) => { return '<style type="text/css">\n' + content + '\n</style>\n'; } const nodulespath = __dirname.replace(/\/[a-zA-Z]+$/,'')+"/node_modules/"; const importCss = (moduleref) => { const solvedPath = moduleref.replace("~",nodulespath).replace("\./",__dirname+'/'); //console.log('solvedpath', moduleref, solvedPath); let styledef = fs.readFileSync(solvedPath); return decoratedStyle(styledef); } let render = require('./server'); const template = (state) => { let s = {...state}; delete s.title; let content = render(s); let page = `<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title> ${state.title} </title> ${importCss('~bootstrap/dist/css/bootstrap.min.css')} ${importCss('~font-awesome/css/font-awesome.min.css')} ${importCss('./template.css')} </head> <body> <div id="root"> ${content} </div> </body> `; return page; } module.exports = template;
and here a rendering script that is called by a nodejs service that generate static documents:
const fs = require('fs'); const inlineCss = require('inline-css'); let template = require('./template'); let getState = require('./state/get-state'); let data = process.argv[2]; //console.log('commna',data); let currentselection = { tariff_id: 5, selected_opt: {"3101":66,"3102":79,"3108":166,"3109":34,"3112":155,"3114":85,"3115":157,"3208":161,"4005":180,"4102":151,"4105":170,"4107":67,"4202":159,"4207":105} }; let state = getState(JSON.parse(data)); let html = template(state); const output_fn_inlined = __dirname + '/../dist/output.inlined.html'; inlineCss(html, {url: 'http://ssl.starsellersworld.com/'}) .then(html => { //fs.writeFileSync(output_fn_inlined, html); let buf = Buffer.from(html); //console.log(buf.toString('base64')) let res = {"html":buf.toString('base64')}; //console.log(JSON.stringify(res)) process.send(JSON.stringify(res)); //process.send(data); process.exit(0); }).catch(err=> { console.log('error', err); process.exit(0); });
If you want to know more, you can consider working with us, drop me an email: dc @ xwave . de
( r e m o v e s p a c e s ! )