DEV Community 👩‍💻👨‍💻

Cover image for Is it Webpack or Node?
Laurie
Laurie

Posted on • Originally published at laurieontech.com

Is it Webpack or Node?

Originally published on laurieontech.dev

Webpack is known as a bit of a bear. Yet, it's used in a large percentage of frontend projects. There is a lot to Webpack, and I won't go into all of it today, but I did want to talk about certain aspects.

I often say that one of the most important pieces of information when debugging your project is knowing what technology is responsible for the error you're seeing. It helps you google more effectively, helps you narrow down what changes might be causing the issue, etc.

Thanks to leaky abstractions, understanding when an issue is Webpack or Node.js is not as obvious as one might think. So let's talk about it!

Node.js

I wrote a post a little over a year ago called The Layers of JavaScript. The reason I bring it up now is that it's important to remember that npm is bundled into Node.

Npm is a package manager. And npm listens to a package.json file to determine what dependencies and versions to install. The result of running npm install lives in your node_modules directory.

Insert joke about the size of that directory here.

If you've gotten your package name wrong when listing it in package.json, or tried to reference a version that doesn't exist, npm will yell at you when you try and install dependencies. But as long as those things exist, and npm can install them, it doesn't care.

Webpack

This is where Webpack comes in. Lots of modern tools abstract Webpack configuration away from you. But the goal of Webpack is to bundle resources so a browser can use them.

The result, is that your dependencies exist as static assets that your code can reference. Ever seen code like this before?

const React = require("react")
Enter fullscreen mode Exit fullscreen mode

Well, this is where things get a bit confusing.

Overloading require

Node.js follows CommonJS conventions and includes require as a built-in function. require allows you to reference JavaScript in other files.

Webpack supports a number of different specs, including CommonJS. So require is also valid Webpack syntax. However, Webpack's require is more powerful than the same function in Node.js. It uses enhanced-resolve and allows you to reference absolute paths, relative paths and module paths.

Webpack also includes a function called require.resolve. This function takes a module name and returns a string that contains the path to the module. The difference between the two is sometimes confusing, so I wanted to include that callout here.

Supporting multiple standards

As mentioned before, Webpack allows for multiple different syntaxes (though it recommends you stay consistent within your project). One of those is ES6. The rough equivalent of require in ES6 is this.

import React from "react"
Enter fullscreen mode Exit fullscreen mode

Here is where stuff really gets interesting. ES6 and CommonJS are not the same spec! So even though both are valid in Webpack, they often aren't elsewhere in the ecosystem. And since Webpack is bundling lots of different types of files for you, it can be challenging to keep things straight.

Node.js

At this moment, ES6 import syntax is not valid in Node.js. If you want to support it you can use the experimental package esm.

This means that files that run server-side, taking advantage of Node.js runtime, likely need to use require.

Babel

Conversely, a lot of JavaScript files run in the browser. These files are often built with Babel. If you're not familiar with Babel my post on the ECMAScript Ecosystem is a good primer.

When Babel compiles your code, it turns all of your imports into Node.js require statements (not Webpack ones).

It's worth noting that Babel output typically needs to be bundled by Webpack, so a bit of a Twilight Zone moment there.

Debugging

With all of that background it becomes a bit easier to determine where an error like Cannot find module 'react' is coming from.

It may appear because it's referencing a dependency you don't have installed in your project. Make sure it's installed, and then make sure you're referencing it properly, no typos!

Conversely, you may see that error because Webpack didn't bundle your files where Node expected to find them. Take a look at your file path.

Not an expert

I've spent a fair time debugging these various issues and the thing I've come to recognize is that error messages go a long way. With so many packages and tools bundling Webpack for us, it's important to make sure the debugging information we get is as helpful as it can be!

Top comments (5)

Collapse
 
gypsydave5 profile image
David Wickes

Very good overview. Also reinforces my view that developers should add the minimum required amount of tooling to get the job done.

At its worst, modern JavaScript development can feel like balancing on top of a stack of wobbly chairs. It's so very complected, with every layer bleeding into the next. The only way to really control this (mostly incidental) complexity is to get rid of some of the layers.

Collapse
 
timhlm profile image
moth

Great article 🙌

One small note- you can actually use es6 modules in Node > v13!

Collapse
 
laurieontech profile image
Laurie Author

You can indeed. But it's so new I don't expect most people to be using it yet :)

Collapse
 
alistaiiiir profile image
alistair smith • Edited on

Although, Node 14 now has the warning removed (although the support is for the most part still experimental unfortunately). I'll still be using Babel for things like this?.prop, though :P

Screenshot

Collapse
 
sqlrob profile image
Robert Myers

I would so love to. Because of Google cloud, I'm stuck on 8 and 10. I'll probably be able to use 13 sometime around 2050.

This post blew up on DEV in 2020:

js visualized

🚀⚙️ JavaScript Visualized: the JavaScript Engine

As JavaScript devs, we usually don't have to deal with compilers ourselves. However, it's definitely good to know the basics of the JavaScript engine and see how it handles our human-friendly JS code, and turns it into something machines understand! 🥳

Happy coding!