Ignore Import of CSS File with Node.js

Posted on Sat May 27 2023

Recently, I had to migrate a couple of web services to the Node.js 20 runtime. With Node.js 20, you get support for stable test runner. My codebase is mostly TypeScript. From my experience, ESM, TypeScript, and Mocha will always give you headaches. So I decided to migrate mocha tests to the native test runner. For the most part, everything went smoothly.

There was an issue, as my React code was importing some styles and images. In old code, I used require.extensions['css'] = noop to ignore require of styles in tests. So I was looking for something similar with the ESM setup. I discovered there is a stable flag called --loader, which can be used to modify how imports are handled by Node.js.

After some tinkering, I ended up with the following code: This code ignores styles and images when running a script using Node.js.

import { URL } from 'url';

function test(input) {
  return (
    input.endsWith('.css') || input.endsWith('.svg') || input.endsWith('.png')
  );
}

export function resolve(specifier, context, nextResolve) {
  const { parentURL = null } = context;

  if (test(specifier)) {
    return {
      shortCircuit: true,
      url: new URL(specifier, parentURL).href,
    };
  } else if (parentURL && test(parentURL)) {
    return {
      shortCircuit: true,
      url: new URL(specifier, parentURL).href,
    };
  }

  // Let Node.js handle all other specifiers.
  return nextResolve(specifier);
}

export function load(url, context, nextLoad) {
  if (test(url)) {
    return {
      format: 'module',
      shortCircuit: true,
      source: 'export default {}',
    };
  }

  // Let Node.js handle all other URLs.
  return nextLoad(url);
}