Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running a node express server using webpack-dev-server

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 ;)

like image 403
Øyvind Bråthen Avatar asked Feb 05 '16 20:02

Øyvind Bråthen


People also ask

Can you use webpack for node?

Webpack provieds a Command Line Interface (CLI), which we can call as webpack filename. js target/index. js from the terminal; and Node. js API, which we can use in our Node.

What is the use of Webpack dev server?

webpack-dev-server is Webpack's officially supported CLI-based tool for starting a static server for your assets. While you don't need any CLI tools to use Webpack, webpack-dev-server gives you a single command that starts a static server with built-in live reload.

Do I need webpack for Express?

As is usually the case in software engineering, the answer is “it depends.” If you're building a basic Express app that runs on Node. js, you don't need Webpack at all.


2 Answers

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).

"scripts": {    "start": "webpack --progress --colors",    "dev-server": "nodemon ./server.js localhost 8080",    "dev-client": "webpack-dev-server --port 3000", } 

Or, to run express directly from node:

"scripts": {    "start": "webpack --progress --colors",    "dev-server": "node dev-server.js",    "dev-client": "webpack-dev-server --port 3000", } 
// dev-server.js const express = require('express'); const app = express(); // Import routes require('./_routes')(app);   // <-- or whatever you do to include your API endpoints and middleware app.set('port', 8080); app.listen(app.get('port'), function() {     console.log('Node App Started'); }); 

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:

devServer: {   historyApiFallback: true,   hot: true,   inline: true,    host: 'localhost', // Defaults to `localhost`   port: 3000, // Defaults to 8080   proxy: {     '^/api/*': {       target: 'http://localhost:8080/api/',       secure: false     }   } }, // and separately, in your plugins section plugins: [   new webpack.HotModuleReplacementPlugin({     multiStep: true   }) ] 

**Bonus points for having a single script to start and kill both

like image 194
Loren_ Avatar answered Sep 18 '22 15:09

Loren_


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-middleware

const express = require('express'); //your original BE server const app = express();  const webpack = require('webpack'); const middleware = require('webpack-dev-middleware'); //webpack hot reloading middleware const compiler = webpack({ .. webpack options .. }); //move your `devServer` config from `webpack.config.js`   app.use(middleware(compiler, {   // webpack-dev-middleware options }));  app.listen(3000, () => console.log('Example app listening on port 3000!')) 

So, 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

like image 26
Shawn Wang Avatar answered Sep 16 '22 15:09

Shawn Wang