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
Vue-CLI have some good features built-in to use, build vue components to library is one of those, at that time as initial development and needed to build something fast was a good choice.
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
Top comments (3)
Very well Rafael, congratulations for your effort to give this level of quality that we have on Design System!
Through that I already used it is really a excelente project and is in constant evolution.
Great work. I am also trying to do something similar however I have two questions:
How to you initialize Vuetify within your component library? I see that Vuetify was installed as dev dependency but I didn't see that it was initialized from your component library.
Are you saying that creating the library with vue rollup can cause issues and that's why you switched to vue-cli? what kind of issues? I am also using vue rollup!
Nice questions mate.
I will update it on this post soon, thanks. I don't initialized it inside my lib, I do it inside my project consuming my lib, on Nuxt(most of our projects) I include Vuetify module on
nuxt.config
like this vuetifyjs.com/en/getting-started/i..., and for a Vue-CLI project I imported Vuetify and add the commomVue.use(Vuetify)
.I had issues to build my scss files, I remember I as trying to building it to separated files on dist folder and couldn't make it works, it was with some rollup plugin. If you could share your project or a sandbox of it with rollup, I would appreciate to see it.