From Gruntjs to Webpack

Yazan Aabed
5 min readApr 13, 2018

This article to narrate the adventure when upgrading an AngularJS project from Grunt to Webpack.

Photo by Tyler Franta on Unsplash

The first thing that came to mind was refactoring the whole app to use webpack, modules, babel, and es6. After researching, it is possible to do this without any refactoring of the codebase. But, there are many problems to solve before adding the webpack to the project.

Problems to consider before starting to work

  • How to solve the window object problem, because webpack shows files as a tree of files talking to each other.
  • How to make fewer changes to the project without merging issues.
  • How to split between development and production.
  • How to remove bower dependencies.
  • How upgrades to webpack solve the big size of JavaScript files.

Start to break things into steps

Upgrade the node version from 0.10 to the latest version available

Before starting moving to using webpack, Node.js needed to be upgraded. But, Grunt is using an old version of node.js and a lot of deprecated things.

First, an error accrued on old grunt-sass & node-sass. It’s not supported anymore for this version of Node. To fix this, a grunt-sass is upgraded from ‘0.18.1’ to ‘2.0.0’, then node-sassupgraded to be ‘4.7.2’.

Secondly, trying to upgrade grunt from ‘0.4.5’ to ‘1.0.0’ didn’t work, because the grunt plugins need grunt@0.4.5 as peer dependency. So stuck with 0.4.5 version.

Remove deprecated things

  • Debug attribute from grunt-express because it is deprecated on the node-inspector new version.
  • Remove the bower-install task from the project.

Start by adding webpack

I added webpack to the project using npm install webpack--save-dev. Then I added the webpack.config.json file.

When I started this step, I got stuck because the project structure has no entry point. The whole project depends on one source which is the window. Webpack needs an entry point to start with and an output point to end with.

To solve this, I created an entry point. I set all the needed files on it and named it the same name on GruntJS config to concatenate it as the old Build did. But this was going to take a long time, because about 550 items were included in index.html.

To solve this problem, I used a RegExp /”(.*?)"/ig and replaced the values by require(src)to get the sources from the src attribute and convert it to require(src). I pasted it to the entry.js on the same order as the old index.html.

After this, the result was a significant JS file containing all scripts. But nothing worked! After investigating what was happening, it seemed that webpack was working by default as modules. If there are exports or export default on the same file, nothing will be exported to the outside even if you include it using require js.

Before searching for a way to solve this, I start adding module.exports to all files needing to be exported — before clearly understanding how webpack works! After two days of working, I found that there is something called loaders which solve the problem.

By adding this to webpack.config.js, all the files were now available as the old behavior!

And everything was now working.

Next step

After I made the project works with Grunt, I needed to make sure both webpack and Grunt worked together. So I made tests to make sure I didn’t miss anything.

To make this happen, I create a new file called inject-HTML.files.json. This file contains all source files to use with usemenPrepare on Grunt and webpack to create the entries as multiple items as arrays taken from the inject-HTML files JSON.

Update the old Grunt config file

Add files to concat

Check if Webpack builds, then remove the JS from configurations

Add new npm script

Webpack.config.js file

Webpack.prod.js file

Motivations

Maintainability and Code Quality

  • Solve the problem with creating files, as the project is growing fast.
  • Solve the problem that there are too many things attached to the window without reason.
  • Make the codebase easier to understand.

Development Efficiency

  • Bower is now deprecated.
  • Can’t use any things on npm packages, because the build process does not provide this.

Performance

  • Files sizes are growing bigger every day, so need to introduce a solution to split the code.
  • Being able to split files and defer loading until needed saves unnecessary transfer and parsing.

Code splitting

  • After use, webpack Code splitting will be easier to use.
  • Split new features into modules-based.

Finally, using the npm packages is a game changer. The goal was to make the codebase easy for other developers. Also, we proved that it’s possible to upgrade your system wisely even if your code base is terrible.

Rewriting the whole app is a disaster, because you are potentially wasting years of hard work. Instead, try to make your codebase more readable, maintainable, and modular. When the old code needs refactoring, you can do it step by step.

Don’t get stuck with your old codebase and say you can’t do anything to it. Try to make changes by yourself — live with new things, new updates, and new technologies that will make you happy.

This is my first time writing for people! If you liked this article, please share it with other people around you.

--

--