December 20, 2017

Tech Stack Modernization, Volume 3: Webpack and NPM

by Dave Sweeton

Tech Stack Modernization Volumes 1 and 2 covered my thought process behind modernization and a review of Angular. Volume 4 will review my selected framework, (spoiler: it's Vue.JS), but before I get there I want to write a bit about Webpack and NPM. Both of these are tools that can be used with any tech stack (Angular, React, Vue.JS, etc.), and they bring their own benefits and pain!

Webpack
Webpack is a "module bundler," but I think of it as a highly configurable build tool that can be plugged into your project's tool chain. At its most basic, you process files with Webpack, transform them with various 3rd party loaders and plugins, and then output something different. Sounds pretty similar to a compiler or a tool like MsBuild, and it is except that it's easier to extend so it can be used for many more purposes. Here are some common uses:

  • Read in many JavaScript files, shrink the code (minify), obfuscate it and output to a single JavaScript file (which is better for network efficiency).
  • Read in Typescript, CoffeeScript or the newest JavaScript syntax and transpile it to a version of JavaScript that can be handled by most browsers. Transpiling is similar to compiling, except instead of source in and binary executable out, you get source in and some other source out.
  • Process CSS styles in some language other than CSS (like Less, Sass or Stylus), and output to plain CSS (again maybe merging multiple files into one).
  • Run various linters to check your code for possible issues, or run unit or integration tests.

Webpack has a neat development time feature called Hot Module Replacement. This basically runs Webpack as a local web server, which monitors your input files and reprocesses them each time they change. You write your web app to load scripts from the Webpack dev server, and it automagically refreshes your scripts, CSS (and templates for a framework that supports it) every time the files change, without refreshing the browser! It's pretty cool to edit a file, save it and then see it appear in your browser instantly. It does have some extra challenges associated, but for the most part works pretty well.

Webpack also helps solve module dependencies. You can use require() calls—or better, the new #import statement—in your script files to load other scripts using relative paths. Those dependency chains will be resolved by Webpack and used to process only the files that are actually in use by your application. When using #import, you can bring in only the functions or classes you actually need, and if the same code is imported by multiple locations, it will ensure you only get one copy in the output. This makes your JavaScript code more self-contained and easier to maintain.

This is also used to support an advanced feature called code splitting. Imagine you have a Single Page Application (SPA) with 10 different areas (or views or whatever) in it. You can use code splitting to put the code for each area in different bundles, which can be downloaded dynamically only when the area is actually accessed. This is pretty easy to enable, and adds a huge performance boost when users first load your application. They would only need to download a main script and the script for the first area, instead of all 10 areas.

Webpack is not without downsides however. It has notoriously poor documentation, and while it has a lot of configurability, you can expect to spend hours setting up the proper configuration and debugging your build chain. I fell into plenty of rabbit holes with Webpack and 3rd party loaders. I eventually got where I wanted to go, but not without some frustration along the way.

Given that (arguably big) downside, should you use Webpack? I'd say absolutely. First off, you will need it (or something similar) in your build chain for any modern framework. Even aside from that, I'd argue that Webpack is worth the effort just to use the new features available in Typescript (or ECMA script 2015) and have it compiled back to browser safe JavaScript. Once you get used to the new features, programming in "old" JavaScript is painful!

You could instead look at a Webpack competitor (like Gulp or Grunt) to get similar functionality. I focused on Webpack because it's widely used, has active 3rd party loader/plugin development, and a developer I trust said that Webpack had won and we should just use it despite the configuration headaches!

NPM

NPM is the Node Package Manager. It is like every other package manager (yarn, NuGet, Bower, RubyGems, etc.). It runs on Node.JS and focuses on JavaScript libraries. It's commonly used with Webpack, but it is separate and can be used entirely on its own.

I have a love/hate relationship with every package manager. I like how easy they make it to grab modules and libraries. I like how they automate managing dependency trees (package A needs package B, which in turn needs package C). The downside though is that they lead to a "kitchen sink" style of programming where packages are added without much thought, and each brings in a host of dependencies—so many that you can't actually be aware of all of them. It becomes a huge black box.

NPM is worse in that regard than others I've used like NuGet, probably just because JavaScript makes importing dependencies so easy. I don't know that I can recommend NPM over any others; it's just the one I use because it's popular, has a lot of modules, and it works well. My only complaints are that it's slow to do a full "npm install" (which I only do for release builds) even if the modules are already downloaded, and that it sometimes churns the package definition files that are checked into source control. I'm hoping the latter is just due to recent changes in NPM and will stop as kinks are worked out.

Modern web development requires aids to support and optimize common use cases like SPAs, and to speed development and improve maintenance. There is no shortage of tools available, and picking a winner is difficult. I hope that you can leverage my experience with Webpack and NPM in your own research into the right tools for your tool chain. Good luck!

info@stoutsystems.com
877.663.0877
© Copyright 1995-2018 - STOUT SYSTEMS DEVELOPMENT INC. - All Rights Reserved
envelopephone-handsetlaptop linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram