Skip to content

Replace webpack with esbuild for the dist/ bundles - #336

Open
tomalec wants to merge 5 commits into
fix/npm-auditfrom
build/esbuild
Open

tomalec wants to merge 5 commits into
fix/npm-auditfrom
build/esbuild

Conversation

@tomalec

@tomalec tomalec commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator

(Stacked on #335; review that one first.)

What changes

  • dist/ is bundled by esbuild instead of webpack 5. It's the same IIFE with the same jsonpatch global and the same 15 exports, ES5, with the licence headers kept in both files. The flags live in package.json scripts, so there's no config file, and webpack.config.js leaves the tarball.

  • Installed dev packages: 175 → 79.

  • A smoke test for the bundles (npm run test-dist). It loads each bundle the way a <script> tag does, and checks:

    • that it parses as ES5;
    • the version banner;
    • the global's exports;
    • one patch.

    It runs in CI and in the version script before the release commit.

  • The import test bundles with esbuild (test-bundler-import) instead of webpack.

What doesn't change

  • commonjs/ and module/.
  • dist/ isn't rebuilt in this PR; the version script rebuilds it at the next release. The new bundles are smaller: 29.2 KB vs 37.5 KB, and 12.3 KB vs 12.8 KB minified.

For maintainers

  • The banner takes the version from $npm_package_version, which a POSIX shell expands, so releases build on Linux or macOS (or in CI).

The browser suite imports `index.mjs`, so nothing tested the bundles a
`<script>` tag loads, and the next release rebuilds them with webpack 5.
`npm run test-dist` loads each bundle in a fresh global scope and checks:
the version banner, the `jsonpatch` global with the same exports as
`index.js`, and one applied and one generated patch.

It passes on the 3.1.1 bundles and on a fresh build, and fails on a banner
left at an older version.

- CI runs it after `test-browser`, which builds `dist/`.
- The `version` script runs it before staging the release build.
esbuild replaces webpack for the `dist/` bundles and for the import test in
the next commits. 0.28.2 is published from GitHub Actions with a provenance
attestation.

- Its only install script is a `postinstall` that swaps a JS shim for the
  native binary. `ignore-scripts=true` in `.npmrc` skips it, and esbuild
  still works without it.
- The lockfile gets 26 optional `@esbuild/*` binaries, one per platform;
  npm installs only the one that matches.
`test-webpack-import` bundles `test/spec/webpack/importSpec.src.js` and
runs the result, so the `import` path of the package stays covered. Do the
same with esbuild, ahead of dropping webpack.

- `test-bundler-import`: replaces `test-webpack-import` and is called by
  `npm test`. `--main-fields=module,main` makes esbuild resolve `index.mjs`
  like webpack did for `target: node`.
- Move the spec to `test/spec/esbuild/` and say "esbuild" in its title.
- Stop tracking the build output: `importSpec.build.js` is now ignored
  instead of committed.
Replace webpack in `npm run build`. The flags live in `package.json`, so
there is no build config to maintain or to ship in the package.

- `bundle`: `index.js` as an IIFE that defines the global `jsonpatch`, ES5
  (`--target=es5`), with the `/*!` licence comments inline
  (`--legal-comments=inline`) and the `fast-json-patch, version: X` banner
  from `$npm_package_version`, so it needs a POSIX shell.
- `build-dist`: the plain and the minified bundle.
- Delete `webpack.config.js`. The package no longer ships it: 23 files
  instead of 24, none added.

`npm run test-dist` passes on the new output: ES5 syntax, the same 15
exports, the banner and the three `/*!` comments. The bundles get smaller,
as webpack's runtime is gone: 37.5 to 29.2 kB, minified 12.8 to 12.3 kB.
`dist/` itself is not rebuilt here; the release build does that.
Nothing uses it any more. Remove `webpack`, `webpack-cli` and
`minimizer-webpack-plugin` from the devDependencies.

`package-lock.json` drops from 202 to 104 entries (175 before esbuild), 26
of them esbuild's per-platform binaries. `fast-uri` goes too: it was only
there through webpack's `ajv`.

- `tsconfig.json` and `test/spec/typings/tsconfig.json`: drop "from webpack" from
  the comment on `"types": []`.
  No `@types/*` package is installed any more; the setting stays, so the
  `@types` of a future devDependency don't leak into the build.
- `bower.json`: drop `webpack.config.js` from `ignore`.
@tomalec tomalec added the dependencies Pull requests that update a dependency file label Oct 28, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant