Skip to content
This repository has been archived by the owner on Jun 3, 2019. It is now read-only.

Commit

Permalink
Colors to chalk (#512)
Browse files Browse the repository at this point in the history
* Minor readme updates (#501)

* Update Webpack version

* Update Webpack version

* Fix acronym

* Fix markdown formatting.

* Update that redux branch does not have Flow

* Add 'Who is using it' section in the README

As per @ctrlplusb’s comment here:
#437 (comment)
98854669

* Server logging enhancements (#508)

* Improving logging experience + consolidating to single log function

* Adding pretty-error for more readable node error stack

* Fix eslint error

* Logging requests received

* Re-commit logging requests received

* Replacing colors with chalk
  • Loading branch information
oyeanuj authored and Steven Truesdell committed Oct 11, 2017
1 parent 1d4164f commit f6fab53
Show file tree
Hide file tree
Showing 13 changed files with 6,922 additions and 32 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ This starter kit contains all the build tooling and configuration you need to ki
- 🌍 Server Side Rendering.
- 😎 Progressive Web Application ready, with offline support, via a Service Worker.
- 🐘 Long term browser caching of assets with automated cache invalidation.
- 📦 All source is bundled using Webpack v2.
- 📦 All source is bundled using Webpack v3.
- 🚀 Full ES2017+ support - use the exact same JS syntax across the entire project. No more folder context switching! We also only use syntax that is stage-3 or later in the TC39 process.
- 🔧 Centralised application configuration with helpers to avoid boilerplate in your code. Also has support for environment specific configuration files.
- 🔥 Extreme live development - hot reloading of ALL changes to client/server source, with auto development server restarts when your application configuration changes. All this with a high level of error tolerance and verbose logging to the console.
Expand Down Expand Up @@ -61,6 +61,10 @@ Now go make some changes to the `Home` component to see the tooling in action.
- [Deploy your very own Server Side Rendering React App in 5 easy steps](/internal/docs/DEPLOY_TO_NOW.md)
- [Changelog](/CHANGELOG.md)

## Who's using it and where?

You can see who is using it and how in [the comments here](https://github.com/ctrlplusb/react-universally/issues/437). Feel free to add to that telling us how you are using it, we'd love to hear from you.

## Contributors

Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
Expand Down
9 changes: 7 additions & 2 deletions config/utils/envVars.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
*/

import appRootDir from 'app-root-dir';
import colors from 'colors/safe';
import dotenv from 'dotenv';
import fs from 'fs';
import path from 'path';

import ifElse from '../../shared/utils/logic/ifElse';
import removeNil from '../../shared/utils/arrays/removeNil';

import { log } from '../../internal/utils';

// PRIVATES

function registerEnvFile() {
Expand All @@ -40,7 +41,11 @@ function registerEnvFile() {
// If we found an env file match the register it.
if (envFilePath) {
// eslint-disable-next-line no-console
console.log(colors.bgBlue.white(`==> Registering environment variables from: ${envFilePath}`));
log({
title: 'server',
level: 'special',
message: `Registering environment variables from: ${envFilePath}`,
});
dotenv.config({ path: envFilePath });
}
}
Expand Down
17 changes: 13 additions & 4 deletions internal/development/createVendorDLL.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ function createVendorDLL(bundleName, bundleConfig) {
log({
title: 'vendorDLL',
level: 'info',
message: `Vendor DLL build complete. The following dependencies have been included:\n\t-${devDLLDependencies.join('\n\t-')}\n`,
message: `Vendor DLL build complete. The following dependencies have been included:\n\t-${devDLLDependencies.join(
'\n\t-',
)}\n`,
});

const webpackConfig = webpackConfigFactory();
Expand All @@ -83,9 +85,14 @@ function createVendorDLL(bundleName, bundleConfig) {
title: 'vendorDLL',
level: 'warn',
message: `Generating a new "${bundleName}" Vendor DLL for boosted development performance.
The Vendor DLL helps to speed up your development workflow by reducing Webpack build times. It does this by seperating Vendor DLLs from your primary bundles, thereby allowing Webpack to ignore them when having to rebuild your code for changes. We recommend that you add all your client bundle specific dependencies to the Vendor DLL configuration (within /config).`,
The Vendor DLL helps to speed up your development workflow by reducing Webpack build times. It does this by seperating Vendor DLLs from your primary bundles, thereby allowing Webpack to ignore them when having to rebuild your code for changes.
We recommend that you add all your client bundle specific dependencies to the Vendor DLL configuration (within /config).`,
});
buildVendorDLL().then(resolve).catch(reject);
buildVendorDLL()
.then(resolve)
.catch(reject);
} else {
// first check if the md5 hashes match
const dependenciesHash = fs.readFileSync(vendorDLLHashFilePath, 'utf8');
Expand All @@ -97,7 +104,9 @@ The Vendor DLL helps to speed up your development workflow by reducing Webpack b
level: 'warn',
message: `New "${bundleName}" vendor dependencies detected. Regenerating the vendor dll...`,
});
buildVendorDLL().then(resolve).catch(reject);
buildVendorDLL()
.then(resolve)
.catch(reject);
} else {
log({
title: 'vendorDLL',
Expand Down
2 changes: 1 addition & 1 deletion internal/docs/FEATURE_BRANCHES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Below are a list of extensions to this repository, in the form of branches. Eac
- [`apollo`](https://github.com/ctrlplusb/react-universally/tree/feature/apollo) - Adds the Apollo Stack (i.e. Graphql).
- [`mobx`](https://github.com/andreyluiz/react-universally/tree/feature/mobx) - Adds MobX as a state management library.
- [`postcss-sass`](https://github.com/ctrlplusb/react-universally/tree/feature/postcss-sass) - Adds PostCSS and SASS.
- [`redux-opinionated`](https://github.com/ctrlplusb/react-universally/tree/feature/redux-opinionated) - Adds an opinionated Redux implementation, using `redux-thunk` and `react-jobs` to support data loading across the client/server. It also merges in the `flow` feature branch.
- [`redux-opinionated`](https://github.com/ctrlplusb/react-universally/tree/feature/redux-opinionated) - Adds an opinionated Redux implementation, using `redux-thunk` and `react-jobs` to support data loading across the client/server.

If you would like to add a new feature branch log an issue describing your chosen technology and we can come up with a plan together. :)

Expand Down
8 changes: 4 additions & 4 deletions internal/docs/PKG_SCRIPTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

## `npm run analyze:client`

Creates an 'webpack-bundle-analyze' session against the production build of the client bundle.
Creates an `webpack-bundle-analyze` session against the production build of the client bundle.

## `npm run analyze:server`

Creates an 'webpack-bundle-analyze' session against the production build of the server bundle.
Creates an `webpack-bundle-analyze` session against the production build of the server bundle.

## `npm run build`

Expand Down Expand Up @@ -43,10 +43,10 @@ Executes `eslint` against the project. Alternatively you could look to install t

Executes the server. It expects you to have already built the bundles using the `npm run build` command.

## `npm run test`
## `npm run test`

Runs the `jest` tests.

## `npm run test:coverage`
## `npm run test:coverage`

Runs the `jest` tests and generates a coverage report. I recommend you look at [codecov.io](https://codecov.io) to host your coverage reports.
4 changes: 2 additions & 2 deletions internal/docs/PROJECT_OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

Below is a general overview of the project.

## TOC
## ToC

- [Bundled by Webpack](#bundled-by-webpack)
- [Transpiled by Babel](#transpiled-by-babel)
Expand All @@ -18,7 +18,7 @@ Below is a general overview of the project.

## Bundled by Webpack

This starter uses Webpack 2 to produce bundles for both the client and the server. The `internal/webpack/configFactory.js` is used to generate the respective Webpack configuration for all our bundles. The factory is heavily commented to help you understand what is going on within the Webpack configuration.
This starter uses Webpack 3 to produce bundles for both the client and the server. The `internal/webpack/configFactory.js` is used to generate the respective Webpack configuration for all our bundles. The factory is heavily commented to help you understand what is going on within the Webpack configuration.

> Note: Given that we are bundling our server code I have included the `source-map-support` module to ensure that we still get nice stack traces when executing our code.
Expand Down
13 changes: 8 additions & 5 deletions internal/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os from 'os';
import HappyPack from 'happypack';
import notifier from 'node-notifier';
import colors from 'colors/safe';
import chalk from 'chalk';
import { execSync } from 'child_process';
import appRootDir from 'app-root-dir';

Expand Down Expand Up @@ -31,18 +31,21 @@ export function log(options) {
}

const level = options.level || 'info';
const msg = `==> ${title} -> ${options.message}`;
const msg = `${title}: ${options.message}`;

switch (level) {
case 'warn':
console.log(colors.yellow(msg));
console.log(chalk.yellowBright(msg));
break;
case 'error':
console.log(colors.bgRed.white(msg));
console.log(chalk.bgRed.white.bold(msg));
break;
case 'special':
console.log(chalk.italic.cyanBright(msg));
break;
case 'info':
default:
console.log(colors.green(msg));
console.log(chalk.gray(msg));
}
}

Expand Down
10 changes: 6 additions & 4 deletions internal/webpack/configFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import path from 'path';
import webpack from 'webpack';
import WebpackMd5Hash from 'webpack-md5-hash';

import { happyPackPlugin } from '../utils';
import { happyPackPlugin, log } from '../utils';
import { ifElse } from '../../shared/utils/logic';
import { mergeDeep } from '../../shared/utils/objects';
import { removeNil } from '../../shared/utils/arrays';
Expand Down Expand Up @@ -44,11 +44,13 @@ export default function webpackConfigFactory(buildOptions) {
const ifDevClient = ifElse(isDev && isClient);
const ifProdClient = ifElse(isProd && isClient);

console.log(
`==> Creating ${isProd
log({
level: 'info',
title: 'Webpack',
message: `Creating ${isProd
? 'an optimised'
: 'a development'} bundle configuration for the "${target}"`,
);
});

const bundleConfig =
isServer || isClient
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
"homepage": "https://github.com/ctrlplusb/react-universally#readme",
"dependencies": {
"app-root-dir": "1.0.2",
"colors": "1.1.2",
"compression": "1.7.1",
"cross-env": "5.0.5",
"dotenv": "4.0.0",
Expand All @@ -69,6 +68,7 @@
"modernizr": "3.5.0",
"normalize.css": "7.0.0",
"offline-plugin": "4.8.4",
"pretty-error": "2.1.1",
"prop-types": "15.6.0",
"raf": "3.4.0",
"react": "16.0.0",
Expand All @@ -95,6 +95,7 @@
"babel-preset-react": "6.24.1",
"babel-preset-stage-3": "6.24.1",
"babel-template": "6.26.0",
"chalk": "2.1.0",
"chokidar": "1.7.0",
"css-loader": "0.28.7",
"enzyme": "3.1.0",
Expand Down
35 changes: 33 additions & 2 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import serviceWorker from './middleware/serviceWorker';
import offlinePage from './middleware/offlinePage';
import errorHandlers from './middleware/errorHandlers';
import config from '../config';
import { log } from '../internal/utils';

// Create our express based server.
const app = express();
Expand Down Expand Up @@ -43,14 +44,44 @@ app.use(config('bundles.client.webPath'), clientBundle);
app.use(express.static(pathResolve(appRootDir.get(), config('publicAssetsPath'))));

// The React application middleware.
app.get('*', reactApplication);
app.get('*', (request, response) => {
log({
title: 'Request',
level: 'special',
message: `Received for "${request.url}"`,
});

return reactApplication(request, response);
});

// Error Handler middlewares.
app.use(...errorHandlers);

// Create an http listener for our express app.
const listener = app.listen(config('port'), () =>
console.log(`Server listening on port ${config('port')}`));
log({
title: 'server',
level: 'special',
message: `✓
${config('welcomeMessage')}
${config('htmlPage.defaultTitle')} is ready!
with
Service Workers: ${config('serviceWorker.enabled')}
Polyfills: ${config('polyfillIO.enabled')} (${config('polyfillIO.features').join(', ')})
Server is now listening on Port ${config('port')}
You can access it in the browser at http://${config('host')}/${config('port')}
Press Ctrl-C to stop.
`,
}),
);

// We export the listener as it will be handy for our development hot reloader,
// or for exposing a general extension layer for application customisations.
Expand Down
13 changes: 11 additions & 2 deletions server/middleware/errorHandlers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
/* eslint-disable no-console */
/* eslint-disable no-unused-vars */

const prettyError = require('pretty-error').start();

// Configure prettyError to simplify the stack trace:

// skip events.js and http.js and similar core node files
prettyError.skipNodeFiles();

// skip all the trace lines about express` core and sub-modules
prettyError.skipPackage('express');

const errorHandlersMiddleware = [
/**
* 404 errors middleware.
Expand All @@ -21,8 +31,7 @@ const errorHandlersMiddleware = [
*/
function unexpectedErrorMiddleware(err, req, res, next) {
if (err) {
console.log(err);
console.log(err.stack);
console.log(prettyError.render(err));
}
res.status(500).send('Sorry, an unexpected error occurred.');
},
Expand Down
13 changes: 9 additions & 4 deletions server/middleware/reactApplication/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import config from '../../../config';

import ServerHTML from './ServerHTML';
import DemoApp from '../../../shared/components/DemoApp';
import { log } from '../../../internal/utils';

/**
* React application middleware, supports server side rendering.
Expand All @@ -26,7 +27,11 @@ export default function reactApplicationMiddleware(request, response) {
if (config('disableSSR')) {
if (process.env.BUILD_FLAG_IS_DEV === 'true') {
// eslint-disable-next-line no-console
console.log('==> Handling react route without SSR');
log({
title: 'Server',
level: 'info',
message: `Handling react route without SSR: ${request.url}`,
});
}
// SSR is disabled so we will return an "empty" html page and
// rely on the client to initialize and render the react application.
Expand Down Expand Up @@ -78,10 +83,10 @@ export default function reactApplicationMiddleware(request, response) {
.status(
reactRouterContext.missed
? // If the renderResult contains a "missed" match then we set a 404 code.
// Our App component will handle the rendering of an Error404 view.
404
// Our App component will handle the rendering of an Error404 view.
404
: // Otherwise everything is all good and we send a 200 OK status.
200,
200,
)
.send(`<!DOCTYPE html>${html}`);
});
Expand Down
Loading

0 comments on commit f6fab53

Please sign in to comment.