diff --git a/.babelrc b/.babelrc deleted file mode 100644 index d2609ca..0000000 --- a/.babelrc +++ /dev/null @@ -1,17 +0,0 @@ -{ - "presets":[ - "es2015", "react" - ], - "env": { - "development": { - "presets": ["es2015", "react", "stage-0"], - "plugins": ["transform-runtime"], - "presets": ["react-hmre"] - } - }, - "env": { - "build": { - "presets": ["es2015", "react", "stage-0"] - } - } -} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..59affb2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,34 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# Matches multiple files with brace expansion notation +# Set default charset +[*.{js,py}] +charset = utf-8 + +# 4 space indentation +[*.py] +indent_style = space +indent_size = 4 + +# Tab indentation (no size specified) +[Makefile] +indent_style = tab + +# Indentation override for all JS under lib directory +[lib/**.js] +indent_style = space +indent_size = 2 + +# Matches the exact files either package.json or .travis.yml +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 + diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..d1c13a8 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,23 @@ +{ + "env": { + "browser": true, + "es6": true, + "node": true + }, + "extends": [ + "standard", + "plugin:react/recommended" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parser": "babel-eslint", + "plugins": [ + "babel", + "react" + ], + "rules": { + "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }] + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 49f5104..ecd48b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ node_modules -dist +build public *.log content diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..100f654 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,38 @@ +module.exports = function (api) { + const presets = [ + '@babel/preset-env', + '@babel/react' + ] + const plugins = [ + '@babel/plugin-proposal-object-rest-spread', + '@babel/plugin-transform-runtime', + '@babel/plugin-transform-template-literals', + '@babel/plugin-proposal-class-properties' + ] + + if (api.env() === 'development') { + plugins.push([ + 'css-modules-transform', { + 'generateScopedName': '[name]__[local]___[hash:base64:5]', + 'preprocessCss': processSass, + 'extensions': ['.css', '.scss'] + } + ]) + } + + return { + presets, + plugins + } +} + +var sass = require('node-sass') + +function processSass (data, filename) { + var result + result = sass.renderSync({ + data: data, + file: filename + }).css + return result.toString('utf8') +} diff --git a/config.json b/config.json index 4bbce5d..70f9560 100644 --- a/config.json +++ b/config.json @@ -4,13 +4,13 @@ "name": "Matúš Námešný", "email": "matus@namesny.com", "social": { - "twitter": "https://twitter.com/matus_n", "github": "https://github.com/LordMathis", "codepen": "https://codepen.io/LordMathis/", "linkedin": "https://www.linkedin.com/in/mat%C3%BA%C5%A1-n%C3%A1me%C5%A1n%C3%BD-3903b6128/" }, "contentPath": "./content", "renderPath": "./renders", + "dataPath": "./src/utils/data.json", "files": [ "about.md", "resume.md" ] diff --git a/package.json b/package.json index 252c755..684f186 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,14 @@ { "name": "portfolio", - "version": "1.0.0", + "version": "2.0.0", "description": "portfolio", "main": "index.js", "scripts": { - "build": "NODE_ENV=production webpack -p --progress --config webpack.prod.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" + "build": "npm run build-client && npm run build-server", + "build-client": "NODE_ENV=production webpack --config webpack.client.js -p --progress", + "build-server": "NODE_ENV=production webpack --config webpack.server.js -p --progress", + "start": "NODE_ENV=production node ./build/server.js", + "start-dev": "NODE_ENV=development babel-node ./src/server.js" }, "keywords": [ "porfolio", @@ -16,34 +18,45 @@ "license": "MIT", "dependencies": { "async": "^2.5.0", - "axios": "^0.17.0", "express": "^4.13.4", + "express-static-gzip": "^1.1.3", "front-matter": "^2.2.0", "jsonfile": "^4.0.0", - "markdown-it": "^8.4.0", - "moment": "^2.19.1", + "markdown-it": "^8.4.2", + "moment": "^2.24.0", "node-sass": "^4.9.0", - "react": "^15.0.1", - "react-dom": "^15.0.1", - "react-router-dom": "^4.1.1" + "prop-types": "^15.7.2", + "react": "^16.7.0", + "react-dom": "^16.7.0", + "react-router-dom": "^4.1.1", + "serialize-javascript": "^1.6.1" }, "devDependencies": { - "babel-cli": "^6.26.0", - "babel-core": "^6.7.6", - "babel-jest": "*", - "babel-loader": "^7.1.4", - "babel-plugin-transform-runtime": "^6.7.5", - "babel-polyfill": "^6.26.0", - "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", - "babel-runtime": "^6.26.0", + "@babel/core": "^7.2.2", + "@babel/node": "^7.2.2", + "@babel/plugin-proposal-class-properties": "^7.3.3", + "@babel/plugin-proposal-object-rest-spread": "^7.2.0", + "@babel/plugin-transform-runtime": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.2.0", + "@babel/preset-env": "^7.2.3", + "@babel/preset-react": "^7.0.0", + "@babel/runtime": "^7.2.0", + "babel-eslint": "^10.0.1", + "babel-loader": "^8.0.5", + "babel-plugin-css-modules-transform": "^1.6.2", "clean-webpack-plugin": "^0.1.19", "compression-webpack-plugin": "^1.1.11", + "create-file-webpack": "^1.0.2", "css-loader": "^0.28.11", - "css-modules-require-hook": "^4.0.6", + "css-modules-require-hook": "^4.2.3", + "eslint": "^5.14.0", + "eslint-config-standard": "^12.0.0", + "eslint-plugin-babel": "^5.3.0", + "eslint-plugin-import": "^2.16.0", + "eslint-plugin-node": "^8.0.1", + "eslint-plugin-promise": "^4.0.1", + "eslint-plugin-react": "^7.12.4", + "eslint-plugin-standard": "^4.0.0", "file-loader": "^1.1.11", "mini-css-extract-plugin": "^0.4.0", "optimize-css-assets-webpack-plugin": "^4.0.2", @@ -55,6 +68,7 @@ "webpack-cli": "^2.1.2", "webpack-dev-middleware": "^3.1.3", "webpack-hot-middleware": "^2.18.0", - "webpack-manifest-plugin": "^2.0.3" + "webpack-manifest-plugin": "^2.0.4", + "webpack-node-externals": "^1.7.2" } } diff --git a/postcss.config.js b/postcss.config.js index f053ebf..4ba52ba 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1 +1 @@ -module.exports = {}; +module.exports = {} diff --git a/src/app-client.js b/src/app-client.js index a194113..6694f77 100644 --- a/src/app-client.js +++ b/src/app-client.js @@ -1,17 +1,11 @@ -import React from 'react'; -import {render} from 'react-dom'; -import {BrowserRouter as Router} from 'react-router-dom'; -import {App} from './components'; +import React from 'react' +import { hydrate } from 'react-dom' +import { BrowserRouter as Router } from 'react-router-dom' +import { App } from './components' -const AppClient = () => ( +hydrate( - - + + , + document.getElementById('root') ) - -window.onload = () => { - render( - , - document.getElementById('root') - ); -}; diff --git a/src/components/About.js b/src/components/About.js index 8d14d90..bcd3f4d 100644 --- a/src/components/About.js +++ b/src/components/About.js @@ -1,24 +1,32 @@ -import React, {Component} from 'react'; -import {Spinner, Header} from '.'; -import '../static/stylesheets/globals.scss'; -import styles from './About.scss'; -import contentStyle from '../static/stylesheets/content.scss'; +import PropTypes from 'prop-types' +import React, { Component } from 'react' +import { Spinner, Header } from '.' +import '../static/stylesheets/globals.scss' +import contentStyle from '../static/stylesheets/content.scss' +import MarkdownIt from 'markdown-it' export default class About extends Component { + static propTypes = { + isLoading: PropTypes.bool.isRequired, + about: PropTypes.string.isRequired + } render () { + const md = MarkdownIt() + const result = md.render(this.props.about) + if (this.props.isLoading) { return (
- ); + ) } return (
-
-
+
+
) diff --git a/src/components/App.js b/src/components/App.js index 316d82b..1c49409 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -1,16 +1,26 @@ -import React from 'react'; -import { Route, Switch } from 'react-router-dom'; -import { Home, NotFoundWrapper } from '.'; -import { MainContainer, PostContainer } from '../containers'; +import { NotFoundWrapper } from '.' +import React, { Component } from 'react' +import routes from '../utils/routes' +import { Route, Switch } from 'react-router-dom' -export const App = () => ( -
- - - - - -
-); - -export default App; +export default class App extends Component { + render () { + return ( +
+ + {routes.map(({ path, exact, component: C, ...rest }) => ( + ( + + )} + /> + ))} + } /> + +
+ ) + } +} diff --git a/src/components/Blog.js b/src/components/Blog.js index 42eb365..d5ff2b6 100644 --- a/src/components/Blog.js +++ b/src/components/Blog.js @@ -1,21 +1,29 @@ -import React, {Component} from 'react'; -import {Spinner, Header} from '.'; -import '../static/stylesheets/globals.scss'; -import styles from './Blog.scss'; -import contentStyle from '../static/stylesheets/content.scss'; +import PropTypes from 'prop-types' +import React, { Component } from 'react' +import { Spinner, Header } from '.' +import '../static/stylesheets/globals.scss' +import styles from './Blog.scss' +import contentStyle from '../static/stylesheets/content.scss' export default class Blog extends Component { + static propTypes = { + isLoading: PropTypes.bool.isRequired, + posts: PropTypes.arrayOf(PropTypes.object).isRequired + } - render() { + render () { if (this.props.isLoading) { return (
- ); + ) } - let posts = this.props.posts.map((post) => + let posts = this.props.posts.sort((a, b) => { + return new Date(b.published) - new Date(a.published) + }) + let postsHTML = posts.map((post) => {post.published} @@ -28,17 +36,17 @@ export default class Blog extends Component { return (
-
+
- {posts} + {postsHTML}
- ); + ) } }; diff --git a/src/components/Home.js b/src/components/Home.js index 025255f..084608e 100644 --- a/src/components/Home.js +++ b/src/components/Home.js @@ -1,14 +1,13 @@ -import React, { Component } from 'react'; -import { Link } from 'react-router-dom'; -import config from '../../config.json'; -import '../static/stylesheets/globals.scss'; -import styles from './Home.scss'; +import React, { Component } from 'react' +import { Link } from 'react-router-dom' +import config from '../../config.json' +import '../static/stylesheets/globals.scss' +import styles from './Home.scss' export default class Home extends Component { - - render() { - let key = 0; - const objKeys = Object.keys(config.social); + render () { + let key = 0 + const objKeys = Object.keys(config.social) const socialLinks = objKeys.map((val) => { const link = ( @@ -16,17 +15,17 @@ export default class Home extends Component {