yahoi
Version:
Yet Another Highly Opinionated Isomorphic Framework
124 lines (93 loc) • 3.72 kB
JavaScript
import React from 'react';
import { renderToString } from 'react-dom/server'
import { ViewRenderer } from './../Renderer';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
const requireAll = require('require-all')
export default class ClientRenderer {
constructor(props) {
this.projectPath = props.projectPath;
this.state = props.state;
this.req = props.req;
this.targetView = props.targetView;
}
loadTranslations(language) {
let resources = requireAll({
dirname : `${this.projectPath}/Translations`,
filter : /^.*\.(JSON|json)$/,
recursive : true,
map : (name, path) => {
if(name=='json') {
return require('path').basename(path).split('.')[0];
} else {
return name;
}
}
});
return resources;
}
render() {
let req = this.req;
let preloadedState = this.preloadedState;
return new Promise((fulfill, reject) => {
let compPath = `${this.projectPath}/Client/index.js`;
try {
var preloadedState = this.state;
// locale Store?
var localeStore = preloadedState.Locale;
if(typeof(localeStore)=='undefined') {
localeStore = {};
}
localeStore.preloadedTranslations = this.loadTranslations('en');
var injectedPreloadedState = JSON.stringify(preloadedState);
if(process.env.NODE_ENV!='development') {
// Server Side Safe require
var Module = require('module');
var originalRequire = Module.prototype.require;
Module.prototype.require = function() {
if(!/.\.css$/.test(arguments[0])) {
return originalRequire.apply(this, arguments);
}
};
var sourceComponent = originalRequire(compPath).default;
} else {
var sourceComponent = require(compPath).default;
}
var Component = (React.createFactory(sourceComponent));
var ssr = {
location: req.url,
context: { },
preloadedState: preloadedState
}
if(process.env.NODE_ENV!='development') {
require = originalRequire;
}
// console.log('root comp', Component);
var initatedComponent = <Component ssr={ssr} />;
const sheet = new ServerStyleSheet()
const htmlStyle = renderToString(sheet.collectStyles(initatedComponent))
var styleTags = sheet.getStyleTags()
var renderedClient = renderToString(initatedComponent);
} catch(e) {
var message = e.message || '';
var stack = e.stack || ''
var renderedClient = `Error rendering ${compPath}:<br/><br/><div style='color:#ff0000'>${message}<br/><br/>${stack}</div>`;
}
let CLIENT_INJECTOR = `<script>window.__PRELOADED_STATE__=${injectedPreloadedState}</script><div id='client-wrapper'>${renderedClient}</div><script src="/public/clientjs/vendor.js"></script><script src="/public/clientjs/main.js"></script>`;
let EXTRACTED_POST_CSS_LINK = `<link rel="stylesheet" type="text/css" href="/Public/clientjs/main.css">`;
var viewRenderer = new ViewRenderer({
filePath: `${this.projectPath}/Views/${this.targetView}`,
data: {
CLIENT: CLIENT_INJECTOR,
STYLED_COMPONENTS_STYLE_TAG: styleTags,
EXTRACTED_POST_CSS_LINK: EXTRACTED_POST_CSS_LINK
}
});
viewRenderer.render().then(renderedHtml => {
fulfill(renderedHtml);
}).catch(e => {
console.log(e);
reject(e);
})
});
}
}