client: exceljs -> archiver 8 override breaks Node-side xlsx writes (Archiver is not a function) #415

Closed
opened 2026-10-31 06:37:28 +00:00 by hermes · 0 comments
Collaborator

What

client/package.json overrides exceljs's archiver to ^8.0.0 (added with the 7.14.0 release). exceljs calls archiver as a callable - lib/stream/xlsx/workbook-writer.js:50: this.zip = Archiver('zip', this.zipOptions) on a CJS require('archiver') - and archiver 8 is an ESM package that exports only the classes (Archiver, ZipArchive, TarArchive, JsonArchive) with no callable default.

So the streamed xlsx writer throws:

$ node scripts/probe-xlsx.mjs
streamed write FAILED: Archiver is not a function

with

const workbook = new ExcelJS.stream.xlsx.WorkbookWriter({ filename: out, useStyles: true })

Why it does not affect the app today

The client imports exceljs dynamically in the browser bundle (src/app/shared/hot-export/hot-export.util.ts:115) and hands the workbook to the download plugin, so the shipped Excel export never runs exceljs under Node. The breakage is confined to Node-side use of exceljs - any tooling, script, test or future server-side export.

Why it is worth fixing anyway

  • Any Node script that writes a workbook through exceljs is broken with a confusing error.
  • The override exists to keep a single archiver in the tree; archiver 8 is ESM-only, so the pairing needs either a CJS-compatible archiver (7.x) or an exceljs version that handles the ESM default export.

Reproduce

cd client
npm ci
node -e "const E=require('exceljs'); new E.stream.xlsx.WorkbookWriter({filename:'/tmp/x.xlsx'})"

Found while adding a guard for the readdir-glob/minimatch override in #414; recorded separately because it predates that change.

## What `client/package.json` overrides exceljs's archiver to `^8.0.0` (added with the 7.14.0 release). exceljs calls archiver as a callable - `lib/stream/xlsx/workbook-writer.js:50`: `this.zip = Archiver('zip', this.zipOptions)` on a CJS `require('archiver')` - and archiver 8 is an ESM package that exports only the classes (`Archiver`, `ZipArchive`, `TarArchive`, `JsonArchive`) with no callable default. So the streamed xlsx writer throws: ``` $ node scripts/probe-xlsx.mjs streamed write FAILED: Archiver is not a function ``` with ```js const workbook = new ExcelJS.stream.xlsx.WorkbookWriter({ filename: out, useStyles: true }) ``` ## Why it does not affect the app today The client imports exceljs dynamically in the browser bundle (`src/app/shared/hot-export/hot-export.util.ts:115`) and hands the workbook to the download plugin, so the shipped Excel export never runs exceljs under Node. The breakage is confined to Node-side use of exceljs - any tooling, script, test or future server-side export. ## Why it is worth fixing anyway - Any Node script that writes a workbook through exceljs is broken with a confusing error. - The override exists to keep a single archiver in the tree; archiver 8 is ESM-only, so the pairing needs either a CJS-compatible archiver (7.x) or an exceljs version that handles the ESM default export. ## Reproduce ```bash cd client npm ci node -e "const E=require('exceljs'); new E.stream.xlsx.WorkbookWriter({filename:'/tmp/x.xlsx'})" ``` Found while adding a guard for the readdir-glob/minimatch override in #414; recorded separately because it predates that change.
allan closed this issue 2026-10-31 21:37:15 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dc/dc#415