Skip to content

Instantly share code, notes, and snippets.

@raghavgarg1257
Created March 27, 2018 12:08
Show Gist options
  • Save raghavgarg1257/60fbb05410d4ccb86bf9bb13e69f4933 to your computer and use it in GitHub Desktop.
Save raghavgarg1257/60fbb05410d4ccb86bf9bb13e69f4933 to your computer and use it in GitHub Desktop.
React only SSR (for apps using redux we need to do some more things)
// template for wrapping html
import WebpackHash from '../../public/webpack-hash';
export default function(html) {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Spectrum - Real-time AWS monitoring dashboard, built on CloudWatch</title>
<base href="/" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<link rel="shortcut icon" type="image/png" href="${process.env.PUBLIC_URL}/dist/src/assets/images/favicon-ok.png" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
<meta name="description" content="Real-time AWS monitoring dashboard, built on CloudWatch." />
<meta itemprop="name" content="Real-time AWS monitoring dashboard, built on CloudWatch." />
<meta itemprop="description" content="Real-time AWS monitoring dashboard, built on CloudWatch." />
<meta itemprop="image" content="${process.env.PUBLIC_URL}/dist/src/assets/images/facebook-og.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:description" content="Real-time AWS monitoring dashboard, built on CloudWatch." />
<meta name="twitter:image" content="${process.env.PUBLIC_URL}/dist/src/assets/images/twitter-og.png" />
<meta name="twitter:image:alt" content="Real-time AWS monitoring dashboard, built on CloudWatch." />
<meta property="og:title" content="Real-time AWS monitoring dashboard, built on CloudWatch." />
<meta property="og:description" content="Real-time AWS monitoring dashboard, built on CloudWatch." />
<meta property="og:url" content="${process.env.PUBLIC_URL}" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Spectrum" />
<meta property="og:image" content="${process.env.PUBLIC_URL}/dist/src/assets/images/facebook-og.png" />
<meta name="twitter:title" content="Real-time AWS monitoring dashboard, built on CloudWatch." />
<meta name="description" content="Real-time AWS monitoring dashboard, built on CloudWatch." />
<meta name="theme-color" content="#1ebaa2" />
<meta name="full-screen" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="Spectrum" />
<link rel="apple-touch-icon" href="/launcher-icons/ios-254.png" type="image/x-icon" />
<link rel="manifest" href="/manifest.json" />
<link href="/dist/${WebpackHash['main.css']}" rel="stylesheet">
</head>
<body>
<div id="react-container">${html}</div>
<script type="text/javascript" src="/dist/${WebpackHash['main.js']}"></script>
</body>
</html>
`;
}
// server file
import express from "express";
import fs from "fs";
import path from "path";
import cors from "cors";
import React from "react";
import sourceMapSupport from "source-map-support";
import { renderToString } from "react-dom/server";
import { StaticRouter, matchPath } from "react-router-dom";
import Routes from '../routes';
import IndexHTML from './IndexHTML';
if (process.env.NODE_ENV === "development") {
sourceMapSupport.install();
}
const app = express();
app.use(cors());
app.use(express.static(path.resolve(process.cwd(), 'public', process.env.NODE_ENV, 'browser')));
app.get("*", (req, res, next) => {
const content = renderToString(
<StaticRouter location={req.path} context={{}}>
<Routes />
</StaticRouter>
);
console.log("[req.path] ", req.path);
console.log("------------------------------------------[content start]------------------------------------------");
console.log(content);
console.log("-------------------------------------------[content end]-------------------------------------------");
res.header("Content-Type", "text/html");
res.header("Cache-Control", "no-cache, max-age=86400");
res.send(IndexHTML(content));
});
app.listen(process.env.SERVER_PORT || 3000, () => {
console.log("Listening on ", process.env.SERVER_PORT || 3000);
});
{
"main.css": "main-af94b35f1b4c7a1c7c4b.css",
"main.js": "main-af94b35f1b4c7a1c7c4b.js"
}
// webpack config file to bundle the server files
require('dotenv').config();
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const crypto = require('crypto');
const webpackNodeExternals = require('webpack-node-externals');
let plugins = [
new webpack.EnvironmentPlugin([
'NODE_ENV',
'SERVER_PORT',
'BASE_URL',
'APP_URL',
'API_URL',
'PUBLIC_URL',
'DEBUG_CONSOLE'
])
];
if (process.env.NODE_ENV === 'production') {
const optimizeJs = new webpack.optimize.UglifyJsPlugin({
output: { comments: false }
});
plugins = [ ...plugins, optimizeJs ];
}
module.exports = {
target: "node",
// project starting point
entry: {
server: './src/server/index.js',
},
// compiled file properties
output: {
path: path.resolve(__dirname, 'public', process.env.NODE_ENV),
filename: '[name].js',
libraryTarget: "commonjs2"
},
// extra modules used
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['react', 'es2015', 'stage-1']
}
}
},
{
// server
test: /\.css$/,
use: [{ loader: "css-loader/locals" }]
},
{
// server
test: /\.scss$/,
exclude: /node_modules/,
use: [{ loader: "sass-loader/locals" }]
},
{
test: /\.(png|gif|jpe?g)$/,
exclude: /node_modules/,
use: {
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
emitFile: false
}
}
},
{
test: /\.(woff|woff2|eot|ttf|svg|mp3)(\?.*$|$)/,
use: {
loader: 'file-loader',
options: {
name: '[path][name].[ext]',
emitFile: false
}
}
}
]
},
devtool: 'cheap-module-source-map',
plugins: plugins,
externals: [ webpackNodeExternals() ]
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment