Skip to content

Commit 221b587

Browse files
author
Turbo
committed
Refactor application
1 parent 4681ed9 commit 221b587

38 files changed

+436
-123
lines changed

.eslintrc.js

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ module.exports = {
55
"node": true, //# Node.js global variables and Node.js scoping.
66
},
77

8+
// Specifying global variables
9+
"globals": {
10+
"logInfo": true,
11+
"logWarning": true,
12+
"logError": true,
13+
"logDebug": true,
14+
},
15+
816
"parser": "babel-eslint", // By default, ESLint expects ECMAScript 5 syntax, specify ES6 instead
917

1018
"parserOptions": {

package.json

+6-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
"repository": "",
66
"license": "UNLICENSED",
77
"scripts": {
8+
"license-check": "license-checker --exclude 'MIT, MIT OR X11, BSD, ISC, Public Domain'",
89
"lint": "eslint .",
910
"lint-fix": "eslint . --fix",
10-
"clean-babel-cache": "rimraf -rf ./node_modules/.cache/babel-loader/*",
11+
"clean": "rimraf -rf ./node_modules/.cache/babel-loader/*",
1112
"prod": "NODE_ENV=production node src/server/index.js",
1213
"dev": "NODE_ENV=development nodemon --watch src/server --watch config --inspect src/server/index.js"
1314
},
@@ -34,7 +35,6 @@
3435
"babel-plugin-module-resolver": "^3.1.1",
3536
"babel-plugin-universal-import": "^3.1.2",
3637
"brotli-webpack-plugin": "^1.0.0",
37-
"chalk": "^2.4.1",
3838
"compression-webpack-plugin": "^2.0.0",
3939
"cookie-parser": "^1.4.3",
4040
"express": "^4.16.4",
@@ -43,7 +43,6 @@
4343
"graphql": "^14.0.2",
4444
"graphql-tag": "^2.10.0",
4545
"import": "0.0.6",
46-
"isomorphic-fetch": "^2.2.1",
4746
"isomorphic-unfetch": "^3.0.0",
4847
"markdown-with-front-matter-loader": "^0.1.0",
4948
"node-noop": "^1.0.0",
@@ -67,7 +66,9 @@
6766
"webpack-dev-middleware": "3.4.0",
6867
"webpack-flush-chunks": "^2.0.3",
6968
"webpack-hot-middleware": "2.24.3",
70-
"webpack-hot-server-middleware": "^0.5.0"
69+
"webpack-hot-server-middleware": "^0.5.0",
70+
"winston": "^3.1.0",
71+
"winston-daily-rotate-file": "^3.6.0"
7172
},
7273
"devDependencies": {
7374
"babel-eslint": "^10.0.1",
@@ -80,6 +81,7 @@
8081
"eslint-plugin-jsx-a11y": "^6.1.2",
8182
"eslint-plugin-react": "^7.11.1",
8283
"husky": "^1.2.1",
84+
"license-checker": "^25.0.1",
8385
"lint-staged": "^8.1.0",
8486
"nodemon": "^1.18.9"
8587
},

src/App/AppWrapper.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import { ApolloProvider } from 'react-apollo';
66

77
import theme from 'src/styles/theme';
88
import GlobalizeStyle from 'src/styles/global-styles';
9-
import App from 'src/App';
10-
import apolloClient from 'src/data';
9+
import RouteComponents from 'src/App/RouteComponents';
10+
import apolloClient from 'src/data/ApolloClient';
1111

1212
const AppWrapper = ({ lang }) => (
1313
<ApolloProvider client={apolloClient}>
1414
<ThemeProvider theme={theme}>
1515
<React.Fragment>
1616
<GlobalizeStyle />
17-
<App lang={lang} />
17+
<RouteComponents lang={lang} />
1818
</React.Fragment>
1919
</ThemeProvider>
2020
</ApolloProvider>

src/App/Client.js

+9-20
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,14 @@ import React from 'react';
33
import { BrowserRouter as Router } from 'react-router-dom';
44
import AppWrapper from 'src/App/AppWrapper';
55
import ScrollToTop from 'src/Components/ScrollToTop';
6-
import { getLocaleOnClient } from 'src/i18n/helpers';
6+
import { getLocaleOnClient } from 'src/i18n/utils';
77

8-
/* eslint-disable no-restricted-globals */
9-
export default class extends React.Component {
10-
constructor(props) {
11-
super(props);
12-
this.state = {};
13-
}
8+
const ClientApp = () => (
9+
<Router>
10+
<ScrollToTop>
11+
<AppWrapper lang={getLocaleOnClient(window.location)} />
12+
</ScrollToTop>
13+
</Router>
14+
);
1415

15-
render() {
16-
// Determine current language by name
17-
const currentLang = getLocaleOnClient(location);
18-
19-
return (
20-
<Router>
21-
<ScrollToTop>
22-
<AppWrapper lang={currentLang} />
23-
</ScrollToTop>
24-
</Router>
25-
);
26-
}
27-
}
16+
export default ClientApp;

src/App/index.js renamed to src/App/RouteComponents.js

+11-30
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import Footer from 'src/Components/Footer';
66
import Loading from 'src/Components/Loading';
77
import { RedirectWithStatus } from 'src/Components/SSR';
88

9+
/*
10+
* Create a Universal Component template, allowing SSR a component + Code Splitting
11+
*/
912
const UniversalComponent = universal(props => import(`../Pages/${props.page}`), {
1013
loading: () => <Loading />,
1114
ignoreBabelRename: true,
@@ -16,43 +19,21 @@ export default ({ lang }) => (
1619
<Header lang={lang} />
1720

1821
<Switch>
19-
<Route
20-
exact
21-
path="/:lang"
22-
render={routeProps => <UniversalComponent page="Home" {...routeProps} />}
23-
/>
24-
25-
<Route
26-
exact
27-
path="/:lang/login"
28-
render={routeProps => <UniversalComponent page="Login" {...routeProps} />}
29-
/>
30-
31-
<Route
32-
exact
33-
path="/:lang/books"
34-
render={routeProps => <UniversalComponent page="Books" {...routeProps} />}
35-
/>
36-
37-
<Route
38-
exact
39-
path="/:lang/posts"
40-
render={routeProps => <UniversalComponent page="Posts" {...routeProps} />}
41-
/>
42-
43-
<Route
44-
exact
45-
path="/:lang/posts/:slug"
46-
render={routeProps => <UniversalComponent page="Post" {...routeProps} />}
47-
/>
22+
<Route exact path="/:lang" render={props => <UniversalComponent page="Home" {...props} />} />
23+
<Route exact path="/:lang/login" render={props => <UniversalComponent page="Login" {...props} />} />
24+
25+
<Route exact path="/:lang/books" render={props => <UniversalComponent page="Books" {...props} />} />
26+
27+
<Route exact path="/:lang/posts" render={props => <UniversalComponent page="Posts" {...props} />} />
28+
<Route exact path="/:lang/posts/:slug" render={props => <UniversalComponent page="Post" {...props} />} />
4829

4930
{/* Define Redirect logic if any */}
5031
<RedirectWithStatus httpStatus={301} from="/:lang" to={`/${lang}`} />
5132
<RedirectWithStatus httpStatus={301} from="/:lang/users" to="/" />
5233
<RedirectWithStatus httpStatus={302} from="/:lang/courses" to="/:lang/404" />
5334

5435
{/* If url is not defined, go 404 */}
55-
<Route render={routeProps => <UniversalComponent page="404" {...routeProps} />} />
36+
<Route render={props => <UniversalComponent page="404" {...props} />} />
5637
</Switch>
5738

5839
<Footer />

src/Components/Footer/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Image, Box } from 'rebass';
44
import FlexBox from 'src/Components/FlexBox';
55
import { TextBlock } from 'src/Components/Typo';
66

7-
const imagePath = require('src/assets/images/full-logo.svg');
7+
const imagePath = require('src/static/images/full-logo.svg');
88

99
const BoxWithFooter = Box.withComponent('footer');
1010

src/Components/Head/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import { Helmet } from 'react-helmet';
33
import PropTypes from 'prop-types';
4-
import favicon from 'src/assets/images/favicon.png';
4+
import favicon from 'src/static/images/favicon.png';
55

66
const isProd = process.env.NODE_ENV === 'production';
77

src/Components/Header/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import { Anchor, NavLink } from 'src/Components/Navigation';
33
import PropTypes from 'prop-types';
44

5-
import logo from 'src/assets/images/full-logo.svg';
5+
import logo from 'src/static/images/full-logo.svg';
66

77
import Head from 'src/Components/Head';
88
import FlexBox from 'src/Components/FlexBox';

src/Components/Logger/index.js

-8
This file was deleted.

src/Components/Welcome/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3-
// import icon from 'assets/images/react-icon.png';
3+
// import icon from 'static/images/react-icon.png';
44
import styled from 'styled-components';
55

66
const Component = ({ message, appName }) => (

src/Pages/Books/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Query } from 'react-apollo';
33
import gql from 'graphql-tag';
44
import PropTypes from 'prop-types';
55

6-
import { fetchAllBooks } from 'src/helpers/loadData';
6+
import { fetchAllBooks } from 'src/utils/loadData';
77
import Head from 'src/Components/Head';
88
import FlexBox from 'src/Components/FlexBox';
99
import { H3 } from 'src/Components/Typo';
@@ -31,13 +31,13 @@ class Books extends React.Component {
3131

3232
async componentDidMount() {
3333
if (window.ROUTE_LOADED_DATA) {
34-
// console.log('Data preloaded');
34+
console.log('Data preloaded');
3535
this.setState({
3636
books: window.ROUTE_LOADED_DATA,
3737
});
3838
delete window.ROUTE_LOADED_DATA;
3939
} else {
40-
// console.log('Data not preloaded. Fetching...');
40+
console.log('Data not preloaded. Fetching...');
4141
await fetchAllBooks().then((data) => {
4242
this.setState({
4343
books: data,

src/Pages/Posts/index.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import React from 'react';
22
import { Link } from 'react-router-dom';
33
import PropTypes from 'prop-types';
44

5-
import truncate from 'src/helpers/truncate';
6-
import { fetchAllPosts } from 'src/helpers/loadData';
5+
import truncate from 'src/utils/truncate';
6+
import { fetchAllPosts } from 'src/utils/loadData';
77

88
import FlexBox from 'src/Components/FlexBox';
99
import CardBox from 'src/Components/CardBox';
@@ -24,13 +24,13 @@ class Posts extends React.Component {
2424
const { lang } = this.props.match.params;
2525

2626
if (window.ROUTE_LOADED_DATA) {
27-
// console.log('Data preloaded');
27+
console.log('Data preloaded');
2828
this.setState({
2929
posts: window.ROUTE_LOADED_DATA,
3030
});
3131
delete window.ROUTE_LOADED_DATA;
3232
} else {
33-
// console.log('Data not preloaded. Fetching...');
33+
console.log('Data not preloaded. Fetching...');
3434
await fetchAllPosts().then((data) => {
3535
this.setState({
3636
lang,
File renamed without changes.
File renamed without changes.

src/i18n/helpers/getLocale.js renamed to src/i18n/utils/getLocale.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import getCookie from 'src/helpers/getCookie';
1+
import getCookie from 'src/utils/getCookie';
22
import { LOCALE_DEFAULT, LOCALE_COOKIE_NAME, LOCALE_AVAILABLE } from './constants';
33

44
// Get Locale from request server
File renamed without changes.
File renamed without changes.

src/index.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import React from 'react';
22
import { hydrate } from 'react-dom';
33
import { AppContainer } from 'react-hot-loader';
4-
54
import Client from './App/Client';
65

6+
/*
7+
* Define a render method to make another component wrapped inside
8+
* <AppContainer/> for to allow Hot Loader for development via `hydrate`
9+
* Then render inside a HTML element called #app
10+
*/
711
const render = (Component) => {
812
hydrate(
913
<AppContainer>
@@ -12,12 +16,13 @@ const render = (Component) => {
1216
document.getElementById('app'),
1317
);
1418
};
19+
20+
// By default, render a client
1521
render(Client);
1622

17-
// Enable Hot Module Replacement
18-
if (module.hot) {
19-
module.hot.accept('./App/Client.js', () => {
20-
const NewClient = require('./App/Client.js').default; // eslint-disable-line global-require
21-
render(NewClient);
22-
});
23-
}
23+
/*
24+
* If Hot Module Replacement has been enabled via the HotModuleReplacementPlugin
25+
* Accept update for Client app
26+
* Then render a new Client app with predefined `render` method
27+
*/
28+
if (module.hot) module.hot.accept('./App/Client.js', () => render(Client));

src/routes.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import NotFound404 from 'src/Pages/404';
44
import Posts from 'src/Pages/Posts';
55
import Books from 'src/Pages/Books';
66

7-
import { fetchAllBooks, fetchAllPosts } from 'src/helpers/loadData';
7+
import { fetchAllBooks, fetchAllPosts } from 'src/utils/loadData';
88

99
const routes = lang => [
1010
{ path: `/${lang}/`, exact: true, component: Home },
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/server/bundleSettings/dev.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ import webpackHotServerMiddleware from 'webpack-hot-server-middleware';
44
import configDevClient from 'config/webpack.dev-client';
55
import configDevServer from 'config/webpack.dev-server';
66

7-
import {
8-
log, info,
9-
} from 'src/Components/Logger';
10-
117
/* eslint-disable global-require */
128
const bundleDev = (server, callback) => {
139
const compiler = webpack([configDevClient, configDevServer]);
@@ -29,7 +25,7 @@ const bundleDev = (server, callback) => {
2925
server.use(webpackDevMiddleware);
3026
server.use(webpackHotMiddlware);
3127
server.use(webpackHotServerMiddleware(compiler));
32-
log(info('Middleware enabled'));
28+
console.log('Middleware enabled');
3329
callback();
3430
};
3531

src/server/bundleSettings/prod.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ import expressStaticGzip from 'express-static-gzip';
33

44
import configProdClient from 'config/webpack.prod-client';
55
import configProdServer from 'config/webpack.prod-server';
6-
import { log } from 'src/Components/Logger';
76

87
/* eslint-disable global-require */
98
const bundleProd = (server, callback) => {
109
webpack([configProdClient, configProdServer]).run((err, stats) => {
1110
const clientStats = stats.toJson().children[0];
1211
const render = require('build/server/prod-server-bundle.js').default;
13-
log(stats.toString({ colors: true }));
12+
console.log(stats.toString({ colors: true }));
1413

1514
server.use(expressStaticGzip('build/client', { enableBrotli: true }));
1615
server.use(render({ clientStats }));

src/server/express.js

+3-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import express from 'express';
2+
import 'src/utils/logger';
23
import cookieParser from 'cookie-parser';
3-
4-
import {
5-
log, success,
6-
} from 'src/Components/Logger';
7-
84
import bundleDev from './bundleSettings/dev';
95
import bundleProd from './bundleSettings/prod';
106

@@ -19,14 +15,10 @@ let isBuilt = false;
1915

2016
server.listen(PORT, () => {
2117
isBuilt = true;
22-
log([
23-
'Server listening on ',
24-
`${success(`http://localhost:${PORT}`)} in `,
25-
`${success(process.env.NODE_ENV)} 🌎...`,
26-
].join(''));
18+
logInfo(`Server listening on http://localhost:${PORT} ${process.env.NODE_ENV}`);
2719
});
2820

29-
const done = () => !isBuilt && log(success('App is built'));
21+
const done = () => !isBuilt && console.log('App is built');
3022

3123

3224
// If Development environment

0 commit comments

Comments
 (0)