Shawn Wildermuth

Author, Teacher, and Filmmaker
.NET Foundation Board Member

Revisiting Multiple Vue Projects

Revisiting Multiple Vue Projects

I've talked about how the term SPA annoys me. I think that client-side frameworks are great for expanding websites, not replacing them. With that in mind, I like the idea of a handful of client-side apps enhancing websites, but not every framework makes that easy.

In this article, I'll talk about my new approach to doing this in Vue 3. Though I'm going to use Vue 3, the approach will work with any Vue project using the CLI (including Vue 2).

Vue Pages

Before I talk about the approach, let's talk about the 'pages' feature of Vue. Pages is somewhat a misnomer as each 'page' can be a completely isolated Vue project. The only real magic here is that it will build individual Vue project from a single build-step using the Vue CLI.

Let's start with a simple view of the structure of our Vue project:

Multiple View Project

Note that this has a vue.config.js file. This is an optional file that allows you to customize how you're building your project.

// vue.config.js
module.exports = {
}

To support the Pages functionality you just need to create a pages object in the configuration:

// vue.config.js
module.exports = {
  pages: {
    // ...
  }
}

This prevents the main.js/ts file from being the one and only starting point for your project building. You can simply add properties that point at starting .js/ts files. For example:

// vue.config.js
module.exports = {
  pages: {
    main: "src/main.js",
    about: "src/about.js",
  }
}

In this way, it will build two separate projects within the source tree. For me the magic, is that we can share code between the projects. When you build the project, you get one chunk-vendors to share, and individual packages for each item in the pages.

 File                        Size            Gzipped

  dist\js\chunk-vendors.js    597.27 KiB     112.99 KiB
  dist\js\about.js            40.44 KiB        4.92 KiB
  dist\js\main.js             40.43 KiB        4.91 KiB

  Images and other types of assets omitted.

My New Strategy

My new strategy is a small change from my old approach but I like how streamlined sharing code becomes. Effectively, I am moving each of the pages into their own directory. This way the vue.config.js just points at directories:

// vue.config.js
module.exports = {
  pages: {
    main: "src/main",
    about: "src/about"
  }
}

And the shared code stays at the root level:

So that code for shared components can just use the @ prefix:

import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}

Thoughts?