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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@open-xchange/bundler-testutils

v2.0.0

Published

Utility functions needed to write unit tests for rolldown, tsdown, or vite plugins

Readme

@open-xchange/bundler-testutils

Utility functions needed to write unit tests for custom bundler plugins (rolldown, tsdown, or vite).

Installation

npm install -D @open-xchange/bundler-testutils
# or
pnpm add -D @open-xchange/bundler-testutils
# or
yarn add -D @open-xchange/bundler-testutils

API

Tip: buildRolldownBundle and buildTsdownBundle accept a cwd option, and buildViteBundle, createViteServer and createVitePreviewServer accept a root option. Always pass one of these explicitly (typically import.meta.dirname), so tests do not depend on the actual working directory of the test runner, which can differ between a package-local run and a monorepo-wide run, or between different CI and IDE setups.

withEnvironment

Runs a callback function with the specified environment variables set to the given values (or unset, for values of null), restoring their original values afterwards regardless of the outcome (even if the callback throws or rejects).

it('reads value from environment', async () => {
  await withEnvironment({ MY_VAR: 'value' }, async () => {
    expect(readMyVar()).toBe('value')
  })
})

buildRolldownBundle

Invokes rolldown's build function with the specified plugins for testing, and returns the resulting bundle wrapped in a TestBundle. Set the cwd option to a fixed path to become independent from unstable CWD during tests. The entry point is configured through rolldown's own input option.

it('plugin works in build mode', async () => {
  const bundle = await buildRolldownBundle({
    cwd: import.meta.dirname,
    input: 'fixtures/index.ts',
    plugins: testPlugin(),
  })
  const chunk = bundle.getChunk('index.js') // throws if missing
  expect(chunk.code).toContain('...')
})

buildTsdownBundle

Invokes tsdown's build function with the specified plugins for testing, and returns the resulting bundle wrapped in a TestBundle. Set the cwd option to a fixed path to become independent from unstable CWD during tests. The entry point is configured through tsdown's own entry option; tsdown emits .mjs chunks by default.

it('plugin works in build mode', async () => {
  const bundle = await buildTsdownBundle({
    cwd: import.meta.dirname,
    entry: 'fixtures/index.ts',
    plugins: testPlugin(),
  })
  const chunk = bundle.getChunk('index.mjs') // throws if missing
  expect(chunk.code).toContain('...')
})

buildViteBundle

Invokes vite's build function with the specified ViteBuildConfig for testing, and returns the resulting bundle wrapped in a TestBundle. Set the root option to a fixed path to become independent from unstable CWD during tests. By default, vite discovers the entry point from an index.html file at the project root; passing input bypasses HTML processing and builds the given module directly.

it('plugin works in build mode', async () => {
  const bundle = await buildViteBundle({
    root: import.meta.dirname,
    plugins: [testPlugin()],
    input: 'fixtures/index.ts',
  })
  const chunk = bundle.getChunk('index.js') // throws if missing
  expect(chunk.code).toContain('...')
})

createViteServer

Creates a vite development server for testing, with the specified vite InlineConfig, and already listening by the time the promise resolves. Set the root option to a fixed path to become independent from unstable CWD during tests. Returns the server extended with a transformCode helper method (see TestServer).

it('plugin works in serve mode', async () => {
  await using server = await createViteServer({
    root: import.meta.dirname,
    plugins: [testPlugin()],
  })
  const code = await server.transformCode('/index.js')
  expect(code).toContain('...')
})

createVitePreviewServer

Creates a vite preview server for testing, with the specified vite InlineConfig, and already listening by the time the promise resolves. Set the root option to a fixed path to become independent from unstable CWD during tests. Returns the server extended with Symbol.asyncDispose (see TestPreviewServer).

it('plugin works in preview mode', async () => {
  await using server = await createVitePreviewServer({
    root: import.meta.dirname,
    plugins: [testPlugin()],
  })
  server.printUrls()
})

Types

TestBundle

Wraps the chunks and assets returned by a rolldown, tsdown, or vite build, and offers convenience methods to look them up by file name:

  • items: the raw list of chunks and assets.
  • getItemNames(): returns the file names of all chunks and assets.
  • findChunk(fileName) / findAsset(fileName): return the matching chunk or asset, or undefined if not found.
  • getChunk(fileName) / getAsset(fileName): return the matching chunk or asset, or fail the current test if not found.

ViteBuildConfig

The configuration object accepted by buildViteBundle: a vite InlineConfig, plus:

  • input (optional): convenience shortcut for build.rolldownOptions.input.

TestServer

A vite ViteDevServer extended with:

  • transformCode(route): transforms the module at the given route and returns its resulting code, failing the current test if the module cannot be transformed.
  • Symbol.asyncDispose: closes the server, so it can be closed automatically at the end of an await using block.

TestPreviewServer

A vite PreviewServer extended with Symbol.asyncDispose, so it can be closed automatically at the end of an await using block.

OutputItem

Type alias for a rolldown OutputChunk or OutputAsset, i.e. a single entry of a build output.