Library based on Vuetify, how we use and tips to avoid performance issues

Introduction

How to build a Design System inside a startup?
I'm Rafael Bastiansch, Front End Tech Leader responsible for this architeture and I'm going to show how we build a design system at Logcomex and help you to build similar tool for your personal projects or job, I gonna show our stack today and why our library was build this way.
To make you feel confortable with our business, I'll explain our projects at Logcomex:

  • the biggest one is a monolithic type, that sharing different purposes.
  • new projects are created with Nuxt.

We wanted to create our new projects with same design but it was in separated repositories, so we had to reuse our basics components. The idea was to create a library that shares our pieces of code.

First version with rollup

The first version was build with rollup, but I have some problems just after we started. Using complex components from vuetify and separated scss, it started to generate some errors to compile the library. So I had to figure out what was happening and, after some POCs I tried Vue-CLI and it works like a charm. So due to lack of time we decided to keep using it.

Version with vue-cli

To create a library with Vue-CLI, we init a project following the instructions and added some configurations to vue.config.js

const path = require('path');

module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        "~": path.resolve(__dirname)
      }
    },
  },
  css: {
    loaderOptions: {
      sass: {
        additionalData: `
          @import "@/assets/scss/_main.scss";
        `
      }
    }
  }
}

and add the script to package.json to build our lib

...
"scripts": {
    "build": "vue-cli-service build --target lib src/index.js",
},
...

The structure of our lib have src/index.js file, it's where we imported all my components and prepare them to be imported when another project is using this package. You can check more about this here: Vue cookbook

export * from './components/inputs'
import * as inputs from './components/inputs'


const components = {
    ...inputs,
}

export function install (Vue) {
    for (const [name, component] of Object.entries(components)) {
        Vue.component(name, component)
    }
}

const plugin = {
  install
}

let GlobalVue = null;
if (typeof window !== "undefined") {
  GlobalVue = window.Vue;
} else if (typeof global !== "undefined") {
  // eslint-disable-next-line no-undef
  GlobalVue = global.Vue
}
if (GlobalVue) {
  GlobalVue.use(plugin);
}

export default plugin;

Basically, these are all the files that you will need to create/modify to start your own library with Vue-CLI.

Current version and problems

We're running our current version build using Vue-CLI for almost one year, it keeps the same way that was made and up to now it is good for us... but we have some improvements to do. We did this thinking in our current projects, so we have to keep them compatible.
As we found some errors on consuming it we keep external libraries building within our package and that's a problem, the size of package increase as we add new features that requires external installations. Currently its size is 219KB zipped.

New version with some fixes

So right now I'm working to improve this, first of all I set all the third packages as external, this reduced the size of our old file to 58KB zipped, almost 4 times less than before. To achieve this you have to set libraries as externals in vue.config.js inside configureWebpack key and it won't compile anymore.

...
externals: [
  'dayjs',
  'moment',
  'ramda',
  'sortablejs'
],
...

and migrate some dependencies to devDependencies(sorry, my mistake). It's the current changes I'm doing, after we use this new build to production we gonna see if it will be enough or if we will see more improvement to our lib.

If you want to check it out and use or contribute, you will be more than welcomed.
Project github
New branch with improvement

14