{{announcement.body}}
{{announcement.title}}

Vue CLI 3 Full-Stack App Structure

DZone 's Guide to

Vue CLI 3 Full-Stack App Structure

A discussion of how Vue can used in full-stack web application development.

· Web Dev Zone ·
Free Resource

If you're creating an app with Vue.js, you'll most likely want to utilize the best-practice scaffolding provided by Vue CLI 3.

But if the Vue app is the client layer of a full-stack JavaScript app, for example, in a "MEVN" configuration (Mongo, Express, Vue, Node), it's not entirely clear how Vue CLI 3 should be integrated into such a structure.

There are several approaches you could reasonably take:

  1. Put your server in a completely separate repo.
  2. Create a repo for your server and put your Vue CLI 3 scaffold in a sub-folder.
  3. Create a "universal" structure by modifying your Vue CLI 3 scaffold to share with your server.
  4. Conclude that it is not appropriate to use Vue CLI 3 for a full-stack structure and roll your own config.

The difficulty of choosing one of these options is that each has its own pros and cons when it comes to balancing best practices, maintainability, ease of use, ease of testing, and deployment, etc.

Making this choice was of particular interest to me as I thought about the best approach to take for my [Enterprise Vue](https://vuejsdevelopers.com/courses/enterprise-vue?utmsource=vjd-blog&utmmedium=article ) course, which is centered around the creation of a MEVN app. I was hoping it would be possible to build this app and still take advantage of Vue CLI 3.

Deferring to Authority and Experience

As far as I know, there is no "official" example of Vue CLI 3 in a full-stack configuration, and I imagine there is unlikely to ever be.

But we can look at how other JavaScipt frameworks have tackled this issue.

A popular and well-respected full-stack app boilerplate is the one outlined at mean.io for a full-stack Angular app.

This boilerplate, and in fact almost all of the full-stack JavaScript boilerplates I could find, use the universal approach I mentioned, where both the client and server share the same directory, giving you a structure like this:

- client
  - components
    ...
  main.js
- server
  - routes
    ...
  index.js
  ...
package.json
...

Interestingly, the mean.io boilerplate also includes Angular CLI.

Universal Folder Structure Pros and Cons

By looking at examples out on in the wild, it seems this approach is the most popular way to structure a full-stack JS app.

Some of the advantages I can see are:

  • It's efficient, as it allows you to share package.json, node_modules, environment variables, and opens the possibility of common code between client and server.
  • It makes installation and deployment easy, as one command in package.json can be used to install/deploy the whole app.
  • It's easy to read and understand.

The disadvantage is that if you want to use this app structure with Vue CLI 3, you'll need to modify the scaffold, which is not without its shortcomings.

Accommodating a Server in a Vue CLI 3 Scaffold

Vue CLI 3 hasn't been designed to share its space with a server. By going down this path a few of the problems you'll face include:

  • It doesn't like you to change the file structure. For example, the src folder can't easily be renamed.
  • It hijacks the .env file and important environment variables like PORT which are normally reserved for the server.
  • Some out-of-the-box config like ESLint is not appropriate for server files, so you'll have to manually update them.

None of these problems are insurmountable, though, and if you can get through them you'll have a clean, maintainable folder structure, with the best practices and zero-config advantages of Vue CLI 3.


Do you want to learn how to build fully-tested, production-ready Vue applications that are suitable for commercial purposes? Join the pre-sale of my upcoming Enterprise Vue course!


Topics:
javascript ,vue.js ,web dev ,full-stack development

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}