Playing around with SSR
This commit is contained in:
2
.babelrc
2
.babelrc
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"presets": ["latest", "stage-0"]
|
||||
"presets": ["latest", "stage-0", "react"]
|
||||
}
|
||||
|
||||
140
components/App.js
Normal file
140
components/App.js
Normal file
@@ -0,0 +1,140 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
function App({ items, releses, pageName }) {
|
||||
return (
|
||||
<div className="js--body">
|
||||
<div className="page">
|
||||
<div className="page__header">
|
||||
<div className="branding">
|
||||
<a className="branding__logo" href="/"><img src="/assets/logo.svg"/></a>
|
||||
<div className="branding__content">
|
||||
<div className="nav">
|
||||
<div className="nav__item"><a className="icon-link" href="/howto.html"><span className="icon icon--question icon-link__icon"></span>How to Use Technology Radar?</a></div>
|
||||
<div className="nav__item"><a className="icon-link" href="/overview.html"><span className="icon icon--overview icon-link__icon"></span>Technologies Overview</a></div>
|
||||
<div className="nav__item"><a className="icon-link" href="#todo"><span className="icon icon--search icon-link__icon"></span>Search</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="page__content">
|
||||
<div className="headline-group">
|
||||
<div className="hero-headline">Technology Radar<span className="hero-headline__alt"> Mar 2017</span></div>
|
||||
</div>
|
||||
<div className="quadrant-grid">
|
||||
<div className="quadrant-grid__quadrant">
|
||||
<div className="quadrant-section">
|
||||
<div className="quadrant-section__header">
|
||||
<div className="split">
|
||||
<div className="split__left">
|
||||
<h4 className="headline">Platforms and AOE Services</h4>
|
||||
</div>
|
||||
<div className="split__right"><a className="icon-link" href="/platforms-and-aoe-services.html"><span className="icon icon--pie icon-link__icon"></span>Quadrant Overview</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-section__rings">
|
||||
<div className="quadrant-section__ring">
|
||||
<div className="ring-list">
|
||||
<div className="ring-list__header"><span className="badge badge--assess">assess</span></div>
|
||||
<span className="ring-list__item"><a className="link" href="/platforms-and-aoe-services/bar.html">Bar</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-grid__quadrant">
|
||||
<div className="quadrant-section">
|
||||
<div className="quadrant-section__header">
|
||||
<div className="split">
|
||||
<div className="split__left">
|
||||
<h4 className="headline">Methods & Patterns</h4>
|
||||
</div>
|
||||
<div className="split__right"><a className="icon-link" href="/methods-and-patterns.html"><span className="icon icon--pie icon-link__icon"></span>Quadrant Overview</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-section__rings">
|
||||
<div className="quadrant-section__ring">
|
||||
<div className="ring-list">
|
||||
<div className="ring-list__header"><span className="badge badge--trial">trial</span></div>
|
||||
<span className="ring-list__item"><a className="link" href="/methods-and-patterns/foo.html">Foo</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-grid__quadrant">
|
||||
<div className="quadrant-section">
|
||||
<div className="quadrant-section__header">
|
||||
<div className="split">
|
||||
<div className="split__left">
|
||||
<h4 className="headline">Tools</h4>
|
||||
</div>
|
||||
<div className="split__right"><a className="icon-link" href="/tools.html"><span className="icon icon--pie icon-link__icon"></span>Quadrant Overview</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-section__rings">
|
||||
<div className="quadrant-section__ring">
|
||||
<div className="ring-list">
|
||||
<div className="ring-list__header"><span className="badge badge--hold">hold</span></div>
|
||||
<span className="ring-list__item"><a className="link" href="/tools/grunt.html">Grunt 2</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-grid__quadrant">
|
||||
<div className="quadrant-section">
|
||||
<div className="quadrant-section__header">
|
||||
<div className="split">
|
||||
<div className="split__left">
|
||||
<h4 className="headline">Languages & Frameworks</h4>
|
||||
</div>
|
||||
<div className="split__right"><a className="icon-link" href="/languages-and-frameworks.html"><span className="icon icon--pie icon-link__icon"></span>Quadrant Overview</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-section__rings">
|
||||
<div className="quadrant-section__ring">
|
||||
<div className="ring-list">
|
||||
<div className="ring-list__header"><span className="badge badge--trial">trial</span></div>
|
||||
<span className="ring-list__item"><a className="link" href="/languages-and-frameworks/react.html">React</a></span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-section__ring">
|
||||
<div className="ring-list">
|
||||
<div className="ring-list__header"><span className="badge badge--assess">assess</span></div>
|
||||
<span className="ring-list__item"><a className="link" href="/languages-and-frameworks/react123.html">This is a long title</a></span><span className="ring-list__item"><a className="link" href="/languages-and-frameworks/vue123.html">Vue 123</a></span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-section__ring">
|
||||
<div className="ring-list">
|
||||
<div className="ring-list__header"><span className="badge badge--adopt">adopt</span></div>
|
||||
<span className="ring-list__item"><a className="link" href="/languages-and-frameworks/vue.html">Vue</a></span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="quadrant-section__ring">
|
||||
<div className="ring-list">
|
||||
<div className="ring-list__header"><span className="badge badge--hold">hold</span></div>
|
||||
<span className="ring-list__item"><a className="link" href="/languages-and-frameworks/vue1230.html">Something else</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="page__footer">
|
||||
<div className="branding">
|
||||
<span className="branding__logo"><img src="/assets/logo.svg"/></span>
|
||||
<div className="branding__content"><span className="footnote">AOE is a leading provider of Enterprise Open Source web solutions.
|
||||
Using current agile development methods, more than 250+ developers
|
||||
and consultants in 8 global locations develop customized Open Source
|
||||
solutions for global companies and corporations.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default connect(({ items, releases, pageName }) => ({ items, releases, pageName }))(App);
|
||||
@@ -22,6 +22,7 @@
|
||||
"babel-cli": "6.22.2",
|
||||
"babel-loader": "6.2.10",
|
||||
"babel-preset-latest": "6.22.0",
|
||||
"babel-preset-react": "6.23.0",
|
||||
"babel-preset-stage-0": "6.22.0",
|
||||
"front-matter": "2.1.2",
|
||||
"fs-extra": "2.0.0",
|
||||
@@ -34,6 +35,10 @@
|
||||
"postcss-easy-import": "2.0.0",
|
||||
"postcss-nested": "1.0.0",
|
||||
"pug": "2.0.0-beta9",
|
||||
"react": "15.4.2",
|
||||
"react-dom": "15.4.2",
|
||||
"react-redux": "5.0.2",
|
||||
"redux": "3.6.0",
|
||||
"vue": "2.1.10",
|
||||
"walk": "2.3.9",
|
||||
"webpack": "2.2.0"
|
||||
|
||||
0
react/index.js
Normal file
0
react/index.js
Normal file
@@ -4,17 +4,18 @@ import {
|
||||
outputRadar,
|
||||
} from './radar';
|
||||
import {
|
||||
createStatic,
|
||||
renderApp,
|
||||
} from './static';
|
||||
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const radar = await createRadar();
|
||||
outputRadar(radar);
|
||||
renderApp(radar, 'index');
|
||||
// outputRadar(radar);
|
||||
|
||||
// const radarByQuadrants = groupByQuadrants(radar);
|
||||
createStatic(radar);
|
||||
// createStatic(radar);
|
||||
|
||||
console.log('Built radar');
|
||||
// console.log(JSON.stringify(radar, null, 2));
|
||||
|
||||
@@ -1,36 +1,73 @@
|
||||
import { outputFile } from 'fs-extra';
|
||||
import pug from 'pug';
|
||||
import frontmatter from 'front-matter';
|
||||
import marked from 'marked';
|
||||
import {
|
||||
staticPath,
|
||||
distPath,
|
||||
getAllPugFiles,
|
||||
} from './file';
|
||||
import {
|
||||
vars,
|
||||
} from './template';
|
||||
import React from 'react';
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import { createStore } from 'redux';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
export const createStatic = async (radar) => {
|
||||
const paths = await getAllPugFiles(staticPath());
|
||||
const fileNames = getPlainFileNames(paths);
|
||||
return renderStaticPages(radar, fileNames);
|
||||
return fileNames;
|
||||
};
|
||||
import { distPath } from './file';
|
||||
import App from '../components/App';
|
||||
|
||||
const getPlainFileNames = (paths) => (
|
||||
paths.map((fileName) => {
|
||||
const [ nameWithSuffix ] = fileName.split('/').slice(-1);
|
||||
return nameWithSuffix.substr(0, nameWithSuffix.length - 4);
|
||||
})
|
||||
)
|
||||
const appReducer = (state = {}, action) => {
|
||||
return state;
|
||||
}
|
||||
|
||||
const renderStaticPages = (radar, fileNames) => (
|
||||
Promise.all(fileNames.map((name) => (
|
||||
new Promise((resolve, reject) => (
|
||||
outputFile(distPath(`${name}.html`), pug.renderFile(staticPath(`${name}.pug`), vars({
|
||||
export const renderApp = (radar, pageName) => {
|
||||
// Create a new Redux store instance
|
||||
const store = createStore(appReducer, {
|
||||
...radar,
|
||||
})), (err, data) => {
|
||||
pageName
|
||||
});
|
||||
|
||||
// Render the component to a string
|
||||
const html = renderToString(
|
||||
<Provider store={store}>
|
||||
<App />
|
||||
</Provider>
|
||||
)
|
||||
|
||||
// Grab the initial state from our Redux store
|
||||
const preloadedState = store.getState()
|
||||
|
||||
// Send the rendered page back to the client
|
||||
const fullHtml = renderFullPage(html, preloadedState);
|
||||
|
||||
// Save file
|
||||
save(fullHtml, pageName);
|
||||
}
|
||||
|
||||
const renderFullPage = (html, preloadedState) => {
|
||||
return `
|
||||
<html>
|
||||
<head>
|
||||
<title>AOE Technology Radar - AOE Tech Radar</title>
|
||||
<link rel="stylesheet" href="/styles.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">${html}</div>
|
||||
<script>
|
||||
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState)}
|
||||
</script>
|
||||
<script src="/bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Redux Universal Example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script src="/static/bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
}
|
||||
|
||||
const save = (html, pageName) => (
|
||||
new Promise((resolve, reject) => (
|
||||
outputFile(distPath(`${pageName}.html`), html, (err, data) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
@@ -38,5 +75,4 @@ const renderStaticPages = (radar, fileNames) => (
|
||||
}
|
||||
})
|
||||
))
|
||||
)))
|
||||
);
|
||||
|
||||
42
tasks/static2.js
Normal file
42
tasks/static2.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import { outputFile } from 'fs-extra';
|
||||
import pug from 'pug';
|
||||
import frontmatter from 'front-matter';
|
||||
import marked from 'marked';
|
||||
import {
|
||||
staticPath,
|
||||
distPath,
|
||||
getAllPugFiles,
|
||||
} from './file';
|
||||
import {
|
||||
vars,
|
||||
} from './template';
|
||||
|
||||
export const createStatic = async (radar) => {
|
||||
const paths = await getAllPugFiles(staticPath());
|
||||
const fileNames = getPlainFileNames(paths);
|
||||
return renderStaticPages(radar, fileNames);
|
||||
return fileNames;
|
||||
};
|
||||
|
||||
const getPlainFileNames = (paths) => (
|
||||
paths.map((fileName) => {
|
||||
const [ nameWithSuffix ] = fileName.split('/').slice(-1);
|
||||
return nameWithSuffix.substr(0, nameWithSuffix.length - 4);
|
||||
})
|
||||
)
|
||||
|
||||
const renderStaticPages = (radar, fileNames) => (
|
||||
Promise.all(fileNames.map((name) => (
|
||||
new Promise((resolve, reject) => (
|
||||
outputFile(distPath(`${name}.html`), pug.renderFile(staticPath(`${name}.pug`), vars({
|
||||
...radar,
|
||||
})), (err, data) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
})
|
||||
))
|
||||
)))
|
||||
);
|
||||
Reference in New Issue
Block a user