Problem: Babel isn't compiling my code how I expected


Like many Webpack 5 projects, it is common to add in loaders such as babel-loader. These tools are typically something that can help process files for your application and added to the graph what things depend on each other.

Problem

However, I learned that babel-loader right out of the gate isn’t going to compile your code down to the browsers you need it for without it explicitly targetting it. Here’s how I came acrossed it and solved it with browserslist.

Background

For my first custom Webpack configuration I wanted to start with a common path: I wanted to make sure I understood how Babel gets added to Webpack and compiles my code. I ended up adding it to my devDependencies with npm i -D babel-loader. In order for my Webpack to understand that it should consume this new loader, we need to add it to to our module.rules:

const path = require("path")

module.exports = {  
  mode: "production",
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.bundle.js'
  },
+  module: {
+    rules: [
+      {
+        test: /.m?js$/,
+        exclude: /(node_modules)/,
+        loader: 'babel-loader',
+        options: {
+          presets: ['@babel/preset-env']
+        }
+      }
+    ]
+  }
}

To be brief about these additions:

When I put this in and ran Webpack, I noticed the output looked exactly the same way it was before without any Babel step.

Minified code for my babel compiled code with no browserslist

This made me curious: “Does this mean it isn’t working?“. After some trial and error, I went to Twitter to ask about it and a colleague mentioned that I was missing my browerslist.

The browserslist is a way to specify targets for browsers or node for frontend tools! You can add this either through the explicit .browserslistrc file, or more commonly, add it into your package.json. Otherwise, Babel may not try to actually compile it down to the environments you’d expect. And that’s exactly what was happening for me!

So in my package.json I targeted greater than 0.25% of browser versions that aren’t dead:

{
  "name": "example-full-repo",
  "version": "0.1.0",
  "description": "This is going to represent following through the Modern JavaScript Tooling with React course by Andy Van Slaars.",
  "main": "index.js",
+  "browserslist": "> 0.25%, not dead",
  // rest of the file ...

Once I did that, it seems as though Babel recognizes: “Oh hey, I am no longer targeting nothing, I should make sure that this JavaScript compiles down to the browsers it might get used on.”

Minified code for my babel compiled code with a set browserslist

Thank you Rob for sleuthing this down! With this written down, hopefully I won’t come across a bug like this again. And it will serve as a good archive for others who might come across this same problem on their webpack learning journey!