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

swc-plugin-webpack-chunk-names

v0.2.0

Published

An SWC plugin that automatically injects `/* webpackMode: "lazy-once" */` and `/* webpackChunkName: "…" */` into dynamic `import()` calls, generating deterministic chunk names from import paths.

Downloads

186

Readme

swc-plugin-webpack-chunk-names

An SWC plugin that automatically injects /* webpackMode: "lazy-once" */ and /* webpackChunkName: "…" */ into dynamic import() calls, generating deterministic chunk names from import paths.

Comments are emitted as leading trivia on the specifier (the string or template literal), i.e. inside the import(…) parentheses and immediately before the module path—not before the import keyword. Existing webpackChunkName / webpackMode block comments at that position are replaced; other leading block comments are kept.

Before:

const Button = lazy(() => import("./components/Button"));

After:

const Button = lazy(() =>
  import(
    /* webpackMode: "lazy-once" */ /* webpackChunkName: "mfWidgets.Button" */ "./components/Button"
  )
);

Exact spacing after emit may depend on your printer/SWC pipeline; both magic comments are always attached to the specifier.

Installation

npm install swc-plugin-webpack-chunk-names

Add to your SWC config (.swcrc):

{
  "jsc": {
    "experimental": {
      "plugins": [
        ["swc-plugin-webpack-chunk-names", {}]
      ]
    }
  }
}

Configuration

| Option | Type | Default | Description | |--------|------|---------|-------------| | dirs | string[] | ["src", "lib", "dist"] | Source directories used to identify package boundaries when resolving chunk name prefixes. |

Example with custom dirs:

["swc-plugin-webpack-chunk-names", { "dirs": ["client", "shared"] }]

Chunk Name Format

The general format is camelCasePrefix.leaf where:

  • Prefix identifies the package or module owner, converted to camelCase (- and _ are treated as word separators).
  • Leaf is the last path segment with file extensions stripped (.tsx, .ts, .js, etc.).

Special cases:

  • A trailing / appends .index (e.g. lodash/ becomes lodash.index).
  • A bare package with no sub-path produces just the camelCased prefix (e.g. lodash stays lodash).
  • Absolute paths (/...) are rejected.

Chunk Name Reference

Bare Imports

Standard npm package imports. The first path segment is used as the prefix unless a source directory is found deeper in the path (see Source-Dir Aware Resolution).

| Import Path | Chunk Name | |---|---| | lodash | lodash | | my-package | myPackage | | lodash/fp/get | lodash.get | | lodash.get | lodash.get | | lodash/index | lodash.index | | lodash/ | lodash.index | | lodash/fp/ | lodash.fp | | punycode | punycode | | punycode/ | punycode.index | | lib/lib/test-package/src/Component | testPackage.Component |

Scoped Imports

For @scope/pkg/... imports, the prefix is formed by joining scope and pkg with -, then camelCasing the result.

| Import Path | Chunk Name | |---|---| | @scope/pkg | scopePkg | | @my-scope/my-pkg | myScopeMyPkg | | @scope/pkg/sub/Leaf | scopePkg.Leaf | | @my-company/package-name/src/my/test/ComponentName | myCompanyPackageName.ComponentName | | @my-company/package-name/my/test/ComponentName | myCompanyPackageName.ComponentName | | @scope-a/ui/Button.tsx | scopeAUi.Button | | @scope-b/ui/Button.tsx | scopeBUi.Button | | @scope/my-lib/utils/helpers.ts | scopeMyLib.helpers | | @scope/pkg/ | scopePkg.index | | @scope/pkg/sub/ | scopePkg.sub |

@/ Alias Imports

Paths starting with @/ are treated as bare imports after stripping the @/ prefix. Source-dir aware resolution applies.

| Import Path | Chunk Name | |---|---| | @/components/Button | components.Button | | @/utils/helpers/format | utils.format | | @/lib | lib | | @/lib/ | lib.index | | @/lib/test-package/src/Component | testPackage.Component |

Relative Imports

For ./ and ../ imports, the plugin resolves the path against the current file's directory, then finds the owning package by scanning for a configured source directory.

| Import Path | Current File | Chunk Name | |---|---|---| | ./components/MyWidget | /project/mf-widgets/src/App.tsx | mfWidgets.MyWidget | | ./Button.tsx | /project/mf-widgets/src/components/App.tsx | mfWidgets.Button | | ../GroupB/components/GroupBChild | /project/mf-widgets/src/components/GroupA/index.tsx | mfWidgets.GroupBChild | | ../../GroupTitle | /project/mf-widgets/src/components/Group/components/GroupName/index.tsx | mfWidgets.GroupTitle | | ./components/ | /project/mf-widgets/src/App.tsx | mfWidgets.components | | ./components/Button | /project/node_modules/@scope1/pkg1/node_modules/@scope2/pkg2/src/index.tsx | pkg2.Button | | ../utils/formatDate | /project/node_modules/@company/ui-kit/src/components/DatePicker.tsx | uiKit.formatDate | | ./locale/en | /project/node_modules/some-lib/src/index.tsx | someLib.en |

Template Literal Imports

All dynamic expressions in template literals are replaced with a fixed dynamic placeholder, regardless of the expression type. This ensures stable and predictable chunk names.

| Import Expression | Flattened Path | Chunk Name (relative context) | |---|---|---| | `./locale/${language}` | ./locale/dynamic | mfWidgets.dynamic | | `./v${2}/api` | ./vdynamic/api | (depends on context) | | `./${scope}/${name}` | ./dynamic/dynamic | (depends on context) | | `./locale/${lang.code}` | ./locale/dynamic | (depends on context) | | `./locale/${getLocale()}` | ./locale/dynamic | (depends on context) |

Source-Dir Aware Resolution

When resolving the package prefix for bare and @/ alias imports, the plugin scans the path segments left-to-right looking for configured source directories (src, lib, dist by default). The segment immediately before the rightmost source-dir match is used as the package prefix.

If no source directory is found, the first path segment is used as fallback.

Example: For import path lib/lib/test-package/src/Component with default dirs:

lib / lib / test-package / src / Component
                 ^          ^
            prefix found   source dir match (rightmost)

Result: testPackage.Component

For relative imports, the same logic applies to the resolved absolute path. The segment before the rightmost source directory in the resolved path identifies the package, and the import's last segment becomes the leaf.

Example: File /project/mf-widgets/src/App.tsx importing ./components/Button:

project / mf-widgets / src / components / Button
              ^          ^
         prefix found   source dir match

Result: mfWidgets.Button

Development

  • Tests: cargo test — unit tests and test_inline! integration-style cases live in src/tests.rs.
  • Wasm artifact for npm: run build.sh (release build for wasm32-wasip1, then wasm-opt into lib/swc_plugin_webpack_chunk_names.wasm). Requires a nightly-capable Rust toolchain and the WASI target as set up in your environment.

License

MIT