npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

esm-loader-mock-exports

v1.0.11

Published

Chainable ESModule Loader for mocking module exports

Downloads

6

Readme

esm-loader-mock-exports

Node.js ESModule Loader for mocking module exports.

This loader will add a _MOCK named export to each loaded ESModule, which can be used to mock the rest of its exports. This only works for ESModules (import), and does not work for CommonJS (require) modules.

Warning! This uses experimental Node.js features and flags, whose API will likely change. This may be helpful for development and testing, but should not be used in production.

Usage

We'll take some production code which accesses a live filesystem:

// filesystem.js
import { readdirSync } from 'node:fs'

export const getDir = () => {
  return readdirSync('.')
}

// getDir() => ['packge.json', 'tsconfig.json', ...]
// app.js
import { getDir } from './filesystem.js'

export const getFirst = () => {
  const files = getDir()
  return files[0]
}

// getFirst() => 'package.json'

Now, we want to test this code in development. We don't want to actually access the filesystem here, so we'll mock the filesystem call:

npm install --save-dev esm-loader-mock-exports
// app.test.js
import assert from 'node:assert'
import { getFirst } from './app.js'
import { _MOCK } from './filesystem.js'

const clear = _MOCK('getDir', () => ['one', 'two'])

assert.equal(getFirst(), 'one')

clear() // clear our single mock above
_MOCK.CLEAR() // alternatively, clear all mocks on this module

If we want to mock the default export of a module, instead of one of its named exports, we just use the default keyword:

_MOCK('default', () => 'hello world')

Standalone

By default, all loaded modules will be instrumented with mocking abilities:

# node >= 20.7
cat << EOF > ./register.js
import { register } from 'node:module'
register('esm-loader-mock-exports', import.meta.url)
EOF
NODE_OPTIONS="--import ./register.js" node app.test.js

# node < 20.7
NODE_OPTIONS="--loader esm-loader-mock-exports" node app.test.js

Chainable

This loader can be configured, and chained with other loaders, using node-esm-loader.

Note: This loader should be on the bottom of your chain, so that it runs last.

npm install --save-dev node-esm-loader
// .loaderrc.js
export default {
  loaders: ['esm-loader-mock-exports'],
}
# node >= 20.7
NODE_OPTIONS="--import node-esm-loader/register" node app.test.js

# node < 20.7
NODE_OPTIONS="--loader node-esm-loader" node app.test.js

Options

Includes

To only instrument mocks on certain specific modules, you can pass a list of regular expressions in an includes option. This can increase speed and performance, reduce chance of breakage, and reduce any security concerns.

Note: The includes RegExes will be tested against the final resolved module name on the filesystem. If you are trying to mock a module named common/utils, and the module resolves to node_modules/common/dist/utils.js, your RegEx will look something like:

// .loaderrc.js
export default {
  loaders: [
    {
      loader: 'esm-loader-mock-exports',
      options: {
        includes: [/common\/dist\/utils/],
      },
    },
  ],
}
Debug
// .loaderrc.js
export default {
  loaders: [
    {
      loader: 'esm-loader-mock-exports',
      options: {
        debug: true,
      },
    },
  ],
}

Unsupported

This loader CANNOT handle the following situations, and will skip them:

  • Node.js built-in modules (already pre-loaded and not mockable).

  • Bulk exports from other modules (You may be able to mock a parent module at a higher level to accomplish the same thing):

    export * from ...
  • Class with uninitialized private field declarations:

    class BlobDataItem {
      #path
    
      constructor(options) {
        this.#path = options.path
      }
    }

Security

Warning! This loader uses eval to accomplish adding/clearing mocks. Make sure this loader is used under development/test, with code/tests/mocks that you trust. See the includes option above to restrict which modules are instrumented with mocking abilities.

This loader will always print a warning about this during startup, as a reminder.

Context

There are other ESModule mocking libraries available, but they all have one or more of these problems:

  • Cannot be chained with other loaders.
  • Only works for .js files, not any others (.ts, .svelte, etc.)

License

MIT