Build Tools Demystified - My Thoughts
August 15, 2019
Hi again! Another prep post for a work talk I'm giving. The talk isn't until the start of October, so if you're reading this post after that point I hope it helps you. This one will probably be followed up by another one that takes a more "talk in a post" approach, whereas this one will be "thoughts regarding the topic that are unorganized". It's probably pretty rough, but I figured I would put it out there in case there's interest. If that's your jam, feel free to read on and I'd appreciate any feedback that you have!
When using Next.js it includes configuration and support for Babel and webpack. Their out-of-the-box configurations are pretty solid, and in most cases easily extendable. For instance, we've included a babel configuration file in our stack that sets up the styled-components babel plugin, and that has been relatively painless to have an keep up to date. Other build tools that we've helped projects work with include Gulp and Grunt, though we don't have many projects with changing Gulp/Grunt setups at this point. Most of those are the legacy AngularJS projects and since they don't change all that often we're not going to talk about them in this post. As such, I'll be focusing on Babel and webpack.
webpack is a Bundler that will take the files you give it (usually called "entries") and gather all the assets/code that are referenced into a set of files that are ready to serve to the browser.
One of the greatest features of webpack and babel is extensibility through a
vast plugin ecosystem. In a lot of cases, people will utilize Babel within
webpack through something called
babel-loader. Loaders are used by webpack to
customize how file types are bundled in the pipeline, and so
used to run files through Babel before being bundled by webpack.
In either case (using Babel directly or within webpack), the configuration files are where a lot of the "magic" happens that I'll be de-mystifying through this talk I'm going to give. The goal of the talk is for people to have a working vocabulary they can use when googling the different things they might need to while working with these tools as well as provide them with some strategies for working with them. One of my biggest goals is to have people be less scared of tinkering with the tools, since more often than not you just need to give it a try and see if it works.
Both of these fantastic tools have thorough documentation, and one of my favorite sections of the webpack docs is called "Concepts" since it gives a great high-level overview of the main things going on with webpack. Those main concepts include:
While Babel doesn't have a "Concepts" page, there are still some major concepts that are important to understand in order to work with Babel from a consumer standpoint. In my opinion that includes ideas and things like the following. Note that I wouldn't recommend sitting and reading through any of these links since they're pretty dense.
- Config File Types
- That a Babel Handbook exists
preset-envis since it's one of the most common presets
So, while Babel might not have a dedicated docs page to describing their major
Concepts, these are the things I find people would get the most benefit from
understanding. Since the linked to docs pages are a bit dense, here are some
working definitions/views that I have for these topics. Plugins are the things
that actually give Babel behavior and capability. If you don't use any plugins,
Babel will just give you the code you gave it. There's a couple types of
plugins-Transform and Syntax. Syntax plugins are the more straightforward ones
to understand since they enable Babel to even parse the feature. While they're
simpler to understand, they're rarely used directly since merely parsing a
language feature doesn't do much good for the consumer of that code. Therefore
Transform plugins will load the Syntax plugins they need and transform the
relevant code to the desired output. Because it can be tedious to configure and
load all the plugins you might want in each project, Babel allows for Presets,
which are groups of plugins that are pre-configured. In both Presets and
Plugins, along with lots of other things about Babel the idea of passing in
options is super useful. Options allow for plugins and presets to adapt based
on the target environments that you have, the "mode" that you're in (similar to
webpack), or any other thing that they've been setup to handle. With babel,
there's a multitude of tools that utilize it and passing presets and plugins
through the command line can get pretty tedious, so there are a number of config
file types available to you, with two major kinds - Project Wide and File
Relative. The one that you'll generally want to use in application-type projects
or monorepos as of this writing is the Project Wide
Libraries will generally use a File Relative config, like a
.babelrc file (or
something in their
package.json file depending on how complex their
configurations are). If you do ever decide to write anything that other people
will use with Babel, the handbook linked above is an excellent resource. The
plugin handbook is super helpful if you're trying to debug someone else's
plugin, since they likely used that while writing it. In most projects that I've
seen, they utilize the
preset-env provided by the babel team. The docs on that
are excellent, so I'd recommend checking those out if you're going to be using
it directly. Thankfully, Next.js handle a lot of the configuration for us and
even provides a preset we can use to extend their configuration (which we did to
add styled-components support).
I think that's all I'm going to get to so far as my thoughts on the overall topic today. I might throw out some other, more detailed and specific posts as I continue to refine what I'll be talking about. Thanks for reading!