UNPKG

reactatouille

Version:

Reactatouille is a command-line tool to help quickly start and build a new React project, using Redux, Webpack, Gulp (You can add your own tasks, yo!), HMR/Hot Module Reload, Sass (architecture best practices), Jest, Enzyme, popmotion, Redux devtools (bro

139 lines (122 loc) 3.64 kB
import express from 'express' import path from 'path' import axios from 'axios' import chalk from 'chalk' import React from 'react' import { renderToString } from 'react-dom/server' import { StaticRouter } from 'react-router' import configureStore from '../root/store' import { Provider } from 'react-redux' import App from '../modules/main/containers/App' import Routes from '../root/routes' const config = require('config') const mainModuleChildRoutes = Routes[0].routes const app = express() const port = config.defaultPort const rootDir = path.resolve(__dirname, '../../../') const dist = path.join(rootDir, 'dist/' + process.env.NODE_ENV) const webpack = require('webpack') const webpackHotMiddleware = require('webpack-hot-middleware') const webpackDevConfig = require('../../../config/webpack.dev.config') const compiler = webpack(require('../../../config/webpack.dev.config')) const webpackDevMiddleware = require('webpack-dev-middleware') const webpackAssets = require('../../../config/webpack-assets.json') let serverInstance /** * Process error handling */ process.on('uncaughtException', (err) => { throw err }) process.on('SIGINT', () => { serverInstance.close() process.exit(0) }) app.set('views', path.join(rootDir, 'src')) app.set('view engine', 'ejs') app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: webpackDevConfig.output.publicPath, stats: { colors: true, hash: false, version: true, timings: false, assets: false, chunks: false, modules: false, reasons: false, children: false, source: false, errors: true, errorDetails: true, warnings: true, publicPath: false } })) app.use(webpackHotMiddleware(compiler, { log: console.log })) /** * The Cross origin resource sharing rules */ app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', '*') res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE') res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type') res.setHeader('Access-Control-Allow-Credentials', true) next() }) /** * Health check */ app.use('/healthcheck', (req, res) => { res.json({ 'env': { 'NODE_ENV': process.env.NODE_ENV } }) res.end() }) app.use('/api/test', (req, res) => { const URL = 'https://jsonip.com/' axios({ method: 'get', url: URL, responseType: 'json' }) .then((response) => res.send(response.data)) }) app.use('/', express.static(dist)) app.get('*', (req, res) => { const isRoute = mainModuleChildRoutes.find(route => route.path === req.url) if (!isRoute) { res.status(404).send('Not found') } else { const preloadedState = {} // Create a new Redux store instance const store = configureStore(preloadedState) // Render the component to a string const mainHtml = renderToString(<StaticRouter context={{}} location={req.url}> <Provider store={store}> <App routes={mainModuleChildRoutes} /> </Provider> </StaticRouter>) // Grab the initial state from our Redux store const finalState = store.getState() res.render('index', { app: mainHtml, state: JSON.stringify(finalState).replace(/</g, '\\x3c'), bundle: webpackAssets.main.js, vendors: '/assets/js/vendors.dll.js', build: config.buildName, css: '/assets/css/main.min.css' }) } }) serverInstance = app.listen(port, (error) => { if (error) { console.log(error) // eslint-disable-line no-console } console.log(chalk.green('[' + config.buildName + '] listening on port ' + port + '!')) })