Enable Vue.js Webpack Development With Hot Module Reloading (HMR) On External Server

February 20, 2018

Vue.js webpack template offer first-in-class development experience by running a simple command of npm run dev. This command will spawn webpack-dev-server serving index.html, offering features like hot-reload, eslint & source maps to allow quick edit and reload feature during development.

I am developing a web app using Flask which run on nginx + uwsgi (or Google App Engine development), and it would be ideal to use my Flask web server for development rather than the default webserver of Vue.js webpack. npm run dev is ideal for SPA (Single Page Application), but I am building multiple modules for different pages of my Flask web app.

This guide will cover development only, not production or deployment.

NOTE: this is latest update from the previous guide.

Setup Vue.js webpack project

This is the standard instruction for setup a Vue.js webpack project and run a development server on http://localhost:8080.

npm install -g vue-cli
vue init webpack <PROJECT_NAME>
cd <PROJECT_NAME>
npm install
npm run dev

NOTE: I am using vuejs-templates/webpack v1.3.1 - 14 Jan 2018.

Check the source of the page (http://localhost:8080/) and you will notice the following JavaScript being included.

<!doctype html>
<html lang="en">
  ...
  <script type="text/javascript" src="http://localhost:8080/app.js"></script></body>
</html>

CTRL-C to stop the development server.

Enable Hot Module Reloading (HMR) for External Server

Edit build/webpack.dev.conf.js to enable CORS.

...

const devWebpackConfig = merge(baseWebpackConfig, {
  devServer: {
    // EDIT: add headers to allow CORS
    headers: {
      "Access-Control-Allow-Origin":"\*"
    },
    clientLogLevel: 'warning',
    ...
  },
  ...
})
...

Edit config/index.js

...
module.exports = {
  dev: {
    // EDIT: edit full path to enable module reload from external source, without this will trigger page reload
    // assetsPublicPath: '/'
    assetsPublicPath: 'http://localhost:8080/',
  },
  ...
}

Run development server again.

npm run dev

Embed JavaScript

Include http://localhost:8080/app.js and <div id="app" /> in the html file of your external server.

<!doctype html>
<html lang="en">
  ...
  <body>
    <h1>I am External Server</h1>
    <div id="app" />
    <script type="text/javascript" src="http://localhost:8080/app.js"></script></body>
  </body>
</html>

Browse you page (e.g. http://localhost/).

You could see [HMR] Waiting for update signal from WDS... in console log if HMR is successful. Try edit your files in Vue.js project and the page should auto update (just like npm run dev at http://localhost:8080/).

You might want to load different set of JavaScript for development and production environment, something like the following using Jinja2.

<!doctype html>
<html lang="en">
  ...
  <body>
  {% if DEVELOPMENT_SERVER %}
  <script src="http://localhost:8081/app.js" type="text/javascript"></script>
  {% else %}
  <script src="{{ JS_ASSETS['manifest.js'] }}" type="text/javascript"></script>
  <script src="{{ JS_ASSETS['vendor.js'] }}" type="text/javascript"></script>
  <script src="{{ JS_ASSETS['app.js'] }}" type="text/javascript"></script>
  {% endif %}
  </body>
</html>
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.