vch
vch

Reputation: 721

Server / client app with webpack + socket.io

I'm working on an app that has frontend communicating with backend via socket.io

Right now I have them in two separate apps like this:

.
├──client
│  ├──src
│  │  └──index.js
│  ├──public 
│  │  └──index.html
│  ├──webpack.config.js
│  └──package.json
└──server
   ├──app.js
   └──package.json

./server/app.js goes like this

const Express = require('express')();
const server = require('http').Server(Express);
const options = {
    cors: {
        origin: 'http://localhost:8080',
        methods: ['GET','POST'],
        credentials: true,
    },
};
const Socketio = require('socket.io')(server, options);

Socketio.on('connection', socket => {
    socket.on('do-something', () => {
        console.log('doing something...');
    });

});

server.listen(3000, () => {
    console.log('listening on port 3000');
});

./client/src/index.js has these lines

const io = require('socket.io-client');
const socket = io('http://localhost:3000');

const someFunction = () => {
    socket.emit('do-something');
}

Pretty standard stuff.

Right now I run them separately from two terminal windows. So basically I have two servers serving a single app. It doesn't seem like the right way to go so I want to try and unite them into a single webpack app to aim for deployment. How do I do that? How do you setup this kind of thing in a real world?

I tried googling on the subject but couldn't find anything. If you know of a post that clearly explains this, share the link please.

Upvotes: 0

Views: 734

Answers (2)

Jonas
Jonas

Reputation: 181

I recommend:

  1. Placing webpack.config.js and package.json in the root of your project.
  2. In ./server, distinguished app.js (export express app) and server.js (listen at a port).
  3. Use npm-run-all for simplify your package.json scripts (that provided the commands run-p and run-s)
  4. Add a production ./server.js in the root of your project.

./package.json

  "scripts": {
    "dev": "run-p dev:*",
    "dev:server": "nodemon ./server/server.js",
    "dev:webpack": "webpack serve",
    "build:webpack": "webpack",
    "serve": "node ./server.js"
  }

./server/app.js

const Express = require('express')();
const app = require('http').Server(Express);

// Your app definition (socket.io, etc) ...

module.exports = app

./server/server.js

// Your api dev server

const app = require('./app')

app.listen(3000, () => {
    console.log('Dev server listening on port 3000');
});

./server.js

// Your prod server

const express = require('express')
const app = require('./server/app')

// Same of your api dev server, but your also serve your frontend build
// ./dist depends on webpack "output-path" parameter
app.use(express.static('./dist')) 

app.listen(3000, () => {
    console.log('Prod server listening on port 3000');
});

Now, you can:

Run frontend and backend in parallel

npm run dev

Run only frontend

npm run dev:webpack

Run only backend

npm run dev:server

Build frontend

npm run build:webpack

Serve backend and frontend in production (I suggest use pm2)

npm run serve

This architecture works fine in my projects 😊. You can easily extend it to use Typescript for example...

Sorry for my aproximativ English.

I did not test the code presented, sorry if there are any errors.

Regards

Upvotes: 1

Jared Smith
Jared Smith

Reputation: 21926

Ok, I give up. I'm answering.

Don't do this. Right now, merging the two repos looks tempting because you're using the same language and maybe some of the same dependencies for the client and the server.

But what happens when

  • Your boss says you have to port the server part to Python/Java/Go/whatever because reasons?
  • You want to hand off the client or the server to another team?
  • You want to open source the client but now the git history has all of your (still proprietary) server code tangled up in it?
  • You add a CI/CD workflow and now a commit to the client kicks off your pipeline for the server and vice-versa?

N.B. this isn't hypothetical, I've actually seen most of those happen. Now, you may have good answers to all those questions and decide to do it anyway, but if you don't then leave it be: bundling a client and server in the same repo loses you lots of flexibility for very minimal gains.

Upvotes: 2

Related Questions