Liferay Gradle Yarn Workspaces

Optimizing your JS builds in the Liferay Gradle Workspace by incorporating a Yarn Workspace

Introduction

In a recent blog I explained how to create a React-based portlet within your Liferay Gradle Workspace by using the js-widget Blade template which in turn uses the Yeoman Liferay JS Generator to create the project.

(Wow, that was a mouthful ;-) )

In this way, you can have your Liferay Gradle Workspace take care of building your complete suite of Liferay modules, the customizations and the portlets.

The Only Problem With This Is...

Well, as soon as you get like 3 or 4 of your JS-based portlets in your Liferay Gradle Workspace, you see that your build times just blow up.

Why? Well each of your JS modules are separate JS projects: they each have their own package.json files, they each manage their own set of dependencies, they each download the dependencies and they each end up with their own set of components that can sometimes be duplicated across each other.

It's this repetition across what each individual JS module is doing that makes your builds take forever. And each additional JS module, while being easy to create and develop and may work great in the portal, well they just add to your build time.

And this can be exacerbated in a CI/CD setup since each build starts with a clean slate, so each module needs to download and resolve its own Node artifacts and dependencies.

Can we still have the goodness of all the JS modules yet reduce our build times? Sure we can!

Yarn To The Rescue

I'm just going to assume that you already know about NPM and Yarn and that you're aware that Yarn still has some performance leads over NPM because of its dependency handling. If you want to know more about the NPM vs Yarn, I found a nice article which provides an objective comparison: https://www.whitesourcesoftware.com/free-developer-tools/blog/npm-vs-yarn-which-should-you-choose/

To leverage Yarn in your Liferay Gradle Workspace, first you need to have installed Yarn, but next you just add the following to your gradle.properties file in the workspace:

liferay.workspace.node.package.manager=yarn

With this setting in place, you're ready to start using Yarn (and its caching capabilities) to reduce your build times.

If you add this to an existing workspace, you have a little more work to do before you're good to go. Sweep through your modules and remove all of the node_modules folders as well as any package-lock.json files. You need to do this, otherwise Yarn will use what is already there instead of switching over to the shared Yarn cache.

Outcome

So you might be wondering if switching to Yarn will really do anything for you.

I don't have really good numbers to share, but I do have an anecdote. On one client we worked with that had a large number of JS-based modules using NPM, their build time on CI/CD went from ~3.5 hours to ~12 minutes...

Will you see the same kind of performance improvement? I can't promise you anything because of course it will depend upon your workspace, how many modules you have, whether you are using consistent versions, ...

You should expect an improvement in build times though since Yarn is using a shared cache for the Node artifacts and dependencies.

If switching to Yarn improves your build times, drop a comment below and provide the timing details. Perhaps together we can move from basic anecdotes of improvements to some real data showing the impact of the switch.

Happy Yarning!

1