Code Restructuring

This commit is contained in:
LordMathis 2017-07-15 16:52:09 +02:00
parent e6b71ebc34
commit 7cfb6e330f
23 changed files with 401 additions and 3129 deletions

View File

@ -1,6 +1,17 @@
{
"presets":[
"es2015",
"react"
]
"es2015", "react"
],
"env": {
"development": {
"presets": ["es2015", "react", "stage-0"],
"plugins": ["transform-runtime"],
"presets": ["react-hmre"]
}
},
"env": {
"build": {
"presets": ["es2015", "react", "stage-0"]
}
}
}

39
.gitignore vendored
View File

@ -1,37 +1,4 @@
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
dist
public
*.log

View File

@ -4,11 +4,9 @@
"description": "portfolio",
"main": "index.js",
"scripts": {
"start": "npm run build && babel-node src/server.js",
"start:dev": "export NODE_ENV=development && npm run build:dev && nodemon --exec babel-node -- src/server.js",
"build": "NODE_ENV=production webpack -p",
"build:dev": "webpack -d",
"build:dev:watch": "webpack -d --watch"
"build": "NODE_ENV=production babel src --out-dir dist --copy-files && webpack -p --progress --config webpack.config.js",
"start": "NODE_ENV=production node ./src/server.js",
"dev": "NODE_ENV=development babel-node ./src/server.js --presets es2015,stage-2 ./srcserver.js"
},
"keywords": [
"porfolio",
@ -17,27 +15,34 @@
"author": "Matúš Námešný",
"license": "ISC",
"dependencies": {
"ejs": "^2.5.6",
"express": "^4.15.2",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"react-router-dom": "^4.0.0"
"babel-cli": "^6.24.1",
"babel-polyfill": "^6.7.4",
"babel-runtime": "^6.6.1",
"express": "^4.13.4",
"isomorphic-fetch": "^2.2.1",
"react": "^15.0.1",
"react-dom": "^15.0.1",
"react-redux": "^4.4.4",
"react-router-dom": "^4.1.1"
},
"devDependencies": {
"babel-core": "^6.24.0",
"babel-loader": "^6.4.1",
"babel-preset-es2015": "^6.24.0",
"babel-preset-react": "^6.23.0",
"css-loader": "^0.28.0",
"file-loader": "^0.11.1",
"html-webpack-plugin": "^2.28.0",
"json-loader": "^0.5.4",
"node-sass": "^4.5.2",
"nodemon": "^1.11.0",
"sass-loader": "^6.0.3",
"style-loader": "^0.16.1",
"url-loader": "^0.5.8",
"webpack": "^2.3.2",
"webpack-dev-server": "^2.4.2"
"babel-core": "^6.7.6",
"babel-jest": "*",
"babel-loader": "^6.2.4",
"babel-plugin-transform-runtime": "^6.7.5",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-preset-react-hmre": "^1.1.1",
"babel-preset-stage-0": "^6.5.0",
"babel-register": "^6.7.2",
"css-loader": "^0.28.4",
"css-modules-require-hook": "^4.0.6",
"extract-text-webpack-plugin": "^2.1.2",
"sass-loader": "^6.0.6",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",
"webpack": "^2.5.1",
"webpack-dev-middleware": "^1.10.2",
"webpack-hot-middleware": "^2.18.0"
}
}

View File

@ -13,6 +13,6 @@ const AppClient = () => (
window.onload = () => {
render(
<AppClient />,
document.getElementById('app')
document.getElementById('root')
);
};

View File

@ -1,9 +1,14 @@
import React, {Component} from 'react';
import React from 'react';
// import { Home } from '.';
export const About = () => (
<div>
<div className="content">
<h1>About</h1>
</div>
</div>
);
export default About;
// <Home key={'home'} fullwidth={false} />

View File

@ -2,15 +2,14 @@ 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 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>

View File

@ -1,12 +1,11 @@
import React, {Component} from 'react';
import React from 'react';
export default class Blog extends Component {
render () {
return (
export const Blog = () => (
<div>
<div className="content">
<h1>Hello</h1>
</div>
)
}
}
</div>
);
export default Blog;

View File

@ -1,43 +1,66 @@
import React, {Component, PropTypes} from 'react';
import config from '../config/config.json';
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import config from '../static/config/config.json';
export default class Home extends Component {
render() {
var socialLinks = [];
var key = 0;
for (var i in config.social) {
socialLinks.push(
<a key={key} href={config.social[i]}>
<i className={"fa fa-" + i + " fa-3x"}></i>
let key = 0;
const objKeys = Object.keys(config.social);
const socialLinks = objKeys.map((val) => {
const link = (
<a key={key} href={config.social[val]}>
<i className={`fa fa-${val} fa-3x`} aria-hidden="true" />
<span className="sr-only">{val}</span>
</a>
);
key++;
};
key += 1;
return link;
});
socialLinks.push(
<a key={key} href={"mailto:" + config.email}><i className="fa fa-envelope-o fa-3x" aria-hidden="true"></i></a>
)
<a key={key} href={`mailto:${config.email}`}>
<i className="fa fa-envelope-o fa-3x" aria-hidden="true" />
<span className="sr-only">e-mail</span>
</a>,
);
return (
<div id="cover-page" className={this.props.location.pathname == '/' ? "cover-page-full" : "cover-page-collapsed"}>
<div id="cover-page" className={this.props.location.pathname === '/' ? 'cover-page-full' : 'cover-page-collapsed'}>
<div id="cover-page-content">
<div>
<h1 id="cover-page-name"><Link to='/'>{ config.name }</Link></h1>
<h1 id="cover-page-name"><Link to="/">{ config.name }</Link></h1>
</div>
<div className="social">
{socialLinks}
</div>
<div className="menu-links">
<ul>
<li><Link to='/about'><i className="fa fa-question" aria-hidden="true"></i> About</Link></li>
<li><Link to='/blog'><i className="fa fa-rss" aria-hidden="true"></i> Blog</Link></li>
<li><Link to='/portfolio'><i className="fa fa-briefcase" aria-hidden="true"></i> Portfolio</Link></li>
<li><Link to='/resume'><i className="fa fa-file-text-o" aria-hidden="true"></i> Resume</Link></li>
<li>
<Link to="/about">
<i className="fa fa-question" aria-hidden="true" /> About
</Link>
</li>
<li>
<Link to="/blog">
<i className="fa fa-rss" aria-hidden="true" /> Blog
</Link>
</li>
<li>
<Link to="/portfolio">
<i className="fa fa-briefcase" aria-hidden="true" /> Portfolio
</Link>
</li>
<li>
<Link to="/resume">
<i className="fa fa-file-text-o" aria-hidden="true" /> Resume
</Link>
</li>
</ul>
</div>
</div>
</div>
)
);
}
}

8
src/components/Main.js Normal file
View File

@ -0,0 +1,8 @@
import React from 'react';
import { Home } from '.';
export const Main = () => (
<Home key={'home'} fullwidth />
);
export default Main;

View File

@ -1,23 +1,18 @@
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;
export const NotFoundPage = (props) => {
if (props.location.pathname === '/') {
return null;
}
}
render() {
return (
<div>
<div className="content">
<h1>Uhm... WHAT?</h1>
<h2>Looks like you're lost</h2>
<h2>Looks like you&apos;re lost</h2>
<p>404 Page not found</p>
</div>
</div>
);
}
}
};
export default NotFoundPage;

View File

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

47
src/components/Post.js Normal file
View File

@ -0,0 +1,47 @@
import React, {Component} from 'react';
import jsonfile from 'jsonfile';
export default class Post extends Component {
static blogPost;
constructor() {
super();
var dataPath = path.join(process.cwd(), 'src/helpers/data.json');
jsonfile.readFile(dataPath, function(err, data) {
if (err) throw err;
for (var i = 0; i < data.posts.length; i++) {
var val = data.posts[i];
if (val.filename === this.props.match.params.post) {
blogPost = val;
}
}
}.bind(this));
}
render () {
return (
<div className="content">
<div className="post-header">
<h1>
{blogPost.title}
</h1>
<span>
{blogPost.published}
</span>
{ if (blogPost.updated) {
<span>{ blogPost.updated }</span>
}}
</div>
<div className="post-content" dangerouslySetInnerHTML={{__html: blogPost.body}}>
</div>
</div>
)
}
}

View File

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

View File

@ -5,3 +5,4 @@ export { default as Portfolio } from './Portfolio';
export { default as Resume } from './Resume';
export { default as NotFoundPage } from './NotFoundPage';
export { default as App } from './App';
export { default as Main } from './Main';

View File

@ -1,55 +1,41 @@
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';
require('babel-register');
const app = new Express();
const server = new Server(app);
var app = new (require('express'))()
var port = process.env.PORT || 3000;
// use ejs templates
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
require('css-modules-require-hook')({
generateScopedName: '[name]__[local]___[hash:base64:5]'
})
// 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;
// initalize webpack dev middleware if in development context
if (process.env.NODE_ENV === 'development') {
var webpack = require('webpack')
var config = require('../webpack.config')
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);
var devMiddleware = require('webpack-dev-middleware')
var hotDevMiddleware = require('webpack-hot-middleware')
var compiler = webpack(config)
var devMiddlewareConfig = {
noInfo: true,
stats: {colors: true},
publicPath: config.output.publicPath
}
if (context.is404) {
status = 404;
app.use(devMiddleware(compiler, devMiddlewareConfig))
app.use(hotDevMiddleware(compiler))
}
app.use(require('express').static('public'))
return res.status(status).render('index', { markup });
});
var serverRender = require('./serverRender')
// 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);
app.get("*", serverRender)
app.listen(port, function(error) {
if (error) {
console.error(error)
} else {
console.info("==> Listening on port %s", port)
}
return console.info(
`
Server running on http://localhost:${port} [${env}]
`);
});
})

44
src/serverRender.js Normal file
View File

@ -0,0 +1,44 @@
import 'babel-polyfill'
import React from 'react'
import { renderToString } from 'react-dom/server'
import { StaticRouter as Router } from 'react-router-dom'
import { App } from './components/App'
function serverRender(req, res) {
let markup = '';
let status = 200;
const context = {}
markup = renderToString(
<Router location={req.url} context={context}>
<App />
</Router>,
);
return res.status(status).send(renderFullPage(markup));
}
function renderFullPage(html) {
return `
<!DOCTYPE html>
<html>
<head>
<title>Redux Hello World</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="root">${process.env.NODE_ENV === 'production' ? html : `<div>${html}</div>`}</div>
<script src="/static/vendor.js"></script>
<script src="/static/bundle.js"></script>
</body>
</html>
`
}
module.exports = serverRender

File diff suppressed because one or more lines are too long

View File

@ -1,17 +0,0 @@
<!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"><%- markup -%></div>
<script src="/js/bundle.js"></script>
</body>
</html>

19
temp
View File

@ -1,19 +0,0 @@
<!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>

View File

View File

@ -1,19 +1,46 @@
const path = require('path');
const { resolve, join } = require('path')
const webpack = require('webpack')
module.exports = {
entry: [
'./src/app-client.js'
],
const config = {
devtool: 'cheap-eval-source-map',
context: resolve(__dirname, 'src'),
entry: {
home: [
'webpack-hot-middleware/client',
'./app-client.js'
]
},
output: {
path: path.join(__dirname, 'src', 'static', 'js'),
publicPath: "/js/",
filename: 'bundle.js'
path: resolve(__dirname,'public/static'),
filename: 'bundle.js',
publicPath: '/static/'
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loader: "babel-loader"},
{test: /\.json$/, exclude: /node_modules/, loader: 'json-loader' },
{test: /\.(png|jpg)$/, exclude: /node_modules/, loader: 'url-loader'},
rules: [
{
test: /\.js$/,
use: [
'babel-loader'
],
exclude: '/node_modules/'
},
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
},
{
loader: 'postcss-loader'
}
]
},
{test: /\.scss$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
@ -22,8 +49,19 @@ module.exports = {
}, {
loader: "sass-loader" // compiles Sass to CSS
}]
}
},
{
test: /\.(png|jpg)$/,
exclude: /node_modules/,
loader: 'url-loader'
},
]
},
plugins: []
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.NamedModulesPlugin()
]
}
module.exports = config

69
webpack.prod.config.js Normal file
View File

@ -0,0 +1,69 @@
const { resolve, join } = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const config = {
context: resolve(__dirname, 'src'),
entry: {
bundle: [
'./app-client.js'
],
'vendor/js': [
'react',
'react-dom',
'redux',
'react-redux'
]
},
output: {
path: resolve(__dirname, 'public/static'),
filename: '[name].js',
publicPath: '/static/'
},
module: {
rules: [
{
test: /\.js$/,
use: [
'babel-loader'
],
exclude: '/node_modules/'
},
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
use: [
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[name]_[local]___[hash:base64:5]'
}
},
{
loader: 'postcss-loader'
}
]
})
}
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.indexOf('node_modules') !== -1
}
}),
new ExtractTextPlugin({
filename: '[name].css',
disable: false,
allChunks: true
})
]
}
module.exports = config