Search code examples
javascriptnode.jsexpressvue.jskoa

How to organise a webpacked vue.js application served by an express/koa backend?


I am having some difficulty with setting up an easy to debug vue.js project in combination with a koa server. The command cross-env NODE_ENV=development webpack-dev-server --open --hot from the webpack-simple generated configuration seems to be a nice thing, but what is the convention for using this with koa/express?

One solution that i've found is using pm2 to launch the webpack-dev-server for vue and the backend at the same time, but then i think this means i need a copied version of the initial landing vue.js app page which i'm currently serving from a koa route on /. Also it's kind of confusing for me to think about these two servers and it feels strange.

So, i think i must be doing it wrong! Could someone please explain a nice conventional way of doing this.


Solution

  • If you're trying to use webpack-dev-server with your own Node backend, you'll want to look into using proxy.

    Basically, the idea is that you run your webpack-dev-server on one port (for example, port 3000) and you run your Node server on another port (for example, port 3001). You just need to tell webpack to forward your server-side requests to your Node backend.

    You can do this by adding a proxy property to the devServer setting in your webpack.config.js file. For example:

    devServer: {
      ...
      proxy: {
        '/api/**': {
          target: 'http://localhost:3001',
          secure: false
        }
      }
    }
    

    Now, any requests that start with /api/ will go to your Node backend. So if you do something like:

    fetch('/api/users').then(...)
    

    This request will be proxied to your Node server. You will just want to make sure you prefix all your server-side routes with /api/.

    To automatically prefix all your routes in Koa, you can just do the following:

    const Koa = require('koa')
    const Router = require('koa-router')
    
    const app = new Koa()
    const router = new Router({ prefix: '/api' })
    
    // GET /api/users
    router.get('/users', async ctx => {
      ...
    })
    
    app.use(router.routes())
    app.use(router.allowedMethods())
    

    If you're using Express, you can prefix by doing the following:

    const express = require('express')
    
    const app = express()
    const router = express.Router()
    
    // GET /api/users
    router.get('/users', (req, res) => {
      ...
    })
    
    app.use('/api', router)