DEV Community

heftyhead
heftyhead

Posted on

Let's talk about an unnecessary but popular Vue plugin

A few days ago some news about a popular npm package containing malicious code went viral. The whole incident is a reminder that we should think twice before adding another package to our dependencies.

It also reminded me of an unnecessary Vue plugin that I’ve seen pop up a few times. Vue‘s gentle learning curve makes it a popular choice with beginner developers, for whom it is even harder to figure out what to write themselves and what to install.

The offender

The package/plugin that I want to talk about is vue-axios. If you google “vue axios” it’s the first result. And I think that’s the main reason of it's popularity.

GitHub logo imcvampire / vue-axios

A small wrapper for integrating axios to Vuejs

vue-axios

npm version install size npm downloads jsdelivr License

A small wrapper for integrating axios to Vuejs

Why

I created this library because, in the past, I needed a simple solution to migrate from vue-resource to axios.

It only binds axios to the vue instance so you don't have to import everytime you use axios.

How to install:

ES6 Module:

npm install --save axios vue-axios
Enter fullscreen mode Exit fullscreen mode

Import libraries in entry file:

// import Vue from 'vue'   // in Vue 2
import * as Vue from 'vue' // in Vue 3
import axios from 'axios'
import VueAxios from 'vue-axios'
Enter fullscreen mode Exit fullscreen mode

Usage in Vue 2:

Vue.use(VueAxios, axios)
Enter fullscreen mode Exit fullscreen mode

Usage in Vue 3:

const app = Vue.createApp(...)
app.use(VueAxios, axios)
Enter fullscreen mode Exit fullscreen mode

Script:

Just add 3 scripts in order: vue, axios and vue-axios to your document.

Usage:

in Vue 2

This wrapper bind axios to Vue

Let’s see what a plugin with 1000+ Github stars and 23,000 weekly downloads does. We can start by reading a description:

Usage:

This wrapper bind axios to Vue or this if you're using single file component.

There's also a code example which makes the use of the plugin even more clear:

Vue.axios.get(api).then((response) => {
  console.log(response.data)
})

this.axios.get(api).then((response) => {
  console.log(response.data)
})

this.$http.get(api).then((response) => {
  console.log(response.data)
})
Enter fullscreen mode Exit fullscreen mode

Basically, this package allows you to import axios once and then use it in every component.

It’s actually quite useful. Not only don't you have to import axios in every component but also you can create an axios instance with a custom config and use it in all of them. However, it’s not really mentioned in the plugin's description, therefore I’m not sure if people installing the plugin are even aware of that.

An alternative

We determined that this plugin can be really useful. So what is the problem? Let's code the same functionality without using the plugin:

import Vue from 'vue'
import axios from "axios";

Vue.prototype.$http = axios;
Vue.prototype.axios = axios;
Enter fullscreen mode Exit fullscreen mode

Let's compare it with the code required to configure the plugin:

import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'

Vue.use(VueAxios, axios)

Enter fullscreen mode Exit fullscreen mode

As we can see it takes the same amount of lines to write the whole functionality ourselves as it takes to configure the plugin.

Let's finish by showing slightly supercharged version of this approach of using axios with Vue:

import Vue from 'vue'
import axios from "axios";

const instance = axios.create({
  baseURL: 'https://myapi.com'
});

const instanceUserApi = axios.create({
  baseURL: 'https://userapi.com'
});
instanceUserApi.defaults.headers.common["Authorization"] =
  "Token" + localStorage.getItem("authToken");

Vue.prototype.$http = instance;
Vue.prototype.$httpUserApi = instanceUserApi;

Enter fullscreen mode Exit fullscreen mode

We can create several axios instances each with a different configuration. Not only the plugin doesn't provide any value but it also is less flexible than our code. Just to make it clear the plugin allows you to create many axios instances by passing an object during configuration.

The difference and the excuse

As described in this Github issue:
the different between Vue.prototype and vue-axios? #18

The plugin makes properties(axios and $http) immutable. Which for some may be an advantage over approach described in the previous paragraph. Nevertheless, I'm quite confident that the significant majority of developers using this plugin doesn't really care about immutability.

Conclusion

Vue-axios plugin does what it's description says. There's no dishonesty or anything malicious here in my opinion. Just some uninformed developers that don't think twice about what they add to their projects.

What do you think about such small plugins/packages?
Do you think that creator of such plugins should disclose the alternative?

Latest comments (34)

Collapse
 
moopet profile image
Ben Sinclair

There's a module for Drupal 7 called jquery_dollar. It contains the usual Drupal boilerplate and boils down to this:

var $ = jQuery;

It is (was?) very popular, because people cargo-cult it in and don't understand anything about scope.

There was an app called "Less.app" (I think) that ran on a Mac and watched a directory for changes, and then recompiled the CSS from Less. It did what "Sass watch" does but for Less, and it was totally, utterly and in all ways unnecessary. It sold for 99 cents and was immensely popular, because obvious cargo-cult and shiny Mac reasons.

Every time a new package manager comes along, there's a scramble to re-write everything that's ever been made in a different language, driven mostly I think by people's desire to be able to say they're the maintainer of a project which was already doing quite alright and didn't need a makeover, and hey now it's trailing a version behind and has all-new bugs.

I think wherever you look you'll find these sort of examples. I think you always will. It's not really anyone's failure if they use trivial anti-packages like this, it's just because there's so much to learn and not enough time to question every step you read in most of the tutorials you find online.

Collapse
 
alexparra profile image
Alex Parra

For the sake of decoupling, I think it’s best to only use this.$http even if mapped to axios.
If ever you need to change the library, you won’t need to change all the components (or have a misnomer).
Even better, create an API module that exports specific methods that represent endpoints which in turn use the axios instance.

Collapse
 
whitebookmark profile image
Rein

Oh wow, I never noticed that before. After reading this post I have removed VueAxios from my project, really I don't need it when I am using "this.axios.get..." everywhere, 2 lines of prototype solved it for me.

Thank you for sharing this info

Collapse
 
nektro profile image
Meghan (she/her)

While I would typically agree that a plugin for such a use case, the second block of code is much more in line with how I would want the code to look, from a code quality perspective. Dynamically modifying a prototype you dont control in a system that doesnt actively type check or error/warn for overwriting these properties is a lot worse than the flow of having an extension and registering it to the global object.

Collapse
 
workingwebsites profile image
Lisa Armstrong

Plugins: as many as you need, but no more than necessary.

Before looking for a plugin, I ask myself:

1) How do you code it yourself?
Learn something!

2) Is it worth the time to learn a fix?
I usually put a time limit, if I'm not getting somewhere in 30 minutes with this problem, move on.

3) Will this plugin fix other problems?
I recently used a date plugin because dates are nasty to work with. Life got better.

4) Does the plugin really save time?
If you spend hours fighting with a plugin, find another solution.

5) How many moving parts does this project have, should we add more?
The more plugins you have, the more likely there is to be a conflict... with code you didn't write.

Collapse
 
_wost profile image
William Østensen

At work, we create an Axios object, and just do all the API work in VueX - that way we don't have to worry about writing the axios element all over the code! :D

Collapse
 
leob profile image
leob • Edited

I agree with your last sentence - authors of this kind of pretty trivial package, even when they create their stuff with the best of intentions, would do good to point out the alternative to using their package, rather than selling it as the best thing since sliced bread (which, I'm hasty to add, the author of vue-axios is NOT doing). Authors doing so are benefiting their potential users by educating them.

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

Alt text of image
What do you think about this approach?

Collapse
 
moopet profile image
Ben Sinclair

I think it's too small and blurry for me to read.

Collapse
 
heftyhead profile image
heftyhead

In my opinion, it's a valid approach. Declaring global variables is generally considered a bad coding practice. However, I feel like if you don't abuse it and you are not working on a really big project it doesn't matter as much.

I think that the advantage of using the prototype approach is that usually, you want to make API calls in relation to the component life cycles and events. So making axios available only by components code ensures that API calls are made only in the right moment(you can still pass axios as an argument to a function or a class). This is a quite broad topic so you can easily argue that what I wrote is not always true. Nevertheless, I hope that you can see some advantages of using the prototype approach.

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

Thank you for clarification.

Collapse
 
qm3ster profile image
Mihail Malo

Don't worry, you should just use nuxt-plugin-axios, which wraps vue-plugin-axios for nuxt ;)

Collapse
 
erainey profile image
Eric Rainey

Some great insights here and as far as your questions go, my opinions are:

1) Small plugins/packages can be really useful, and I think this aspect of web development is a carry-over from the jQuery days where you could easily import a script to handle some kind of UI feature without writing your own. It has an appeal in the sense that it is a time saver as well as having some sort of "credibility" as a published open source tool that others have used in their own projects.

However, this leads to relying on plugins being a crutch, and I think that it can hinder developers from improving their skills by leaning on them too much. I know when I first started, I tended to use these scripts a lot, and became frustrated when they didn't do exactly what I needed it to do. This led me to start writing my own solutions and I think that exercise is what helped me improve my own skills.

2) I don't think the onus of offering alternatives should be placed on the plugin developer. Most well-curated plugins have some kind of documentation, and a lot of the times, it has some high-level description of what it does, and perhaps why it was created in the first place. It's often phrased like a sales pitch, but I can understand why. The plugin developer wants people to use their tool; after all, that's why they open sourced it in the first place, right? I think a "buyer beware" policy should be followed by any who want to use these types of tools.

Collapse
 
qm3ster profile image
Mihail Malo

Omg, "jQuery plugins" make my blood boil.

Like:
- here's a vanilla-DOM library
- do you have a version for jQuery?

Or even:
- here's a library of pure functions that don't touch the DOM.
- so modern, so modular! But how do I use it with jQuery?

Collapse
 
maciek134 profile image
Maciej Sopyło

That's because so many people learned jQuery without learning JS, so they were scared of if. Dark times...

Thread Thread
 
qm3ster profile image
Mihail Malo

Well, I was so scared of jQuery, I just avoided the clientside all together until it left.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.