I'm using webpack to run my react frontend successfully using the following config:
{
name: 'client',
entry: './scripts/main.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query:{
presets: ['es2015', 'react', 'stage-2']
}
}
]
}
}
I'm trying to put up a node.js express backend as well, and would like to run that through webpack as well, so that I have a single server running both the backend and frontend, and because I want to use babel to transpile my javascript.
I made a quick testserver looking like this:
var express = require('express');
console.log('test');
var app = express();
app.get('/', function(req, res){
res.send("Hello world from Express!!");
});
app.listen(3000, function(){
console.log('Example app listening on port 3000');
});
If I run this with node index.js
and open my browser on localhost:3000
it prints "Hello world from Express!!". So far so good. Then I tried creating a web-pack config for it:
var fs = require('fs');
var nodeModules = {};
fs.readdirSync('node_modules')
.filter(function(x) {
return ['.bin'].indexOf(x) === -1;
})
.forEach(function(mod) {
nodeModules[mod] = 'commonjs ' + mod;
});
module.exports = [
{
name: 'server',
target: 'node',
entry: './index.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
externals: nodeModules,
module: {
loaders: [
{
test: /\.js$/,
loaders: [
'babel-loader'
]
},
{
test: /\.json$/,
loader: 'json-loader'
}
]
}
}
When I run the command webpack-dev-server
it starts up successfully (it seems). However, if I go to my browser on localhost:3000
now, it just says that the webpage is not available, just as when the server is not running at all.
I'm very new to both node and webpack, so either I have made a small mistake somewhere, or I'm way off ;)
From your questions here and here, it appears that you are using ReactJS with ES6. I faced the exact same issue, and here is how I tackled it -
Have multiple entry points for your application
In particular you can put all your vendor files like JQuery, React etc into one chunk. This way, your vendor files will remain the same even when you modify your souce files. You can add this line to your webpack config
Use the
CommonsChunkPlugin
to have webpack determine what code/modules you use the most, and put it in a separate bundle to be used anywhere in your application.Use React Hot Loader
Run
npm install react-hot-loader --save-dev
. Make sure you have installedwebpack-dev-server
first.Then you need to change your loaders to this -
Make sure React Hot Loader comes before Babel in the loaders array. Also make sure you have
include: path.join(__dirname, 'public')
to avoid processing node_modules, or you may get an error like this -Uncaught TypeError: Cannot read property 'NODE_ENV' of undefined
Modifications to your script tags in your
index.html
pageIf your html has something like this -
Change this to point to your webpack-dev-server proxy -
Run
webpack-dev-server --hot --inline
,wait for the bundling to finish, then hit http://localhost:3000 (your express server port) in your browser.
If you run into any errors, you could find this troubleshooting guide very useful.
Hope this helps, and you can take a look at the webpack setup for my project here
Webpack-dev-server is great for client side development but it will not deploy Express api's or middleware. So in development I recommend running two separate servers: One for the client and one for your server side api's.
Nodemon
npm install --save-dev nodemon
is a good backend development server that will give you hot-redeploy of your api's, or you can just use express and restart when you make changes. In production the client and api will still be served by the same express server.Set a lifecycle event for both nodemon and webpack-dev-server in your
package.json
to make starting them easy (example:npm run dev-server
).Or, to run express directly from node:
Note: The api server must use a different port than webpack-dev-server.
And finally in your webpack-dev-config you need to use a proxy to redirect calls to your api to the new port:
**Bonus points for having a single script to start and kill both
Since webpack-dev-server is just a tiny express server with compile on change and hot reload.
So, if you already got a express server for backend API, just merge the
compile on change and hot reload
into your express server.Then after take a look at the
package.json
of webpack-dev-server, i find the key is just webpack-dev-middlewareSo, when you run your BE server, it will compile all the things using webpack, and watch for changes, LOL ~
Also, add webpack-hot-middleware for hot reloading function, see Hot Module Replacement