`bundled.js` stopped being ES5 when the webpack build was replaced by tsdown
in #628. It parses at ecmaVersion 2015 but not 5:
var t=(t,e)=>()=>(e||(t((e={exports:{}}).exports,e),t=null),e.exports)
That is rolldown's `__commonJS` interop helper. `@rolldown/plugin-babel` only
transforms input modules, and rolldown appends the helper afterwards; terser
with `ecma: 5` avoids introducing newer syntax but does not transpile, so the
arrow functions reached the published file. `es5.js` has no CommonJS
dependencies and never gets the helper, which is why only `bundled.js` broke.
The effect is total rather than partial: in an ES5 engine the whole script is
a SyntaxError, so `bundled.js` — the bundle that exists specifically to serve
those engines, polyfills included — does not load at all there.
Lower the emitted chunk with a babel renderChunk pass that runs after bundling
and before terser, so rolldown's own helpers are covered too. Costs 2.8 kB
(+1.6%) on bundled.js; es5.js is unchanged at 34 kB.
The existing guard was a grep for backticks, which this syntax slips straight
past. Replace it with an acorn parse at ecmaVersion 5 over both legacy
bundles, plus a tokeniser check for real template literals (backticks inside
core-js string literals are fine, and 2.14.1 shipped three of them).
Verified by reverting the build fix: `bundled.js parses as ES5` fails, and
passes again once restored. Also confirmed bundled.js loads and parses the
live navigator.userAgent in a real browser.
Two follow-ups to the dual packaging change (#628), found while running a
consumer-facing regression sweep against published 2.14.1.
An exports map is a closed list. Before #628 bowser had no exports map, so
every published file was reachable by subpath; afterwards LICENSE, README.md
and index.d.ts resolved to ERR_PACKAGE_PATH_NOT_EXPORTED. Nothing in the
documented API regressed, but `/// <reference types="bowser/index.d.ts" />`
and tooling that resolves the license by specifier both did. Add the four
non-code files to the map so the published surface matches 2.14.1 exactly,
and assert it in the package smoke test (25 -> 29 checks).
The acceptance suite asserted src/bowser.js and es5.js against the UA corpus
but not bundled.js or bowser.mjs. bowser.mjs is what the `import` condition
resolves to, so it is the file every modern ESM and bundler consumer runs,
and a build regression confined to it would have kept CI green. Assert all
four artifacts against the spec instead.
Verified by injecting a Chrome-parsing regression into bowser.mjs and into
bundled.js separately (each turns the suite red, labelled by artifact), and
by running the new smoke assertions against a pre-fix tarball (exit 1) and
this one (exit 0) on Node 12.16, 14, 18, 20 and 22.
The 'module' field is used by bundlers such as rollup and webpack to
determine the entrypoint for a package. Conventionally 'module' is used
for the ES6 entrypoint, and 'main' is used for the CommonJS entrypoint.
Adding a 'module' field allows importing bowser as an ES6 module
directly, rather than using a package-relative path to the ES6
entrypoint (e.g. `bowser/src/bowser`)
Closes#353