The great CommonJS debate of 2023

Issue #202.July 6, 2023.2 Minute read.
Bytes

Today’s issue: A new CLI tool for your side hustle, JavaScript Gom Jabbar, Vite stock, and JavaScript inflation.

Welcome to #202.


Eyeballs logo

The Main Thing

Mark Zuckerberg on his foil surf board waving an American flag

Zuck off to fight in the latest JavaScript battle.

The great CommonJS debate of 2023

As we Americans celebrated our Independence Day on Tuesday, I took time in between my third and fourth hot dogs to reflect on how our founding fathers fought for our most basic human right — the right to start pointless JavaScript arguments on the internet. 🫡

The Deno and Bun teams were obviously feeling that same holiday spirit when they reignited an old debate about the future of CommonJS right before the holiday weekend. Here’s what happened.

Last Friday, Andy Jiang wrote an article on the Deno blog about how CommonJS is hurting JavaScript. He argued that, much like The Black Eyed Peas, CommonJS was exactly what the world needed back in 2009 — but that it doesn’t hold up very well today.

  • CommonJS modules load synchronously, which can lead to blocking behavior.

  • It’s difficult to tree-shake CJS modules, which can lead to bigger bundle sizes.

  • CJS modules aren’t browser native, so you need bundlers and transpilers to make your code work client side.

As you probably know, The TC39 team released ES Modules back in 2015 to address these specific problems — so Andy argued that it’s time for us to “bury CommonJS and transition into an all ESM future.”

The rebuttal: Jarred Sumner and the Bun team might have felt like that article was a bit of a subtweet from their fellow runtime rivals, since Bun’s recent release notes explicitly mention CommonJS support.

So later that same day, Jarred dropped his own diss track blog post titled, CommonJS is not going away unless you pry it from my cold, Thiel Fellow fingers. (Ok I added the last part.)

In the article, he argues that CommonJS actually starts faster than ESM for larger applications, and it enables dynamic module loading — by allowing you to require() a file conditionally or require() in the body of a function.

But his most compelling argument is that CommonJS is “already here to stay.” CJS still has dominant market share, despite ES Modules being around for close to a decade now, and it still has “real reasons to exist” — hence, Bun’s treatment of CJS as a first-class citizen.

Bottom Line: Andy’s critiques come at an interesting time for Deno, considering the team made a hard pivot last year to embrace compatibility with Node and npm. My bet is we’ll continue to see this type of pragmatism from Bun and Deno, as the two VC-backed runtimes try to grow as fast as possible.

        

secureframe logo

Our Friends
(With Benefits)

Kermit with money on top of him in a sink.

Drowning in that enterprise customer cash.

Secureframe makes SOC 2 compliance easy

Getting SOC-2 certified is kind of like eating your broccoli — you know you should do it, but you keep putting it off because you know it’s going to be gross.

But that’s why thousands of companies use Secureframe. They’ve automated the entire compliance process for SOC 2 and security and privacy frameworks like ISO 27001, GDPR, and NIST. So now you can get certified in weeks, instead of months, with way less engineering hours.

And that’s one of the best investments you can make — because getting those security certifications allows all those big companies (with big budgets) to become your customers 🤑.

Set up a free, personalized demo — and they’ll help you get all those fancy security compliance badges on your homepage ASAP.


Tip logo

The Tip

Sponsored by Callstack

Learn how module federation allows separate teams to work together without blocking each other. Sign up for their 1-hour super app development training, and get two first lessons for free.

JavaScript has at least 20 different ways to loop over things, including all of the array methods, like forEach, map, and filter, recursive functions, and while, and for.

For array methods and recursive functions, you can end a loop early with a return statement, but if you were to use a return statement in a while or for loop, it would end the entire function, which is not ideal. Instead, if you want to jump to the next iteration of the loop, you can use the continue statement, like so.

for (let i = 0; i < 10; i++) {
  // Skip multiples of 2
  if (i % 2 === 0) {
    continue
  }
  console.log(i)
}
// 1, 3, 5, 7, 9

The break statement lets you end the loop prematurely, without running any more iterations.

for (let i = 0; i < 10; i++) {
  // End the loop when we get to a multiple of 3
  if (i % 3 === 0) {
    break
  }
  console.log(i)
}
// 1, 2

These two statements work great for individual loops, but what if we needed to coordinate nested loops? If we just used break or continue inside the inner loop, it wouldn’t be able to stop or skip the outer loop.

const numberList = [1, 2, 3, 4, 5]
for (let i = 0; i < numberList.length; i++) {
  const iNum = numberList[i]
  for (let j = 0; j < numberList.length; j++) {
    const jNum = numberList[j]
    if ((iNum * jNum) % 2 === 0) {
      // This continues the inner loop if the number is even
      continue
    }
    console.log(iNum * jNum)
  }
}
// 1,3,5,3,9,15,5,15,25

To let us call continue or break on the outer loop from inside the inner loop, we need to apply a label to the outer loop. The label goes right before the for statement. Then, we can use the label with the continue statement. Notice how the results change once we add the label.

const numberList = [1, 2, 3, 4, 5]
outerLoop: for (let i = 0; i < numberList.length; i++) {
  const iNum = numberList[i]
  for (let j = 0; j < numberList.length; j++) {
    const jNum = numberList[j]
    if ((iNum * jNum) % 2 === 0) {
      // This continues the inner loop if the number is even
      continue outerLoop
    }
    console.log(iNum * jNum)
  }
}
// 1,3,5

Next time you need to nest loops for some reason, you can use a label, break, and continue to have more control over the flow of your loops.


Cool Bits logo

Cool Bits

  1. Jacob wrote about Breaking Up with SVG-in-JS in 2023, then proceeded to listen to the 10-minute version of All Too Well 27 times while sobbing into a pint of Ben & Jerry’s.

  2. Vite 4.4 just came out with experimental Lightning CSS support and new create-vite starters for Solid.js and Qwik. Vite stock continues to climb 📈.

  3. Lenz shared his take on the current React & Server Components controversy, based on his unique perspective as a library maintainer for Apollo Client, Redux Toolkit, and RTK Query.

  4. Stream is the easiest way to build in-app chat and feed experiences. They’re used by apps like CodePen, SoundCloud, Strava, and more to serve billions of end users. Try it free. [sponsored]

  5. Alex Kotliarskyi wrote a fun article titled, JavaScript Gom Jabbar, because he’s discovered that packing Dune references into your technical blog post is basically a cheat code for hitting the front page of Hacker News.

  6. Addy Osmani made a 35-minute video on The Cost of JavaScript in 2023. Nothing is safe from inflation.

  7. Ahmad Shadeed wrote about State Container Queries, which the Chromium team has been experimenting with lately.

  8. Maas Lalani created Invoice, which lets you generate invoices from the command line. This will be a perfect way for me to invoice all my clients for my new high-end real estate photography side hustle.