Skip to content

Step 11: alasql/esm, and the build without keepNames - #2848

Merged
mathiasrw merged 5 commits into
feature/rollupfrom
fix/esm-build
Oct 22, 2026
Merged

mathiasrw merged 5 commits into
feature/rollupfrom
fix/esm-build

Conversation

@mathiasrw

@mathiasrw mathiasrw commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Step 11 of the ES6 conversion (context/roadmap-phase-1.md), the part before the release: alasql/esm. The version bump, the publish to the next dist-tag and the merge of #1860 are the maintainer's.

Two ES module files, one subpath. package.json maps ./esm by condition: node to dist/alasql.mjs, default to dist/alasql.browser.mjs, with types first. Both are the same bundle in esbuild's esm format, ending in export default:

  • dist/alasql.mjs keeps the lazy require() calls of the externals (fs, path, the optional libraries) and the __dirname that findAlaSQLPath returns, so it defines both at the top from import.meta.url (createRequire, fileURLToPath). That banner is in this file only.
  • dist/alasql.browser.mjs is the browser file's content as a module: the not-for-browser blocks are out, __dirname is '', and no line imports module, fs, path or url. The two require("fs") and require("path") calls left in it are the jison parser's command-line main, inside a function the browser never calls; esbuild turns them into its __require shim, which a bundler does not try to resolve.

No "use strict" is prepended to the module files (modules are strict), and the CommonJS module.exports tail is not applied to them. The other dist files are byte-identical to the step 10 build apart from the build string.

Smokes (test/parity/smoke.js): the Node file imported in-process (SELECT 1+1, and findAlaSQLPath() returns a string); the browser file in a child node with the import list checked; the browser file bundled by esbuild with platform: 'browser'; and, under --pack, import alasql from 'alasql/esm' from an installed copy, which takes the node condition.

Release notes: the draft is at the end of this description.

The SEARCH case, traced. The json-path case "SEARCH through nested arrays" (SEARCH / orders / items / WHERE(price > 100) price FROM ? over 5,000 nested documents) was +27 percent on Bun and +37 on Node against 4.21.0 at the end of the phase. Across the step builds, 7 runs each on both runtimes, it reads:

build Bun Node
step 1b (esbuild, nothing converted) +26 +43
step 2 +31 +41
step 3 +28 +39
step 4a / 4b +27 / +30 +42 / +45
step 5 +25 +43
step 6 +26 +41
step 7 (SEARCH converted) +28 +41
step 8 / 9 / 10 +22 / +25 / +25 +41 / +44 / +44
step 10 built without keepNames -1 -1

It came with the bundler in step 1, not with a conversion step, and it is esbuild's keepNames: its __name() helper runs at every creation of a named function, and SEARCH creates processSelector inside #doSearch and recurses through it. Without keepNames the whole json-path group is -4 on Bun and 0 on Node, and the two .name values keepNames still protected (alasql.utils.cloneDeep, alasql.stdfn.EXTEND) are kept by declaring the two functions in src/utils/helpers.js as function declarations, which esbuild does not suffix. The API snapshot of the parity check shows 0 changed paths after that. Two commits, "Declare extend and cloneDeep as functions" and "Build without keepNames", separate from the ES module work; the unminified files shrink by about 11 KB.

The end-of-phase full benchmark was run again on this build, on a quiet machine: 99 (Bun 100, Node 99) against 4.21.0, from 102 on the step 9 build. Four dimensions were marked (set-ops, coercion and shapes on Bun, mutation on Node) and a focused run of 7 put all four within 4 percent or faster, with the single cases behind them flipping sign; json-path reads -1 and +2, and the JOIN baseline case of the step 9 investigation reads -37 on Bun on this build, the same layout effect the other way. Detail in ledger row 11.

Checks

suite 2452 pass, 213 skip, 0 fail at each of the three commits
parity on the tip 0 differences over 77,053 statements against develop at #2798; API identical apart from the 11 allowed, and 0 changed paths without keepNames
double run 0 unstable statements, 0 differences
smokes 11 of 11: the eight of before, the three ES module smokes, and alasql/esm from the installed package. The esbuild bundle of the browser file reports two warnings, its note on the typeof-guarded CommonJS variables (module and exports in FileSaver and the parser); no error
sizes alasql.min.js 524,607 bytes, unchanged by keepNames; alasql.fs.js 918,768, 11 KB under step 10; the package grows by the two module files, alasql.mjs 918,497 / 140,522 and alasql.browser.mjs 913,425 / 139,680 bytes / gzip (the pack is 3,038,249 bytes, from 2,760,848); row 11 in test/parity/ledger.md, whose size table lists .mjs files now
test-perf-mini 101 against 4.21.0, nothing marked; json-path focused 7-run -4 on Bun and 0 on Node, the SEARCH case +3 and +1

test/parity/ledger.md row 11 carries this pull request's number and the sizes of the two new files.


Release notes draft

4.22.0 (pre-release on the next dist-tag)

The same alasql, built from ES modules. Every numbered source file is a module under src/ now, bundled by esbuild into the same dist files with the same names and the same exports; the concatenation build is gone. Nothing about the SQL, the API or the behaviour was meant to change, and the checks below say it did not. Please try it from the next tag before it becomes latest:

npm install alasql@next

What is new

  • alasql/esm: an ES module entry. Under Node it resolves to dist/alasql.mjs; in browsers and bundlers to dist/alasql.browser.mjs, which has no Node import in it. import alasql from 'alasql/esm'. It is the same engine as the default entry; the root entry still resolves to the CommonJS files, so a project that mixes require('alasql') and import ... from 'alasql/esm' gets two instances with separate databases.
  • REFERENCES with FILESTORAGE (Fix REFERENCES crash with FILESTORAGE to address #1846 #2798), by @jsingh0026. Thank you.

What was checked

  • The parity check (test/parity/): the suite and the dialect cases, 77,053 statements in order, recorded on this build and on develop at Fix REFERENCES crash with FILESTORAGE to address #1846 #2798 built the old way, compared result by result and compiled function by compiled function: 0 differences. The public API, every property path reachable from alasql, is identical apart from the .name of eleven stateless helpers that are exports now.
  • The suite: 2452 tests pass, 213 skipped, as before.
  • Smokes: the browser global, the worker file, the CLI, alasql.min.js under node, Node 16 and 24, npm pack and install with require, import and the CLI, and the two ES module files.
  • The benchmark: 99 against 4.21.0 (Bun 100, Node 99), where identical builds move by about 2.
  • Sizes: alasql.min.js 524,607 bytes (4.21.0: 520,504), 0.8 percent more; alasql.fs.js 918,768 bytes and 140,210 gzipped (4.21.0: 840,681 and 167,149). esbuild reprints the code, so the unminified files are not the old text; they are the same code.

What was not checked, and where to look if you use it

IndexedDB and localStorage in a real browser, React Native, sql.js and Meteor are not covered by the suite or the smokes; their code moved unchanged, but nothing ran it. A report from any of these environments is welcome.

Known, found on the way, unchanged in this release

For contributors

  • bun build.js builds; yarn test builds and runs the suite. The source is src/index.js and the folders beside it; docs/src-map.md says where each old numbered file went.
  • The husky hooks are gone; CI's formatting job is the gate.
  • One commit reformatted every converted module (fac32eef); it is listed in .git-blame-ignore-revs, so blame still reaches the old files. A clone that wants the same: git config blame.ignoreRevsFile .git-blame-ignore-revs.

@mathiasrw
mathiasrw merged commit dcb30b9 into feature/rollup Oct 22, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant