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

rollup-plugin-iife-split

v0.0.7

Published

Rollup plugin for intelligent IIFE code-splitting

Readme

rollup-plugin-iife-split

A Rollup plugin that enables intelligent code-splitting for IIFE output.

The Problem

Rollup's native IIFE output doesn't support code-splitting. With ESM, Rollup automatically creates shared chunks that are imported transparently. But with IIFE, you'd need to manually add <script> tags for each chunk, and those chunk names change between builds.

The Solution

This plugin:

  1. Uses Rollup's ESM code-splitting internally
  2. Merges all shared code into a "primary" entry point
  3. Converts everything to IIFE at the last moment
  4. Satellite entries access shared code via a global variable

The result: You get code-splitting benefits with only one <script> tag per entry point.

Installation

npm install rollup-plugin-iife-split

Usage

// rollup.config.js
import iifeSplit from 'rollup-plugin-iife-split';

export default {
  input: {
    main: 'src/main.js',
    admin: 'src/admin.js',
    widget: 'src/widget.js'
  },
  plugins: [
    iifeSplit({
      primary: 'main',        // Which entry gets the shared code
      primaryGlobal: 'MyLib', // Browser global: window.MyLib
      secondaryProps: {
        admin: 'Admin',       // Browser global: window.MyLib.Admin
        widget: 'Widget',     // Browser global: window.MyLib.Widget
      },
      sharedProp: 'Shared',   // Shared code at: window.MyLib.Shared
    })
  ],
  output: {
    dir: 'dist'
  }
};

Output

main.js (primary entry):

var MyLib = (function (exports) {
  // Shared code from all common dependencies
  function sharedUtil() { /* ... */ }

  // Main entry code
  function mainFeature() { /* ... */ }

  exports.mainFeature = mainFeature;
  exports.Shared = { sharedUtil };
  return exports;
})({});

admin.js (satellite entry):

MyLib.Admin = (function (exports, shared) {
  // Uses shared code via parameter
  function adminFeature() {
    return shared.sharedUtil();
  }

  exports.adminFeature = adminFeature;
  return exports;
})({}, MyLib.Shared);

HTML Usage

<!-- Load primary first (contains shared code) -->
<script src="dist/main.js"></script>

<!-- Then load any satellite entries you need -->
<script src="dist/admin.js"></script>

<script>
  MyLib.mainFeature();
  MyLib.Admin.adminFeature();
</script>

Options

| Option | Type | Required | Description | |--------|------|----------|-------------| | primary | string | Yes | Name of the primary entry (must match a key in Rollup's input). Shared code is merged into this entry. | | primaryGlobal | string | Yes | Browser global variable name for the primary entry. Example: 'MyLib'window.MyLib | | secondaryProps | Record<string, string> | Yes | Maps secondary entry names to their property name on the primary global. Example: { admin: 'Admin' }window.MyLib.Admin | | sharedProp | string | Yes | Property name on the global where shared exports are attached. Example: 'Shared'window.MyLib.Shared | | unshared | (id: string) => boolean | No | Function that returns true for modules that should be duplicated instead of shared. See Excluding Modules from Sharing. | | debugDir | string | No | Directory to write intermediate files for debugging. If set, writes ESM files before IIFE conversion to help diagnose issues. Example: './debug-output' | | skipRequireGlobals | boolean | No | If true, don't error when an external module is missing a globals mapping. Instead, let Rollup auto-generate a sanitized global name. Default: false |

Excluding Modules from Sharing

By default, any module imported by multiple entries is consolidated into the shared chunk (merged into primary). However, some modules should be duplicated in each entry instead—for example, locale files that should be self-contained.

Use the unshared option to exclude specific modules from sharing:

iifeSplit({
  primary: 'main',
  primaryGlobal: 'MyLib',
  secondaryProps: {
    'locale-en': 'LocaleEn',
    'locale-fr': 'LocaleFr',
    'locales-all': 'LocalesAll'
  },
  sharedProp: 'Shared',
  unshared(id) {
    // Locale files should be duplicated, not shared
    return /\/locales\/[\w-]+\.js$/.test(id)
  }
})

With this configuration:

  • Locale modules matching the pattern are duplicated in each entry that imports them
  • They are not merged into the primary/shared chunk
  • Each satellite entry is self-contained with its own copy of the locale data

External Dependencies

When using external dependencies with IIFE output, you must specify globals in your Rollup output options to map module IDs to global variable names:

export default {
  input: { /* ... */ },
  external: ['lodash', '@fullcalendar/core'],
  plugins: [iifeSplit({ /* ... */ })],
  output: {
    dir: 'dist',
    globals: {
      'lodash': '_',
      '@fullcalendar/core': 'FullCalendar'
    }
  }
};

By default, the plugin will error if an external is missing from globals—this prevents invalid JavaScript output. If you want Rollup to auto-generate global names instead, set skipRequireGlobals: true.

How It Works

  1. Build phase: Rollup builds with ESM format, using manualChunks to consolidate all shared modules into one chunk
  2. Transform phase: In generateBundle, the plugin:
    • Merges the shared chunk into the primary entry
    • Converts each chunk from ESM to IIFE using a nested Rollup instance
    • Deletes the shared chunk from output

License

MIT