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 ! )