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-cli": "6.22.2",
|
||||||
"babel-loader": "6.2.10",
|
"babel-loader": "6.2.10",
|
||||||
"babel-preset-latest": "6.22.0",
|
"babel-preset-latest": "6.22.0",
|
||||||
|
"babel-preset-react": "6.23.0",
|
||||||
"babel-preset-stage-0": "6.22.0",
|
"babel-preset-stage-0": "6.22.0",
|
||||||
"front-matter": "2.1.2",
|
"front-matter": "2.1.2",
|
||||||
"fs-extra": "2.0.0",
|
"fs-extra": "2.0.0",
|
||||||
@@ -34,6 +35,10 @@
|
|||||||
"postcss-easy-import": "2.0.0",
|
"postcss-easy-import": "2.0.0",
|
||||||
"postcss-nested": "1.0.0",
|
"postcss-nested": "1.0.0",
|
||||||
"pug": "2.0.0-beta9",
|
"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",
|
"vue": "2.1.10",
|
||||||
"walk": "2.3.9",
|
"walk": "2.3.9",
|
||||||
"webpack": "2.2.0"
|
"webpack": "2.2.0"
|
||||||
|
|||||||
0
react/index.js
Normal file
0
react/index.js
Normal file
@@ -4,17 +4,18 @@ import {
|
|||||||
outputRadar,
|
outputRadar,
|
||||||
} from './radar';
|
} from './radar';
|
||||||
import {
|
import {
|
||||||
createStatic,
|
renderApp,
|
||||||
} from './static';
|
} from './static';
|
||||||
|
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const radar = await createRadar();
|
const radar = await createRadar();
|
||||||
outputRadar(radar);
|
renderApp(radar, 'index');
|
||||||
|
// outputRadar(radar);
|
||||||
|
|
||||||
// const radarByQuadrants = groupByQuadrants(radar);
|
// const radarByQuadrants = groupByQuadrants(radar);
|
||||||
createStatic(radar);
|
// createStatic(radar);
|
||||||
|
|
||||||
console.log('Built radar');
|
console.log('Built radar');
|
||||||
// console.log(JSON.stringify(radar, null, 2));
|
// console.log(JSON.stringify(radar, null, 2));
|
||||||
|
|||||||
@@ -1,36 +1,73 @@
|
|||||||
import { outputFile } from 'fs-extra';
|
import { outputFile } from 'fs-extra';
|
||||||
import pug from 'pug';
|
import React from 'react';
|
||||||
import frontmatter from 'front-matter';
|
import { renderToString } from 'react-dom/server';
|
||||||
import marked from 'marked';
|
import { createStore } from 'redux';
|
||||||
import {
|
import { Provider } from 'react-redux';
|
||||||
staticPath,
|
|
||||||
distPath,
|
|
||||||
getAllPugFiles,
|
|
||||||
} from './file';
|
|
||||||
import {
|
|
||||||
vars,
|
|
||||||
} from './template';
|
|
||||||
|
|
||||||
export const createStatic = async (radar) => {
|
import { distPath } from './file';
|
||||||
const paths = await getAllPugFiles(staticPath());
|
import App from '../components/App';
|
||||||
const fileNames = getPlainFileNames(paths);
|
|
||||||
return renderStaticPages(radar, fileNames);
|
|
||||||
return fileNames;
|
|
||||||
};
|
|
||||||
|
|
||||||
const getPlainFileNames = (paths) => (
|
const appReducer = (state = {}, action) => {
|
||||||
paths.map((fileName) => {
|
return state;
|
||||||
const [ nameWithSuffix ] = fileName.split('/').slice(-1);
|
}
|
||||||
return nameWithSuffix.substr(0, nameWithSuffix.length - 4);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
const renderStaticPages = (radar, fileNames) => (
|
export const renderApp = (radar, pageName) => {
|
||||||
Promise.all(fileNames.map((name) => (
|
// Create a new Redux store instance
|
||||||
new Promise((resolve, reject) => (
|
const store = createStore(appReducer, {
|
||||||
outputFile(distPath(`${name}.html`), pug.renderFile(staticPath(`${name}.pug`), vars({
|
|
||||||
...radar,
|
...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) {
|
if (err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} 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