loading...

Dear VueJS devs, VeeValidate might not be worth it

sduduzog profile image Beautus S Gumede ・3 min read

In fact, I am not leaving Vuelidate out of this. I wanted to validate user input upon registration/signup so I knew it was best I used a tried and tested package to do validation for me.

Vuelidate is apparently great but...

Although not so much when you're using typescript like me. I'll get into that later but long story short, it was a nightmare trying to get it working with me.

VeeValidate is, I guess, the best. It's just that...

When running npm build and get a warning that my entry bundle exceeds the recommended size, I panick. See I get paranoid about performance because its those type of choices I make on my project that I think reflects my character as a programmer, others being security and accessibility.

Out of the two libraries I've mentioned, Vuelidate had typing issues when integrated with with a typescript project. An issue that has been posted several times and with possible solutions by devs. In short, there's a passage/rant here that sums up the problem. The part that got to me is the quote below.

There are more issues on GitHub talking about TypeScript integration, and again multiple devs try to kickstart adding typings to the project, providing proof of concepts or first versions over the course of months. Again, the repo owner gets excited. Two months ago, he once again states that he's going to "roll out the typings into the offical package soon". Until today, nothing happened though.

Interestingly enough, thats the same post that introduced me to VeeValidate. And I was happy with its implementation and ease of use until I viewed the build output.

Throughout my whole project, I'm only validating 4 input fields and thats it. But VeeValidate being bundled is larger than all other node_modules packages bundled in my app. Even larger than Vue by at least 1/3rd if not more. I tried lazy loading it but it wasn't being injected into the component that was using it.

Of course the creators acknowledged [this and even provide possible solutions for it(https://baianat.github.io/vee-validate/concepts/bundle-size.html#minimal-bundle) BUT I went through all this not planning to solve problems of solutions that I was looking for.

The answer to my problems was right in front of me already though.

v-bind | computed properties| regex

<input
          type="text" 
          name="email"
          @blur="touch('email')"
          :class="{error: !emailValid}"
          placeholder="Email" 
          v-model="email">

Along with other fields, when it looses focus, that means it has been touched. So

private touch(item: string) {
    this.validate = true;
    if (!this.dirty.includes(item)) {
      this.dirty.push(item);
    }
  }

And to show an error in the input field I check whether it has been touched (dirty) and whether whatever input given match the email pattern.

private get emailValid() {
    if (this.dirty.includes('email')) {
      const valid = /^([\w\.]+@[a-zA-Z_]+?(\.[a-zA-Z]{2,6}){1,2})$/.test(this.email);
      if (valid) {
        this.dirty.splice(this.dirty.indexOf('email'));
      }
      return valid;
    }
    return true;
  }

So as inspired by other validators, to get insight, I compute a list of errors like so

private get errors(): string[] {
    const field: string[] = [];
    if (!this.namesValid) {
      field.push('names');
    }
    if (!this.emailValid) {
      field.push('email');
    }
    if (!this.passwordValid) {
      field.push('password');
    }
    if (!this.passwordConfirmed) {
      field.push('password_confirm');
    }
    return field;
  }

But this alone is not enough. Having not touched the input field doesn't mean that they are still valid and to solve that, I must do another check

private get empty(): string[] {
    const field: string[] = [];
    if (this.names.length === 0) {
      field.push('names');
    }
    if (this.email.length === 0) {
      field.push('email');
    }
    if (this.password.length === 0) {
      field.push('password');
    }
    if (this.pwd2.length === 0) {
      field.push('password_confirm');
    }
    return field;
  }

And then finally, when the form is submitted, I wrap up everything together here

private signUp(): void {
    if (this.loading) {
      return;
    }
    if (this.empty.length !== 0) {
      return;
    }
    if (this.errors.length !== 0) {
      return;
    }
    this.loading = true;
    createUser(this.names, this.email, this.password)
      .then((response) => {
        this.toSignin();
      })
      .catch(this.handleNetworkError);
  }
}

To conclude

I know that I might be made misinformed on some details of the libraries I mentioned and maybe my solution is not as good as them but it was worth reinventing this wheel. I shedded milliseconds off load time for most well-off potential visitors to the site, and I definitely shedded a second plus some change for the next billion users

Posted on Dec 9 '19 by:

sduduzog profile

Beautus S Gumede

@sduduzog

Junior Full Stack Dev | I make stuff at home | I break stuff at work | I write code

Discussion

markdown guide
 

Nice article.

I think this line should be deleted since it doesn't seem to be doing anything:

this.validate = true;

And I think this line:

this.dirty.splice(this.dirty.indexOf('email'));

Should be changed to this to delete just that item:

this.dirty.splice(this.dirty.indexOf('email'), 1);
 

I think this article was highly relevant at the time of writing, but note that veeValidate v3 seems much more compact (even ignoring many other improvements to the library).

 

With later reading up on their docs much recently, there are so many points that drew my attention which are solutions to sentiments I was expressing with the article. I do need to check it out soon, I'll compare it with using a custom solution I've written using the composition api, I know I've lost already but why not 😂

 

VeeValidate have made some effort to halve their bundle size with these tree shaking features ...

baianat.github.io/vee-validate/con...

 

Some effort that doesn't do what is says : github.com/baianat/vee-validate/is...

Using the tree shaking or full have the same sizes. ~ 300kb