Reputation: 6015
I'm having a hard time finding resources that explain how to connect webpack to a express server app. I'm wanting to use webpack for babel to use es6 when writing react and use its hot-module and cheap-module-source-map. But, webpack runs it's own express server and that currently conflicts with my express app. I want my express app to dictate the port and routes but still get the benefits of using webpack.
Any ideas?
The express app looks something like this:
var express = require('express'),
Sequelize = require('sequelize'),
/*
set up sequelize ...
app.route ...
*/
app.listen(port), function () {
console.log('Express server listening on port ' + port
});
Upvotes: 1
Views: 2074
Reputation: 1018
You don't need the webpack-dev-server to use Webpack for Babel to use ES2015 when writing React and use its hot-module and cheap-module-source-map.
Webpack configuration for React app in development env:
module.exports = {
entry: {
app: [
'react-hot-loader/patch',
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000',
'app/index.js,
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
})
.babelrc
looks like this:
{
"presets": ["react", "es2015", "stage-0"],
"env": {
"development": {
"plugins": ["react-hot-loader/babel"]
}
}
}
app/index.js
:
import { AppContainer} from 'react-hot-loader'
...
<AppContainer>
<App />
</AppContainer>
...
if (module.hot) {
module.hot.accept('./routes', () => {
// Hot reloading
})
}
server/index.js
:
import webpack from 'webpack'
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import webpackConfig from './webpack.dev.config'
const compiler = webpack(webpackConfig)
app.use(webpackDevMiddleware(compiler, {
noInfo: true,
publicPath: webpackConfig.output.publicPath,
}))
app.use(webpackHotMiddleware(compiler, {
path: '/__webpack_hmr',
heartbeat: 10000,
}))
I am not sure if it's allowed to refer to my own repo here, but please check my Github repo here to see how I have integrated React, Express, Webpack, HMR and Babel.
Upvotes: 1
Reputation: 1674
What I ended up doing was I used 2 different configurations, 1 for packing the server stuff together using webpack, and 1 for packing all the browser stuff together and also run webpack dev server for hot reloading.
Server webpack config aka webpack.node.config.js now looks like this:
var webpack = require('webpack');
var path = require('path');
var fs = require('fs');
var nodeModules = {};
// note the path.resolve(__dirname, ...) part
// without it, eslint-import-resolver-webpack fails
// since eslint might be invoked with different cwd
fs.readdirSync(path.resolve(__dirname, 'node_modules'))
.filter(x => ['.bin'].indexOf(x) === -1)
.forEach(mod => { nodeModules[mod] = `commonjs ${mod}`; });
// es5 style alternative
// fs.readdirSync(path.resolve(__dirname, 'node_modules'))
// .filter(function(x) {
// return ['.bin'].indexOf(x) === -1;
// })
// .forEach(function(mod) {
// nodeModules[mod] = 'commonjs ' + mod;
// });
module.exports =
{
// The configuration for the server-side rendering
name: 'server',
target: 'node',
entry: './app/server/serverEntryPrototype.js',
output: {
path: './bin/',
publicPath: 'bin/',
filename: 'serverEntryPoint.js'
},
externals: nodeModules,
module: {
loaders: [
{ test: /\.js$/,
loaders: [
// 'imports?document=this',
// 'react-hot',
'babel-loader'
//,'jsx-loader'
]
},
{ test: /\.json$/, loader: 'json-loader' },
]
},
plugins: [
// new webpack.NormalModuleReplacementPlugin("^(react-bootstrap-modal)$", "^(react)$")
// new webpack.IgnorePlugin(new RegExp("^(react-bootstrap-modal)$"))
// new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
};
Browser webpack config aka webpack.browser.config.js now looks like this:
var webpack = require('webpack');
var path = require('path');
var buildPath = path.resolve(__dirname, 'assets');
var fs = require('fs');
var commonLoaders = [
{ test: /\.js$/,
loaders: [
'react-hot',
'babel-loader'
//,'jsx-loader'
]
}
];
module.exports =
{
// Makes sure errors in console map to the correct file
// and line number
name: 'browser',
devtool: 'eval',
entry: [
//'./bin/www.js',
'./app/index.js',
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8081' // WebpackDevServer host and port
],
output: {
path: buildPath,
filename: '[name].js',
// Everything related to Webpack should go through a build path,
// localhost:3000/build. That makes proxying easier to handle
publicPath: 'http://localhost:8081/assets/'
},
extensions: [
'',
'.jsx', '.js',
'.json',
'.html',
'.css', '.styl', '.scss', '.sass'
],
module: {
loaders: [
// Compile es6 to js.
{
test: /app\/.*\.jsx?$/,
loaders: [
'react-hot',
'babel-loader'
]
},
///app\/.*\.json$/
{ test: /\.json$/, loader: 'json-loader' },
// Styles
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.s(a|c)ss$/, loader: 'style!css?localIdentName=[path][name]---[local]---[hash:base64:5]!postcss!sass' },
// Fonts
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=10000&minetype=application/font-woff' },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader' }
//{ test: /\.png$/, loader: 'url-loader?limit=100000' },
//{ test: /\.jpg$/, loader: 'file-loader' }
],
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
},
postcss: [
require('autoprefixer-core')
],
devtool: 'source-map'
}
;
Upvotes: 0