Nuxt Areas

Scalable folder management for large Nuxt projects

Overview

Nuxt (opens new window) is the main full stack framework for Vue JS (opens new window).

It ships out of the box with a folder structure siloed by responsibility:

+- src
    +- components
    |   +- product-list.vue             <- stripe 1
    |   +- user-list.vue
    +- pages
    |   +- products.vue                 <- stripe 2
    |   +- users.vue
    +- store
        +- products.js                  <- stripe 3
        +- users.js
        +- user.js

This results in files being “striped” across the application, and as applications grow, not only do related files get further apart, but they sit in a sea of unrelated files, adding a physical and cognitive overhead to working with the various subsystems of the site.

Library

Areas (opens new window) is a Nuxt module that allows you to restucture your app to group related files by “area”:

+- src
    +- areas
        +- products                     <- area 1
        |   +- components
        |   |   +- product-list.vue
        |   +- pages
        |   |   +- index.vue
        |   +- store.js
        +- users                        <- area 2
            +- classes
            |   +- User.js
            +- components
            |   +- user-list.vue
            +- pages
            |   +- index.vue
            +- store
                +- users.js
                +- user.js

Co-locating files this way has various advantages:

  • it’s easier to work on a discrete unit of functionality, such as “products” or “users”
  • it’s easier to understand what the site does as a whole
  • it’s easier to see how related files work together
  • it’s less hopping about between multiple branches of the folder tree
  • it’s easier to find a home for components, classes, or data
  • naming is easier and imports are shorter

The library is available for Vue 2 and Vue 3 and handles:

  • routing (dynamic and custom)
  • store registration
  • component registration
  • Webpack aliases
  • watching and debugging

So...

I hope you found this post interesting or inspiring.

If you want to engage further, follow me on Twitter or drop a comment or reaction below.

Either way, thanks for reading!