Overcoming race conditions when using a global event bus in Vue.js

To ease communication between components which are not directly related, and when using a state manager such as Vuex seems overkill, Vue.js developers' go-to pattern is the global event bus: while it feels kind of hacky, it most certainly is easy to both use and reason about.

Or is it though? Depending on your specific use case, there is virtually no guarantee the event listeners will be bound before the events are emitted. Wouldn't it be nice if we had some sort of mechanism that could keep the early-emitted values in memory and apply them upon binding the listeners? Why do I keep asking questions when you know damn well the answer lies right below?

import Vue from "vue";

const bus = new Vue();
const lastValues = {};
const originalEmit = bus.$emit.bind(bus);
const originalOn = bus.$on.bind(bus);

bus.$emit = function(name, value) {
lastValues[name] = value;
originalEmit(name, value);

bus.$on = function(name, callback) {
if (lastValues[name] !== undefined) {

originalOn(name, callback);

export default bus;

This is, too, sort of hacky, but it most certainly does the trick, remains lighter than Vuex, and is conceptually not too far away from immediately-applied watchers one can define in their components. Let me know your thoughts!

Generically overriding component render functions in Vue.js

Besides from using templates, Vue.js components can be set up with a render function, allowing one to programmatically determine their output in a more advanced way. Combining this feature with the HOC pattern, it is thus possible to easily create "augmented" versions of any component in an app, which can come in handy in some situations.

For the sake of example, let's picture a scenario where we have a form, and want to display each of its fields twice: the regular version, and a disabled version, displaying a recommended value based on business rules.

The resulting HOC might look something like this:

import clone from "clone";
import getDisabledVersion from "./getDisabledVersion";

export default function withRecommendedValue(originalComponent) {
const component = clone(originalComponent); // deep-clone component to avoid reference errors
const originalRender = component.render;
const recommendedValue = /* fetch it from wherever */;

component.render = function(h) {
return h("div", {}, [
getDisabledVersion(originalRender.call(this, h), recommendedValue), // disabled doppelganger
originalRender.call(this, h) // original component

return component;

originalRender.call(this, h) will give us the component's rendered virtual DOM tree as a JSON object, which can then be amended by our getDisabledVersion function, overriding its value and disabled state. The recursive nature of this function implies that it will possibly deal with multiple cases:

  • if our component only contains plain DOM nodes, we will be looking for form controls (i.e. input, select, or textarea) and update their attributes directly; other DOM nodes will be checked for children to call the function upon
  • on the other hand, if our component contains other components, we will rather be interested in their props; specific value handling/transformation that was handled by our own component, if any, will also have to be done here

And this is where the magic happens:

export default function getDisabledVersion(el, value) {
if (["input", "select", "textarea"].includes(el.tag)) {
// Form control node
el.data.domProps.value = value;
el.data.attrs.disabled = true;
} else if (el.componentOptions) {
// Component
// Do dirty things to value if relevant
el.componentOptions.propsData.value = value;
el.componentOptions.propsData.disabled = true;
} else if (Array.isArray(el.children)) {
// Something else, we need to go deeper
el.children = el.children.map(child => getDisabledVersion(child, value));

return el;

Finally, to use the HOC:

Vue.component("MyComponentWithRecommendedValue", withRecommendedValue(MyComponent));

Of course, with the upcoming uprising of version 3.0 and its composition API, this pattern might soon be a thing of the past; I'm eager to see how it will make this kind of voodoo trick easier (or not). Feel free to drop knowledge about it in the comments if you have some!

Sharing a Webpack vendor bundle across applications

If you find yourself maintaining standalone, yet related SPAs, and you would like your users to benefit from their browser's cache to download some third-party code they have in common only once, Webpack has you (pretty much) covered thanks to its DllPlugin, which is actually part of a duet along with DllReferencePlugin. To make a long story short, the former allows you to generate, through a separate build, a standalone bundle and an accompanying manifest file, whereas the latter takes these two as input and in consideration in the context of a full, regular build. Let's get started!

We will assume one of the apps will bear responsibility for building the common bundle. As I mentioned earlier, this implies creating a separate, specific Webpack config:

const webpack = require("webpack");
const path = require("path");

module.exports = {
entry: {
commonVendors: [/* list the names of your common dependencies here */]

output: {
path: path.join(__dirname, "vendor"),
filename: "[name].js",
publicPath: "/",
library: "Vendor"

plugins: [
new webpack.DllPlugin({
context: __dirname,
path: path.join(__dirname, "vendor", "manifest.json")

You might need extra stuff, like setting up loaders to support your framework's DSL, if any - I will leave that up to you. Let's build!

$ webpack --config path/to/specific/config.js

This should result in the creation of a vendor folder, containing commonVendors.js and manifest.json files. Now, on to our main config:

const webpack = require("webpack");

module.exports = {
// ...

plugins: [
// ...

new webpack.DllReferencePlugin({
context: __dirname,
manifest: require("./vendor/manifest.json"),
name: "Vendor" // this has to match output.library in the specific config

If you run your build as usual (and you ran the first one already), you should notice a decrease in your regular bundles' size! Of course, make sure to add a <script src="path/to/vendor/commonVendors.js"></script> tag to your HTML page.

OK, so we now have a separate bundle that we can use in this one application. How should we proceed to benefit from it in another build? Well, that is really up to you and your concrete use case: there is, to my knowledge, no perfect solution given it will always imply build coupling. Feel free to drop your knowledge in a comment below!

Just as a proof of concept, let's have it working in development though: have commonVendors.js and manifest.json available through a local server or, like me, just rely on the filesystem, and in your second app's Webpack config, make use of DllReferencePlugin as well:

const webpack = require("webpack");

module.exports = {
// ...

plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require("../path/to/manifest.json"),
name: "Vendor"

Once again, you should see your JavaScript footprint decrease, and no lack of code if you correctly import the common bundle file in your app!

Mock current time with Moment.js or Day.js

When writing unit tests for JavaScript code relying on Moment.js or Day.js (a lightweight alternative to the former, with pretty much the same API) to handle date-related shenanigans, one might find themselves in need to mock their library of choice when its main function is used with no parameters, to obtain a representation of current time.

The mock we actually need to set up in such a case is actually a partial one: we want it to act as a proxy for parameterized calls, passing them down to the original implementation, while returning a fixed value otherwise. Thankfully, Jest grants us the possibility to do so fairly easily:

jest.mock("dayjs", () => jest.fn((...args) => jest.requireActual("dayjs")(
args.filter(arg => arg).length > 0 ? ...args : "1989-03-21"

As you can see, the aforementioned original implementation is available from within jest.mock's scope through the use of jest.requireActual, allowing us to check if it was called with or without parameters, and pass a fixed value in the latter case.

Congratulations, you are now able to freeze time!