diff --git a/.babelrc b/.babelrc index 79727f0..b88334d 100644 --- a/.babelrc +++ b/.babelrc @@ -8,25 +8,23 @@ ], "plugins": [ "transform-decorators-legacy", - "react-hot-loader/babel", "transform-regenerator" ] }, "client": { "presets": [ - "es2015-webpack", + "es2015", "react" ], "plugins": [ - "transform-decorators-legacy", - "react-hot-loader/babel" + "transform-decorators-legacy" ] }, "client-build": { "presets": [ - "es2015-webpack", + "es2015", "react" ], "plugins": [ diff --git a/nodemon.json b/nodemon.json index 48e9a5d..258d5be 100644 --- a/nodemon.json +++ b/nodemon.json @@ -6,7 +6,8 @@ ], "verbose": true, "watch": [ - "server/" + "src/server/", + "src/express-server/" ], "ext": "js json" } \ No newline at end of file diff --git a/package.json b/package.json index a42eb99..bebc2ea 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node ./src/server/babel-server.js", - "build": "cross-env BABEL_ENV=client-build webpack --config webpack.config.client.js --env.prod", + "build": "cross-env NODE_ENV=production BABEL_ENV=client-build webpack --config webpack.config.client.js", "dev": "cross-env NODE_ENV=development nodemon ./src/server/babel-server.js" }, "author": "Paul Myburgh", @@ -14,6 +14,7 @@ "dependencies": { "babel-register": "^6.11.6", "bluebird": "^3.4.1", + "express": "^4.14.0", "koa": "^2.0.0-alpha.4", "koa-compose": "^3.1.0", "koa-compress": "^2.0.0", @@ -25,6 +26,7 @@ "koa-static": "^3.0.0", "mobx": "^2.4.1", "mobx-react": "^3.5.3", + "morgan": "^1.7.0", "react": "^15.3.0", "react-dom": "^15.3.0" }, @@ -36,14 +38,17 @@ "babel-plugin-transform-regenerator": "^6.11.4", "babel-polyfill": "^6.9.1", "babel-preset-es2015": "^6.9.0", + "babel-preset-es2015-native-modules": "^6.9.3", "babel-preset-es2015-webpack": "^6.4.2", "babel-preset-react": "^6.11.1", + "babel-preset-react-hmre": "^1.1.1", "babel-preset-stage-0": "^6.5.0", "babel-preset-stage-3": "^6.11.0", "cross-env": "^2.0.0", "json-loader": "^0.5.4", "koa-webpack-middleware": "^1.0.1", - "react-hot-loader": "^3.0.0-beta.1", - "webpack": "^2.1.0-beta.20" + "webpack": "^1.13.1", + "webpack-dev-middleware": "^1.6.1", + "webpack-hot-middleware": "^2.12.2" } } diff --git a/src/crossover/entry.js b/src/crossover/entry.js index 3fe4d21..e1b36ea 100644 --- a/src/crossover/entry.js +++ b/src/crossover/entry.js @@ -1,6 +1,5 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { AppContainer } from 'react-hot-loader'; import App from '../client/react/App'; /* @@ -10,9 +9,7 @@ import App from '../client/react/App'; export function baseReact(options) { return ( - - - + ); } diff --git a/src/express-server/babel-server.js b/src/express-server/babel-server.js new file mode 100644 index 0000000..57ad0bb --- /dev/null +++ b/src/express-server/babel-server.js @@ -0,0 +1,4 @@ +process.env.BABEL_ENV = "server"; + +require('babel-register'); +require('./server'); \ No newline at end of file diff --git a/src/express-server/server.js b/src/express-server/server.js new file mode 100644 index 0000000..29cd264 --- /dev/null +++ b/src/express-server/server.js @@ -0,0 +1,45 @@ +import express from 'express'; +import morgan from 'morgan'; + +import { renderToString } from 'react-dom/server'; +import { baseReact } from '../crossover/entry'; + +const app = express(); + +app.use(morgan('combined')); + +if (process.env.NODE_ENV === "development") { + console.log("development environment, starting HMR"); + + const webpack = require('webpack'); + const config = require('../../webpack.config.client'); + + const compiler = webpack(config); + + app.use(require('webpack-dev-middleware')(compiler, { + noInfo: true, + publicPath: config.output.publicPath + })); + + app.use(require('webpack-hot-middleware')(compiler)); +} + +app.get('/*', (req, res) => { + const html = renderToString( + baseReact() + ); + + res.render('base', { + html, + initialState: { + what: "what", + }, + }); +}); + +app.set('views', './src/server/views'); +app.set('view engine', 'pug'); + +const server = app.listen(3000, () => { + console.log(`App listening at ${server.address().address}:${server.address().port}`); +}) \ No newline at end of file diff --git a/src/server/middleware/basicMiddleware.js b/src/server/middleware/basicMiddleware.js index b4093d4..0e5beff 100644 --- a/src/server/middleware/basicMiddleware.js +++ b/src/server/middleware/basicMiddleware.js @@ -37,7 +37,10 @@ export function serveStaticFiles() { export function developmentMiddleware() { console.log("Development environment, starting HMR"); - const devConfigBuilt = devConfig({ env: { prod: false } }); + // FOR WEBPACK v2 + // const devConfigBuilt = devConfig({ env: { prod: false } }); + + const devConfigBuilt = devConfig; const compile = webpack(devConfigBuilt); // console.dir(devConfigBuilt); diff --git a/src/server/server.js b/src/server/server.js index 0f3afbd..dc313a2 100644 --- a/src/server/server.js +++ b/src/server/server.js @@ -25,7 +25,7 @@ pug.use(app); app.use(serverLogging()); app.use(baseErrorHandling()); -if (prod) app.use(compressResponse()); +// if (prod) app.use(compressResponse()); app.use(serveStaticFiles()); app.use(route.get('/', renderReact())); diff --git a/webpack.config.client.js b/webpack.config.client.js index 128eac1..e277530 100644 --- a/webpack.config.client.js +++ b/webpack.config.client.js @@ -1,70 +1,73 @@ const { join } = require('path'); const webpack = require('webpack'); -module.exports = (env) => { - console.log("Compiling client code with env set", env); +const prod = process.env.NODE_ENV === "production"; +console.log(`Compiling client code with production set (${prod})`); - return ({ - entry: !env.prod ? ( - ['react-hot-loader/patch', 'webpack-hot-middleware/client', './src/crossover/entry.js'] - ) : ( - { - js: './src/crossover/entry.js', - vendor: ['react', 'react-dom'], - } - ), - target: 'web', - output: { - path: join(__dirname, 'dist'), - filename: 'bundle.js', - pathInfo: !env.prod, - publicPath: '/dist/', - }, - devtool: env.prod ? 'source-map' : 'eval', - module: { - loaders: [ - { - test: /\.(jsx?)$/, - exclude: /node_modules/, - loaders: [ - 'babel-loader', - ], - }, - ], - }, - plugins: !env.prod ? ([ - new webpack.HotModuleReplacementPlugin(), - new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: JSON.stringify('development'), - BABEL_ENV: JSON.stringify('client'), - }, - }), - ]) : ([ - new webpack.optimize.CommonsChunkPlugin({ - name: 'vendor', - minChunks: Infinity, - filename: 'vendor.bundle.js', - }), - new webpack.LoaderOptionsPlugin({ - minimize: true, - debug: true, - }), - new webpack.optimize.UglifyJsPlugin({ - compress: { - warnings: false, - }, - output: { - comments: false, - }, - sourceMap: false, - }), - new webpack.DefinePlugin({ - 'process.env': { - NODE_ENV: JSON.stringify('production'), - BABEL_ENV: JSON.stringify('client-build'), - }, - }), - ]), - }); -}; +module.exports = { + entry: !prod ? ( + ['webpack-hot-middleware/client', './src/crossover/entry.js'] + ) : ( + { + js: './src/crossover/entry.js', + vendor: ['react', 'react-dom'], + } + ), + target: 'web', + output: { + path: join(__dirname, 'dist'), + filename: 'bundle.js', + pathInfo: !prod, + publicPath: '/dist/', + }, + devtool: prod ? 'source-map' : 'eval', + module: { + loaders: [prod ? + { + test: /\.(jsx?)$/, + exclude: /node_modules/, + loaders: [ + 'babel-loader', + ], + } : { + test: /\.(jsx?)$/, + loader: 'babel', + exclude: /node_modules/, + include: __dirname, + query: { + presets: ['react-hmre'] + } + }, + ], + }, + plugins: !prod ? ([ + new webpack.HotModuleReplacementPlugin(), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('development'), + BABEL_ENV: JSON.stringify('client'), + }, + }), + ]) : ([ + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks: Infinity, + filename: 'vendor.bundle.js', + }), + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false, + }, + output: { + comments: false, + }, + sourceMap: false, + }), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('production'), + BABEL_ENV: JSON.stringify('client-build'), + }, + }), + ]), +} diff --git a/webpackv2.config.client.js b/webpackv2.config.client.js new file mode 100644 index 0000000..128eac1 --- /dev/null +++ b/webpackv2.config.client.js @@ -0,0 +1,70 @@ +const { join } = require('path'); +const webpack = require('webpack'); + +module.exports = (env) => { + console.log("Compiling client code with env set", env); + + return ({ + entry: !env.prod ? ( + ['react-hot-loader/patch', 'webpack-hot-middleware/client', './src/crossover/entry.js'] + ) : ( + { + js: './src/crossover/entry.js', + vendor: ['react', 'react-dom'], + } + ), + target: 'web', + output: { + path: join(__dirname, 'dist'), + filename: 'bundle.js', + pathInfo: !env.prod, + publicPath: '/dist/', + }, + devtool: env.prod ? 'source-map' : 'eval', + module: { + loaders: [ + { + test: /\.(jsx?)$/, + exclude: /node_modules/, + loaders: [ + 'babel-loader', + ], + }, + ], + }, + plugins: !env.prod ? ([ + new webpack.HotModuleReplacementPlugin(), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('development'), + BABEL_ENV: JSON.stringify('client'), + }, + }), + ]) : ([ + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + minChunks: Infinity, + filename: 'vendor.bundle.js', + }), + new webpack.LoaderOptionsPlugin({ + minimize: true, + debug: true, + }), + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false, + }, + output: { + comments: false, + }, + sourceMap: false, + }), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('production'), + BABEL_ENV: JSON.stringify('client-build'), + }, + }), + ]), + }); +};