Hitting your (Bundler) Macros

Issue #275.March 28, 2024.2 Minute read.
Bytes

Today’s issue: You’ll finally learn what macros do, why Typescript doesn’t throw, and what BBQ sauce can teach you about life.

Welcome to #275.


Eyeballs logo

The Main Thing

Bodybuilder making a protein-packed meal

Just a little more JavaScript should do the trick

Hitting your (Bundler) Macros

Parcel recently added support for Macros, playing a little catchup with Bun, who implemented this feature last year.

So what do macros actually do, and why are they the hottest build tool trend out there right now? Let’s dive in.

Bundler Macros are built on top of the import attribute spec and provide a mechanism for running JavaScript functions at build time. The value returned from these functions are directly in-lined into your bundle, instead of being bundled into the output.

It’s kind of like SSG for your JavaScript bundle, but there are some limitations. For example, all of a macro’s arguments must be statically analyzable (the value has to be constant or the result of another macro).

That said, macros can definitely save you from having to do extra work writing custom plugins in a few common scenarios:

  • Inlining Code — You can use bundler macros to remove the runtime cost of using a library. For example: regexgen(['foobar', 'foobaz', 'foozap', 'fooza']); compiles to /foo(?:zap?|ba[rz])/.

  • Making fetch requests at build time — If your application has some remote configuration settings, macros will allow you to fetch that data at build time and bundle everything with the proper config.

  • Generating Assets — You can implement things like CSS-in-JS with static extraction (aka the holy grail) using a combination of macros and Parcel’s addAsset.

Bottom Line: If you’re running a lot of code at bundle time, you’d probably just want to run a server instead, but it’s nice to have macros as an option.

        

Sonar logo

Our Friends
(With Benefits)

A man staring at his computer with disappointment

When your Copilot code betrays you

Sonar makes sure your AI code is clean, secure, and reliable

We all love it when AI copilots write boilerplate code for us — but you’ve also probably been burned by AI code that’s janky and unsecure.

That’s where Sonar can help. Their Clean Code Solutions monitor all your AI-generated code to make sure it’s reliable, secure, and easy for humans to maintain.

Here’s how it works:

  • It automatically finds and helps remediate the quality and security challenges that come from combining AI and human code.

  • It uses powerful static code analysis to detect bugs and vulnerabilities in your entire codebase (one team used it to achieve zero technical bugs in the last 2 years)

  • It automates code reviews for your team and guides you to fix issues in both the IDE and DevOps workflow

Check it out — and never get burned by sketchy AI code again.


Pop Quiz logo

Pop Quiz

Sponsored by STRICH

Their JavaScript library gives you a fast, real-time, multi-format barcode scanner you can easily add to any web app. Check out the free demo app or 30-day free trial.

How can you remove the event listeners from this element without calling removeEventListener?

const element = document.querySelector('button');

element.addEventListener('click', () => {
  console.log('clicked');
});

element.addEventListener('mouseover', () => {
  console.log('hovered');
});

element.addEventListener('mouseout', () => {
  console.log('unhovered');
});

element.addEventListener('focus', () => {
  console.log('focused');
});

Cool Bits logo

Cool Bits

  1. Big release week for UI libraries with Radix Themes 3.0 introducing custom palettes, new components, and a new layout engine, and shadcn/ui introducing ready-made components called blocks.

  2. After starting out as a simple RSC research project, Waku v0.20 introduces a file-based pages router making it a legit framework for “small and medium-sized” React projects.

  3. StackBlitz helps teams up-level their their design systems by making them easier to share, maintain, and evolve. See how developers at Porsche, Google, and others used StackBlitz’s interactive documentation and one-click bug reproductions to build design systems that developers actually enjoy using. [sponsored]

  4. Marvin Hagemeister wrote about The road to Fresh 2.0. I assume he’s talking about Deno’s web framework and not the name of a new ‘90s-style hip hop album he’s producing, but you never know with Marvin.

  5. Josh Goldberg wrote about Why TypeScript doesn’t include a throws keyword.

  6. Aral Roca wrote about The power of partial prerendering with Bun.

  7. Emanuele Stoppa and Bjorn Lu wrote about Migrating 500+ tests from Mocha to Node.js in the Astro monorepo.

  8. The Callstack team is hosting a free meetup in San Francisco on April 11th at 6 pm on performance optimization in enterprise-level React apps. It’ll features real-life case studies from companies like Expensify and Shopify and guide you through the process of identifying, measuring, solving, and monitoring performance issues. [sponsored]

  9. Brian Muenzenmeyer wrote a Deep dive into the Node.js website redesign.

  10. Nue CSS bills itself as a “scalable alternative to Tailwind, BEM, and CSS-in-JS.” That’s a pretty bold claim from a brand new framework, but I once read that “fortune flavors the bold” on a bottle of BBQ sauce, and that’s always stuck with me.


Pop Quiz logo

Pop Quiz: Answer

Sponsored by STRICH

You can use an AbortController to remove all the event listeners at once. When passed a signal as an option, the event listener will be removed when the AbortSignal’s abort() method is called.

const controller = new AbortController();
const { signal } = controller;

element.addEventListener('click', () => {
  console.log('clicked');
}, { signal });

element.addEventListener('mouseover', () => {
  console.log('hovered');
}, { signal });

element.addEventListener('mouseout', () => {
  console.log('unhovered');
}, { signal });

element.addEventListener('focus', () => {
  console.log('focused');
}, { signal });

controller.abort();

Note: Older browsers may not support the options parameter for addEventListener, but it is supported in all modern browsers.