diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 745632e5e..000000000 --- a/.babelrc +++ /dev/null @@ -1,10 +0,0 @@ -// NOTE: These options are overriden by the babel-loader configuration -// for webpack, which can be found in ~/build/webpack.config. -// -// Why? The react-transform-hmr plugin depends on HMR (and throws if -// module.hot is disabled), so keeping it and related plugins contained -// within webpack helps prevent unexpected errors. -{ - "presets": ["es2015", "react", "stage-0"], - "plugins": ["transform-runtime"] -} diff --git a/README.md b/README.md index 52797a79e..463336dbd 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![devDependency Status](https://david-dm.org/davezuko/react-redux-starter-kit/dev-status.svg)](https://david-dm.org/davezuko/react-redux-starter-kit#info=devDependencies) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/) -This starter kit is designed to get you up and running with a bunch of awesome new front-end technologies, all on top of a configurable, feature-rich webpack build system that's already setup to provide hot reloading, CSS modules with Sass support, unit testing, code coverage reports, bundle splitting, and a whole lot more. +This starter kit is designed to get you up and running with a bunch of awesome new front-end technologies, all on top of a configurable, feature-rich webpack build system that's already setup to provide hot reloading, CSS preprocessing with Sass, unit testing, code coverage reports, bundle splitting, and more. The primary goal of this project is to remain as **unopinionated** as possible. Its purpose is not to dictate your project structure or to demonstrate a complete sample application, but to provide a set of tools intended to make front-end development robust, easy, and, most importantly, fun. Check out the full feature list below! @@ -40,7 +40,7 @@ Finally, This project wouldn't be possible without the help of our many contribu * [react-router-redux](https://github.com/rackt/react-router-redux) * [webpack](https://github.com/webpack/webpack) * [babel](https://github.com/babel/babel) -* [koa](https://github.com/koajs/koa) +* [express](https://github.com/expressjs/express) * [karma](https://github.com/karma-runner/karma) * [eslint](http://eslint.org) @@ -54,38 +54,14 @@ After confirming that your development environment meets the specified [requirem ### Install from source -First, clone or download: +First, clone the project: ```bash -$ git clone https://github.com/davezuko/react-redux-starter-kit.git -// or -$ wget -O react-redux-starter-kit.zip https://github.com/davezuko/react-redux-starter-kit/archive/master.zip -$ unzip react-redux-starter-kit.zip -``` - -Then, rename to your project name and change into the directory: - -```bash -$ mv react-redux-starter-kit -$ cd -``` - -### Alternatively, install via `redux-cli` - -If not already installed (globally): - -```bash -$ npm i redux-cli -g -``` - -Then, create a new project: - -```bash -$ redux new +$ git clone https://github.com/davezuko/react-redux-starter-kit.git $ cd ``` -### Install dependencies, and check to see it works +Then install dependencies and check to see it works ```bash $ npm install # Install project dependencies @@ -102,7 +78,6 @@ While developing, you will probably rely mostly on `npm start`; however, there a |`start`|Serves your app at `localhost:3000`. HMR will be enabled in development.| |`compile`|Compiles the application to disk (`~/dist` by default).| |`dev`|Same as `npm start`, but enables nodemon for the server as well.| -|`dev:no-debug`|Same as `npm run dev` but disables devtool instrumentation.| |`test`|Runs unit tests with Karma and generates a coverage report.| |`test:dev`|Runs Karma and watches for changes to re-run tests; does not generate coverage reports.| |`deploy`|Runs linter, tests, and then, on success, compiles your application to disk.| @@ -122,13 +97,13 @@ The application structure presented in this boilerplate is **fractal**, where fu ├── build # All build-related configuration │ └── webpack # Environment-specific configuration files for webpack ├── config # Project configuration settings -├── server # Koa application (uses webpack middleware) +├── server # Express application that provides webpack middleware │ └── main.js # Server application entry point ├── src # Application source code │ ├── index.html # Main HTML page container for app │ ├── main.js # Application bootstrap and rendering -│ ├── components # Reusable Presentational Components -│ ├── containers # Reusable Container Components +│ ├── components # Global Reusable Presentational Components +│ ├── containers # Global Reusable Container Components │ ├── layouts # Components that dictate major page structure │ ├── redux # "Ducks" location... │ │ └── modules # reducer, action, creators not part of a route @@ -164,70 +139,17 @@ npm i --save-dev redux-devtools redux-devtools-log-monitor redux-devtools-dock-m Then follow the [manual integration walkthrough](https://github.com/gaearon/redux-devtools/blob/master/docs/Walkthrough.md). -#### `redux-cli` - -```bash -npm install redux-cli --save-dev -``` - ### Routing We use `react-router` [route definitions](https://github.com/reactjs/react-router/blob/master/docs/API.md#plainroute) (`/index.js`) to define units of logic within our application. See the [application structure](#application-structure) section for more information. ## Testing -To add a unit test, simply create a `.spec.js` file anywhere in `~/tests`. Karma will pick up on these files automatically, and Mocha and Chai will be available within your test without the need to import them. If you are using `redux-cli`, test files should automatically be generated when you create a component or redux module. - -Coverage reports will be compiled to `~/coverage` by default. If you wish to change what reporters are used and where reports are compiled, you can do so by modifying `coverage_reporters` in `~/config/index.js`. +To add a unit test, simply create a `.spec.js` file anywhere in `~/tests`. Karma will pick up on these files automatically, and Mocha and Chai will be available within your test without the need to import them. Coverage reports will be compiled to `~/coverage` by default. If you wish to change what reporters are used and where reports are compiled, you can do so by modifying `coverage_reporters` in `~/config/index.js`. ## Deployment Out of the box, this starter kit is deployable by serving the `~/dist` folder generated by `npm run deploy` (make sure to specify your target `NODE_ENV` as well). This project does not concern itself with the details of server-side rendering or API structure, since that demands an opinionated structure that makes it difficult to extend the starter kit. However, if you do need help with more advanced deployment strategies, here are a few tips: ### Static Deployments -If you are serving the application via a web server such as nginx, make sure to direct incoming routes to the root `~/dist/index.html` file and let react-router take care of the rest. If you are unsure of how to do this, you might find [this documentation](https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md#configuring-your-server) helpful. The Koa server that comes with the starter kit is able to be extended to serve as an API or whatever else you need, but that's entirely up to you. - -### Heroku - -Heroku has `nodejs buildpack` script that does the following when you deploy your app to Heroku. -1. Find `packages.json` in the root directory. -2. Install `nodejs` and `npm` packages. -3. Run `npm postinstall script` -4. Run `npm start` - -Therefore, you need to modify `package.json` before deploying to Heroku. Make the following changes in the `scripts` section of `package.json`. - -``` -... -"start": "better-npm-run start:prod", -"serve": "better-npm-run start", -"postinstall": "npm run deploy:prod", -"betterScripts": { - ... - "start:prod": { - "command": "babel-node bin/server", - "env": { - "NODE_ENV": "production" - } - } - ... -}, -``` - -It's also important to tell Heroku to install all `devDependencies` to successfully compile your app on Heroku's environment. Run the following in your terminal. - -```bash -$ heroku config:set NPM_CONFIG_PRODUCTION=false -``` - -With this setup, you will install all the necessray packages, build your app, and start the webserver (e.g. koa) everytime you push your app to Heroku. Try to deploy to Heroku by running the following commands. - -```bash -$ git add . -$ git commit -m 'My awesome commit' -$ git push heroku master -``` - -If you fail to deploy for an unknown reason, try [this helpful comment](https://github.com/davezuko/react-redux-starter-kit/issues/730#issuecomment-213997120) by [DonHansDampf](https://github.com/DonHansDampf) addressing Heroku deployments. - -Have more questions? Feel free to submit an issue or join the Gitter chat! +If you are serving the application via a web server such as nginx, make sure to direct incoming routes to the root `~/dist/index.html` file and let react-router take care of the rest. If you are unsure of how to do this, you might find [this documentation](https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md#configuring-your-server) helpful. The Express server that comes with the starter kit is able to be extended to serve as an API or whatever else you need, but that's entirely up to you. ## Build System @@ -241,13 +163,11 @@ If you need environment-specific overrides (useful for dynamically setting API e |---|-----------| |`dir_src`|application source code base path| |`dir_dist`|path to build compiled application to| -|`server_host`|hostname for the Koa server| -|`server_port`|port for the Koa server| -|`compiler_css_modules`|whether or not to enable CSS modules| +|`server_host`|hostname for the Express server| +|`server_port`|port for the Express server| |`compiler_devtool`|what type of source-maps to generate (set to `false`/`null` to disable)| |`compiler_vendor`|packages to separate into to the vendor bundle| - ### Root Resolve Webpack is configured to make use of [resolve.root](http://webpack.github.io/docs/configuration.html#resolve-root), which lets you import local packages as if you were traversing from the root of your `~/src` directory. Here's an example: @@ -275,11 +195,11 @@ These are global variables available to you anywhere in your source code. If you ### Styles -Both `.scss` and `.css` file extensions are supported out of the box and are configured to use [CSS Modules](https://github.com/css-modules/css-modules). After being imported, styles will be processed with [PostCSS](https://github.com/postcss/postcss) for minification and autoprefixing, and will be extracted to a `.css` file during production builds. +Both `.scss` and `.css` file extensions are supported out of the box. After being imported, styles will be processed with [PostCSS](https://github.com/postcss/postcss) for minification and autoprefixing, and will be extracted to a `.css` file during production builds. ### Server -This starter kit comes packaged with an Koa server. It's important to note that the sole purpose of this server is to provide `webpack-dev-middleware` and `webpack-hot-middleware` for hot module replacement. Using a custom Koa app in place of [webpack-dev-server](https://github.com/webpack/webpack-dev-server) makes it easier to extend the starter kit to include functionality such as API's, universal rendering, and more -- all without bloating the base boilerplate. +This starter kit comes packaged with an Express server. It's important to note that the sole purpose of this server is to provide `webpack-dev-middleware` and `webpack-hot-middleware` for hot module replacement. Using a custom Express app in place of [webpack-dev-server](https://github.com/webpack/webpack-dev-server) makes it easier to extend the starter kit to include functionality such as API's, universal rendering, and more -- all without bloating the base boilerplate. ### Production Optimization diff --git a/bin/compile.js b/bin/compile.js index 76126d498..af5b5a0cf 100644 --- a/bin/compile.js +++ b/bin/compile.js @@ -1,24 +1,29 @@ -import fs from 'fs-extra' -import _debug from 'debug' -import webpackCompiler from '../build/webpack-compiler' -import webpackConfig from '../build/webpack.config' -import config from '../config' +const fs = require('fs-extra') +const debug = require('debug')('app:bin:compile') +const webpackCompiler = require('../build/webpack-compiler') +const webpackConfig = require('../build/webpack.config') +const config = require('../config') -const debug = _debug('app:bin:compile') const paths = config.utils_paths -;(async function () { - try { - debug('Run compiler') - const stats = await webpackCompiler(webpackConfig) - if (stats.warnings.length && config.compiler_fail_on_warning) { - debug('Config set to fail on warning, exiting with status code "1".') +const compile = () => { + debug('Starting compiler.') + return Promise.resolve() + .then(() => webpackCompiler(webpackConfig)) + .then(stats => { + if (stats.warnings.length && config.compiler_fail_on_warning) { + throw new Error('Config set to fail on warning, exiting with status code "1".') + } + debug('Copying static assets to dist folder.') + fs.copySync(paths.client('static'), paths.dist()) + }) + .then(() => { + debug('Compilation completed successfully.') + }) + .catch((err) => { + debug('Compiler encountered an error.', err) process.exit(1) - } - debug('Copy static assets to dist folder.') - fs.copySync(paths.client('static'), paths.dist()) - } catch (e) { - debug('Compiler encountered an error.', e) - process.exit(1) - } -})() + }) +} + +compile() diff --git a/bin/server.js b/bin/server.js index 07f2dae1e..e433d3e94 100644 --- a/bin/server.js +++ b/bin/server.js @@ -1,11 +1,9 @@ -import config from '../config' -import server from '../server/main' -import _debug from 'debug' +const config = require('../config') +const server = require('../server/main') +const debug = require('debug')('app:bin:server') -const debug = _debug('app:bin:server') const port = config.server_port const host = config.server_host server.listen(port) debug(`Server is now running at http://${host}:${port}.`) -debug(`Server accessible via localhost:${port} if you are using the project defaults.`) diff --git a/build/karma.conf.js b/build/karma.conf.js index b6c0c01c0..f20c35851 100644 --- a/build/karma.conf.js +++ b/build/karma.conf.js @@ -1,11 +1,9 @@ -import { argv } from 'yargs' -import config from '../config' -import webpackConfig from './webpack.config' -import _debug from 'debug' - -const debug = _debug('app:karma') -debug('Create configuration.') +const { argv } = require('yargs') +const config = require('../config') +const webpackConfig = require('./webpack.config') +const debug = require('debug')('app:karma') +debug('Creating configuration.') const karmaConfig = { basePath : '../', // project root in relation to bin/karma.js files : [ @@ -25,13 +23,11 @@ const karmaConfig = { browsers : ['PhantomJS'], webpack : { devtool : 'cheap-module-source-map', - resolve : { - ...webpackConfig.resolve, - alias : { - ...webpackConfig.resolve.alias, + resolve : Object.assign({}, webpackConfig.resolve, { + alias : Object.assign({}, webpackConfig.resolve.alias, { sinon : 'sinon/pkg/sinon.js' - } - }, + }) + }), plugins : webpackConfig.plugins, module : { noParse : [ @@ -46,12 +42,11 @@ const karmaConfig = { }, // Enzyme fix, see: // https://github.com/airbnb/enzyme/issues/47 - externals : { - ...webpackConfig.externals, + externals : Object.assign({}, webpackConfig.externals, { 'react/addons' : true, 'react/lib/ExecutionEnvironment' : true, 'react/lib/ReactContext' : 'window' - }, + }), sassLoader : webpackConfig.sassLoader }, webpackMiddleware : { @@ -72,5 +67,4 @@ if (config.globals.__COVERAGE__) { }] } -// cannot use `export default` because of Karma. module.exports = (cfg) => cfg.set(karmaConfig) diff --git a/build/webpack-compiler.js b/build/webpack-compiler.js index 8ec10d631..bc1be466f 100644 --- a/build/webpack-compiler.js +++ b/build/webpack-compiler.js @@ -1,11 +1,10 @@ -import webpack from 'webpack' -import _debug from 'debug' -import config from '../config' +const webpack = require('webpack') +const debug = require('debug')('app:build:webpack-compiler') +const config = require('../config') -const debug = _debug('app:build:webpack-compiler') -const DEFAULT_STATS_FORMAT = config.compiler_stats +function webpackCompiler (webpackConfig, statsFormat) { + statsFormat = statsFormat || config.compiler_stats -export default function webpackCompiler (webpackConfig, statsFormat = DEFAULT_STATS_FORMAT) { return new Promise((resolve, reject) => { const compiler = webpack(webpackConfig) @@ -33,3 +32,5 @@ export default function webpackCompiler (webpackConfig, statsFormat = DEFAULT_ST }) }) } + +module.exports = webpackCompiler diff --git a/build/webpack.config.js b/build/webpack.config.js index 892a744e3..9f2ceb2d8 100644 --- a/build/webpack.config.js +++ b/build/webpack.config.js @@ -1,15 +1,14 @@ -import webpack from 'webpack' -import cssnano from 'cssnano' -import HtmlWebpackPlugin from 'html-webpack-plugin' -import ExtractTextPlugin from 'extract-text-webpack-plugin' -import config from '../config' -import _debug from 'debug' - -const debug = _debug('app:webpack:config') +const webpack = require('webpack') +const cssnano = require('cssnano') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') +const config = require('../config') +const debug = require('debug')('app:webpack:config') + const paths = config.utils_paths const { __DEV__, __PROD__, __TEST__ } = config.globals -debug('Create configuration.') +debug('Creating configuration.') const webpackConfig = { name : 'client', target : 'web', @@ -23,14 +22,12 @@ const webpackConfig = { // ------------------------------------ // Entry Points // ------------------------------------ -const APP_ENTRY_PATHS = [ - paths.client('main.js') -] +const APP_ENTRY = paths.client('main.js') webpackConfig.entry = { app : __DEV__ - ? APP_ENTRY_PATHS.concat(`webpack-hot-middleware/client?path=${config.compiler_public_path}__webpack_hmr`) - : APP_ENTRY_PATHS, + ? [APP_ENTRY].concat(`webpack-hot-middleware/client?path=${config.compiler_public_path}__webpack_hmr`) + : [APP_ENTRY], vendor : config.compiler_vendor } @@ -182,9 +179,10 @@ if (!__DEV__) { webpackConfig.module.loaders.filter((loader) => loader.loaders && loader.loaders.find((name) => /css/.test(name.split('?')[0])) ).forEach((loader) => { - const [first, ...rest] = loader.loaders + const first = loader.loaders[0] + const rest = loader.loaders.slice(1) loader.loader = ExtractTextPlugin.extract(first, rest.join('!')) - Reflect.deleteProperty(loader, 'loaders') + delete loader.loaders }) webpackConfig.plugins.push( @@ -194,4 +192,4 @@ if (!__DEV__) { ) } -export default webpackConfig +module.exports = webpackConfig diff --git a/config/environments.js b/config/environments.js index 413ac0e34..327957a4a 100644 --- a/config/environments.js +++ b/config/environments.js @@ -1,7 +1,7 @@ // Here is where you can define configuration overrides based on the execution environment. // Supply a key to the default export matching the NODE_ENV that you wish to target, and // the base configuration will apply your overrides before exporting itself. -export default { +module.exports = { // ====================================================== // Overrides when NODE_ENV === 'development' // ====================================================== @@ -9,14 +9,7 @@ export default { // are served webpack by to fix this issue: // http://stackoverflow.com/questions/34133808/webpack-ots-parsing-error-loading-fonts/34133809#34133809 development : (config) => ({ - compiler_public_path : `http://${config.server_host}:${config.server_port}/`, - proxy : { - enabled : false, - options : { - host : 'http://localhost:8000', - match : /^\/api\/.*/ - } - } + compiler_public_path : `http://${config.server_host}:${config.server_port}/` }), // ====================================================== diff --git a/config/index.js b/config/index.js index 8d2dea13c..5ad552e0d 100644 --- a/config/index.js +++ b/config/index.js @@ -1,13 +1,10 @@ /* eslint key-spacing:0 spaced-comment:0 */ -import path from 'path' -import _debug from 'debug' -import { argv } from 'yargs' -import ip from 'ip' +const path = require('path') +const debug = require('debug')('app:config') +const { argv } = require('yargs') +const ip = require('ip') -const localip = ip.address() -const debug = _debug('app:config') debug('Creating default configuration.') - // ======================================================== // Default Configuration // ======================================================== @@ -26,7 +23,7 @@ const config = { // ---------------------------------- // Server Configuration // ---------------------------------- - server_host : localip, // use string 'localhost' to prevent exposure on local network + server_host : ip.address(), // use string 'localhost' to prevent exposure on local network server_port : process.env.PORT || 3000, // ---------------------------------- @@ -43,7 +40,6 @@ const config = { colors : true }, compiler_vendor : [ - 'babel-polyfill', 'history', 'react', 'react-redux', @@ -82,7 +78,6 @@ config.globals = { '__DEV__' : config.env === 'development', '__PROD__' : config.env === 'production', '__TEST__' : config.env === 'test', - '__DEBUG__' : config.env === 'development' && !argv.no_debug, '__COVERAGE__' : !argv.watch && config.env === 'test', '__BASENAME__' : JSON.stringify(process.env.BASENAME || '') } @@ -120,7 +115,7 @@ config.utils_paths = { // Environment Configuration // ======================================================== debug(`Looking for environment overrides for NODE_ENV "${config.env}".`) -const environments = require('./environments').default +const environments = require('./environments') const overrides = environments[config.env] if (overrides) { debug('Found overrides, applying to default configuration.') @@ -129,4 +124,4 @@ if (overrides) { debug('No environment overrides found, defaults will be used.') } -export default config +module.exports = config diff --git a/nodemon.json b/nodemon.json deleted file mode 100644 index 9a8f40f34..000000000 --- a/nodemon.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "verbose": false, - "ignore": ["dist", "coverage", "tests", "src"] -} diff --git a/package.json b/package.json index 5e0320fd0..a6ec39628 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "lint:fix": "npm run lint -- --fix", "start": "better-npm-run start", "dev": "better-npm-run dev", - "dev:no-debug": "npm run dev -- --no_debug", "test": "better-npm-run test", "test:dev": "npm run test -- --watch", "deploy": "better-npm-run deploy", @@ -30,7 +29,7 @@ } }, "dev": { - "command": "nodemon --exec babel-node bin/server", + "command": "nodemon --exec babel-node bin/server --ignore dist --ignore coverage --ignore tests --ignore src", "env": { "NODE_ENV": "development", "DEBUG": "app:*" @@ -77,20 +76,19 @@ "author": "David Zukowski (http://zuko.me)", "license": "MIT", "dependencies": { - "babel-cli": "^6.5.1", "babel-core": "^6.14.0", "babel-loader": "^6.2.5", "babel-plugin-transform-runtime": "^6.15.0", - "babel-polyfill": "^6.9.0", "babel-preset-es2015": "^6.14.0", "babel-preset-react": "^6.11.1", "babel-preset-stage-0": "^6.3.13", - "babel-register": "^6.14.0", "babel-runtime": "^6.11.6", "better-npm-run": "0.0.11", + "connect-history-api-fallback": "^1.3.0", "css-loader": "^0.24.0", "cssnano": "^3.7.4", "debug": "^2.2.0", + "express": "^4.14.0", "extract-text-webpack-plugin": "^1.0.0", "file-loader": "^0.9.0", "fs-extra": "^0.30.0", @@ -99,11 +97,6 @@ "imports-loader": "^0.6.5", "ip": "^1.1.2", "json-loader": "^0.5.4", - "koa": "^2.0.0-alpha.3", - "koa-connect-history-api-fallback": "^0.3.1", - "koa-convert": "^1.2.0", - "koa-proxy": "^0.6.0", - "koa-static": "^3.0.0", "node-sass": "^3.7.0", "normalize.css": "^4.1.1", "postcss-loader": "^0.11.1", diff --git a/server/lib/apply-express-middleware.js b/server/lib/apply-express-middleware.js deleted file mode 100644 index 4c8ba2d2d..000000000 --- a/server/lib/apply-express-middleware.js +++ /dev/null @@ -1,14 +0,0 @@ -// Based on: https://github.com/dayAlone/koa-webpack-hot-middleware/blob/master/index.js -export default function applyExpressMiddleware (fn, req, res) { - const originalEnd = res.end - - return new Promise((resolve) => { - res.end = function () { - originalEnd.apply(this, arguments) - resolve(false) - } - fn(req, res, function () { - resolve(true) - }) - }) -} diff --git a/server/main.js b/server/main.js index 45c8f372a..4565c7ff7 100644 --- a/server/main.js +++ b/server/main.js @@ -1,30 +1,16 @@ -import Koa from 'koa' -import convert from 'koa-convert' -import webpack from 'webpack' -import webpackConfig from '../build/webpack.config' -import historyApiFallback from 'koa-connect-history-api-fallback' -import serve from 'koa-static' -import proxy from 'koa-proxy' -import _debug from 'debug' -import config from '../config' -import webpackDevMiddleware from './middleware/webpack-dev' -import webpackHMRMiddleware from './middleware/webpack-hmr' +const express = require('express') +const debug = require('debug')('app:server') +const webpack = require('webpack') +const webpackConfig = require('../build/webpack.config') +const config = require('../config') -const debug = _debug('app:server') +const app = express() const paths = config.utils_paths -const app = new Koa() - -// Enable koa-proxy if it has been enabled in the config. -if (config.proxy && config.proxy.enabled) { - app.use(convert(proxy(config.proxy.options))) -} // This rewrites all routes requests to the root /index.html file -// (ignoring file requests). If you want to implement isomorphic +// (ignoring file requests). If you want to implement universal // rendering, you'll want to remove this middleware. -app.use(convert(historyApiFallback({ - verbose : false -}))) +app.use(require('connect-history-api-fallback')()) // ------------------------------------ // Apply Webpack HMR Middleware @@ -32,17 +18,23 @@ app.use(convert(historyApiFallback({ if (config.env === 'development') { const compiler = webpack(webpackConfig) - // Enable webpack-dev and webpack-hot middleware - const { publicPath } = webpackConfig.output - - app.use(webpackDevMiddleware(compiler, publicPath)) - app.use(webpackHMRMiddleware(compiler)) + debug('Enable webpack dev and HMR middleware') + app.use(require('webpack-dev-middleware')(compiler, { + publicPath : webpackConfig.output.publicPath, + contentBase : paths.client(), + hot : true, + quiet : config.compiler_quiet, + noInfo : config.compiler_quiet, + lazy : false, + stats : config.compiler_stats + })) + app.use(require('webpack-hot-middleware')(compiler)) // Serve static assets from ~/src/static since Webpack is unaware of // these files. This middleware doesn't need to be enabled outside // of development since this directory will be copied into ~/dist // when the application is compiled. - app.use(serve(paths.client('static'))) + app.use(express.static(paths.client('static'))) } else { debug( 'Server is being run outside of live development mode, meaning it will ' + @@ -55,7 +47,7 @@ if (config.env === 'development') { // Serving ~/dist by default. Ideally these files should be served by // the web server and not the app server, but this helps to demo the // server in production. - app.use(serve(paths.dist())) + app.use(express.static(paths.dist())) } -export default app +module.exports = app diff --git a/server/middleware/webpack-dev.js b/server/middleware/webpack-dev.js deleted file mode 100644 index 5ed7ebe9f..000000000 --- a/server/middleware/webpack-dev.js +++ /dev/null @@ -1,34 +0,0 @@ -import WebpackDevMiddleware from 'webpack-dev-middleware' -import applyExpressMiddleware from '../lib/apply-express-middleware' -import _debug from 'debug' -import config from '../../config' - -const paths = config.utils_paths -const debug = _debug('app:server:webpack-dev') - -export default function (compiler, publicPath) { - debug('Enable webpack dev middleware.') - - const middleware = WebpackDevMiddleware(compiler, { - publicPath, - contentBase : paths.client(), - hot : true, - quiet : config.compiler_quiet, - noInfo : config.compiler_quiet, - lazy : false, - stats : config.compiler_stats - }) - - return async function koaWebpackDevMiddleware (ctx, next) { - let hasNext = await applyExpressMiddleware(middleware, ctx.req, { - end : (content) => (ctx.body = content), - setHeader : function () { - ctx.set.apply(ctx, arguments) - } - }) - - if (hasNext) { - await next() - } - } -} diff --git a/server/middleware/webpack-hmr.js b/server/middleware/webpack-hmr.js deleted file mode 100644 index ddaff4d9e..000000000 --- a/server/middleware/webpack-hmr.js +++ /dev/null @@ -1,18 +0,0 @@ -import WebpackHotMiddleware from 'webpack-hot-middleware' -import applyExpressMiddleware from '../lib/apply-express-middleware' -import _debug from 'debug' - -const debug = _debug('app:server:webpack-hmr') - -export default function (compiler, opts) { - debug('Enable Webpack Hot Module Replacement (HMR).') - - const middleware = WebpackHotMiddleware(compiler, opts) - return async function koaWebpackHMR (ctx, next) { - let hasNext = await applyExpressMiddleware(middleware, ctx.req, ctx.res) - - if (hasNext && next) { - await next() - } - } -} diff --git a/src/main.js b/src/main.js index 6c70aaea8..0be028ccd 100644 --- a/src/main.js +++ b/src/main.js @@ -26,15 +26,6 @@ const history = syncHistoryWithStore(browserHistory, store, { selectLocationState : (state) => state.router }) -// ======================================================== -// Developer Tools Setup -// ======================================================== -if (__DEBUG__) { - if (window.devToolsExtension) { - window.devToolsExtension.open() - } -} - // ======================================================== // Render Setup // ======================================================== @@ -53,6 +44,15 @@ let render = () => { ) } +// ======================================================== +// Developer Tools Setup +// ======================================================== +if (__DEV__) { + if (window.devToolsExtension) { + window.devToolsExtension.open() + } +} + // This code is excluded from production bundle if (__DEV__) { if (module.hot) { diff --git a/src/store/createStore.js b/src/store/createStore.js index 666076b8a..3445c8424 100644 --- a/src/store/createStore.js +++ b/src/store/createStore.js @@ -13,7 +13,7 @@ export default (initialState = {}, history) => { // Store Enhancers // ====================================================== const enhancers = [] - if (__DEBUG__) { + if (__DEV__) { const devToolsExtension = window.devToolsExtension if (typeof devToolsExtension === 'function') { enhancers.push(devToolsExtension())