Universal rendering

This commit is contained in:
LordMathis 2017-04-09 21:09:27 +02:00
parent f170fa609e
commit e6b71ebc34
20 changed files with 3089 additions and 93 deletions

26
dist/bundle.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -4,9 +4,11 @@
"description": "portfolio", "description": "portfolio",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "start": "npm run build && babel-node src/server.js",
"production": "webpack -p", "start:dev": "export NODE_ENV=development && npm run build:dev && nodemon --exec babel-node -- src/server.js",
"start": "webpack-dev-server" "build": "NODE_ENV=production webpack -p",
"build:dev": "webpack -d",
"build:dev:watch": "webpack -d --watch"
}, },
"keywords": [ "keywords": [
"porfolio", "porfolio",
@ -15,6 +17,8 @@
"author": "Matúš Námešný", "author": "Matúš Námešný",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"ejs": "^2.5.6",
"express": "^4.15.2",
"react": "^15.4.2", "react": "^15.4.2",
"react-dom": "^15.4.2", "react-dom": "^15.4.2",
"react-router-dom": "^4.0.0" "react-router-dom": "^4.0.0"
@ -29,6 +33,7 @@
"html-webpack-plugin": "^2.28.0", "html-webpack-plugin": "^2.28.0",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"node-sass": "^4.5.2", "node-sass": "^4.5.2",
"nodemon": "^1.11.0",
"sass-loader": "^6.0.3", "sass-loader": "^6.0.3",
"style-loader": "^0.16.1", "style-loader": "^0.16.1",
"url-loader": "^0.5.8", "url-loader": "^0.5.8",

18
src/app-client.js Normal file
View File

@ -0,0 +1,18 @@
import React from 'react';
import {render} from 'react-dom';
import {BrowserRouter as Router} from 'react-router-dom';
import {App} from './components';
import './static/stylesheets/main.scss';
const AppClient = () => (
<Router>
<App />
</Router>
)
window.onload = () => {
render(
<AppClient />,
document.getElementById('app')
);
};

View File

@ -1,15 +1,9 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
export default class About extends Component{ export const About = () => (
constructor() { <div className="content">
super(); <h1>About</h1>
} </div>
);
render() { export default About;
return (
<div className="content">
<h1>About</h1>
</div>
);
}
}

19
src/components/App.js Normal file
View File

@ -0,0 +1,19 @@
import React from 'react';
import {Route, Switch} from 'react-router-dom';
import {Home, About, Blog, Portfolio, Resume, NotFoundPage} from '.';
export const App = () => (
<div>
<Route component={Home}/>
<Switch>
<Route exact path='/about' component={About} />
<Route exact path='/blog' component={Blog} />
<Route exact path='/portfolio' component={Portfolio} />
<Route exact path='/resume' component={Resume} />
<Route component={NotFoundPage} />
</Switch>
</div>
);
export default App;

View File

@ -1,9 +1,6 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
export default class Blog extends Component { export default class Blog extends Component {
constructor() {
super();
}
render () { render () {
return ( return (

View File

@ -3,9 +3,6 @@ import config from '../config/config.json';
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
export default class Home extends Component { export default class Home extends Component {
constructor() {
super();
}
render() { render() {
var socialLinks = []; var socialLinks = [];
@ -33,10 +30,10 @@ export default class Home extends Component {
</div> </div>
<div className="menu-links"> <div className="menu-links">
<ul> <ul>
<li><Link to='/about'>About</Link></li> <li><Link to='/about'><i className="fa fa-question" aria-hidden="true"></i> About</Link></li>
<li><Link to='/blog'>Blog</Link></li> <li><Link to='/blog'><i className="fa fa-rss" aria-hidden="true"></i> Blog</Link></li>
<li><Link to='/portfolio'>Portfolio</Link></li> <li><Link to='/portfolio'><i className="fa fa-briefcase" aria-hidden="true"></i> Portfolio</Link></li>
<li><Link to='/resume'>Resume</Link></li> <li><Link to='/resume'><i className="fa fa-file-text-o" aria-hidden="true"></i> Resume</Link></li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -0,0 +1,23 @@
import React from 'react';
import { Link } from 'react-router-dom';
export class NotFoundPage extends React.Component {
componentWillMount() {
const { staticContext } = this.props;
if (staticContext) {
staticContext.is404 = true;
}
}
render() {
return (
<div className="content">
<h1>Uhm... WHAT?</h1>
<h2>Looks like you're lost</h2>
<p>404 Page not found</p>
</div>
);
}
}
export default NotFoundPage;

View File

@ -1,10 +1,6 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
export default class Portfolio extends Component{ export default class Portfolio extends Component{
constructor() {
super();
}
render() { render() {
return ( return (
<div className="content"> <div className="content">

View File

@ -1,10 +1,6 @@
import React, {Component} from 'react'; import React, {Component} from 'react';
export default class Resume extends Component{ export default class Resume extends Component{
constructor() {
super();
}
render() { render() {
return ( return (
<div className="content"> <div className="content">

View File

@ -1,5 +1,7 @@
export { default as Home } from './Home'; export { default as Home } from './Home';
export { default as About} from './About'; export { default as About } from './About';
export { default as Blog} from './Blog'; export { default as Blog } from './Blog';
export { default as Portfolio} from './Portfolio'; export { default as Portfolio } from './Portfolio';
export { default as Resume} from './Resume'; export { default as Resume } from './Resume';
export { default as NotFoundPage } from './NotFoundPage';
export { default as App } from './App';

View File

@ -1,16 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Portfolio</title>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css?family=Inconsolata|Open+Sans|Roboto|Montserrat|Concert+One" rel="stylesheet">
<!-- Font Awesome -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
</head>
<body>
<div id="app">
</div>
</body>
</html>

View File

@ -1,18 +0,0 @@
import React from 'react';
import ReactDom from 'react-dom';
import {HashRouter, Route, Switch} from 'react-router-dom';
import {Home, About, Blog, Portfolio, Resume} from './components';
import './static/stylesheets/main.scss';
ReactDom.render(
<HashRouter>
<div className="container">
<Route component={Home}/>
<Route exact path='/about' component={About} />
<Route exact path='/blog' component={Blog} />
<Route exact path='/portfolio' component={Portfolio} />
<Route exact path='/resume' component={Resume} />
</div>
</HashRouter>,
document.getElementById('app')
);

55
src/server.js Normal file
View File

@ -0,0 +1,55 @@
import path from 'path';
import { Server } from 'http';
import Express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter as Router } from 'react-router-dom';
import { App } from './components/App';
const app = new Express();
const server = new Server(app);
// use ejs templates
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// define the folder that will be used for static assets
app.use(Express.static(path.join(__dirname, 'static')));
// universal routing and rendering
app.get('*', (req, res) => {
let markup = '';
let status = 200;
const context = {};
markup = renderToString(
<Router location={req.url} context={context}>
<App />
</Router>,
);
// context.url will contain the URL to redirect to if a <Redirect> was used
if (context.url) {
return res.redirect(302, context.url);
}
if (context.is404) {
status = 404;
}
return res.status(status).render('index', { markup });
});
// start the server
const port = process.env.PORT || 3000;
const env = process.env.NODE_ENV || 'production';
server.listen(port, (err) => {
if (err) {
return console.error(err);
}
return console.info(
`
Server running on http://localhost:${port} [${env}]
`);
});

2889
src/static/js/bundle.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -69,6 +69,11 @@ body {
.content { .content {
margin-left: 320px; margin-left: 320px;
overflow: auto;
padding: 20px;
h1 {
text-align: center;
}
@media screen and (max-width: $break-medium) { @media screen and (max-width: $break-medium) {
width: 100%; width: 100%;
float: none; float: none;
@ -92,18 +97,12 @@ body {
margin-left: 0; margin-left: 0;
padding: 10px; padding: 10px;
li { li {
display: inline-block; margin: 5px;
} a {
li a {
color: $white; color: $white;
display: block;
text-decoration: none; text-decoration: none;
font-size: 1.4em; font-size: 1.4em;
border: 1px solid white; }
border-radius: 20px;
padding: 2px;
margin: 2px;
width: initial;
} }
} }

View File

@ -9,10 +9,9 @@
<link href="https://fonts.googleapis.com/css?family=Inconsolata|Open+Sans|Roboto|Montserrat|Concert+One" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Inconsolata|Open+Sans|Roboto|Montserrat|Concert+One" rel="stylesheet">
<!-- Font Awesome --> <!-- Font Awesome -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous"> <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
</head> </head>
<body> <body>
<div id="app"> <div id="app"><%- markup -%></div>
</div> <script src="/js/bundle.js"></script>
</body> </body>
</html> </html>

19
temp Normal file
View File

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Portfolio</title>
<!-- Bootstrap -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css?family=Inconsolata|Open+Sans|Roboto|Montserrat|Concert+One" rel="stylesheet">
<!-- Font Awesome -->
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
</head>
<body>
<div id="app">
<div data-reactroot="" data-reactid="1" data-react-checksum="-1250583058"><div id="cover-page" class="cover-page-collapsed" data-reactid="2"><div id="cover-page-content" data-reactid="3"><div data-reactid="4"><h1 id="cover-page-name" data-reactid="5"><a href="/" data-reactid="6">Matúš Námešný</a></h1></div><div class="social" data-reactid="7"><a href="https://github.com/LordMathis" data-reactid="8"><i class="fa fa-github fa-3x" data-reactid="9"></i></a><a href="https://twitter.com/matus_n" data-reactid="10"><i class="fa fa-twitter fa-3x" data-reactid="11"></i></a><a href="mailto:matus@namesny.com" data-reactid="12"><i class="fa fa-envelope-o fa-3x" aria-hidden="true" data-reactid="13"></i></a></div><div class="menu-links" data-reactid="14"><ul data-reactid="15"><li data-reactid="16"><a href="/about" data-reactid="17">About</a></li><li data-reactid="18"><a href="/blog" data-reactid="19">Blog</a></li><li data-reactid="20"><a href="/portfolio" data-reactid="21">Portfolio</a></li><li data-reactid="22"><a href="/resume" data-reactid="23">Resume</a></li></ul></div></div></div><div class="content" data-reactid="24"><h1 data-reactid="25">404</h1><h2 data-reactid="26">Page not found!</h2><p data-reactid="27"><a href="/" data-reactid="28">Go back to the main page</a></p></div></div> </div>
<script src="/js/bundle.js"></script>
</body>
</html>

0
temp.html Normal file
View File

View File

@ -1,17 +1,13 @@
var HtmlWebpackPlugin = require('html-webpack-plugin'); const path = require('path');
var HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/src/index.html',
filename: 'index.html',
inject: 'body'
})
module.exports = { module.exports = {
entry: [ entry: [
'./src/index.js' './src/app-client.js'
], ],
output: { output: {
path: __dirname + '/dist', path: path.join(__dirname, 'src', 'static', 'js'),
filename: "index_bundle.js" publicPath: "/js/",
filename: 'bundle.js'
}, },
module: { module: {
loaders: [ loaders: [
@ -29,5 +25,5 @@ module.exports = {
} }
] ]
}, },
plugins: [HtmlWebpackPluginConfig] plugins: []
} }