Let the Node build be bundled: export registerStdFonts, resolve standard fonts and the ICC profile on first use - #1802
Conversation
A bundler that inlines pdfkit leaves the bundle in a package without the
`#standard-fonts/*` mapping and without `data/`, and a CommonJS output has no
`import.meta.url` at all. The Node build bound `createRequire(import.meta.url)`
and the ICC profile URL at import time, so an ESM bundle threw
`Cannot find module '#standard-fonts/Helvetica'` on the first document and a
CommonJS bundle threw `Invalid URL` while being imported, with no way for the
application to supply the font data.
Resolve both on first use, name the font and the fix when a standard font
cannot be loaded, and export `registerStdFonts` from the Node build as the
browser build already does. The `require('#standard-fonts/<Name>')` calls stay
literal so file tracers still pick the font files up.
Fixes foliojs#1801
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
#standard-fonts mapping is only used in node and AFAICS can be replaced by a direct path. Can you try this route and see if simplifies a bit the required changes? |
…ping The `#standard-fonts/*` entry in package.json was only ever referenced from the Node entry, so the fourteen loaders now require `./standard-fonts/<Name>.cjs` relative to the built file. That drops the mapping, and with it the check that kept its import and require conditions pointing at the same file, and lets an ESM bundle load the fonts from a copy of `js/standard-fonts` placed next to it. A CommonJS bundle still has no `import.meta.url`, so the createRequire fallback, the named error and the `registerStdFonts` export stay as they are. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Done in fff40ec. The loaders now do Honestly it doesn't shrink the diff (+63/−43 instead of +45/−6 on the code files), because the 14 loader lines change and the test block is deleted, but the repo ends up smaller and package.json simpler. The rest of Nice side effect: copying |
Fixes #1801
What changes
lib/document.node.js:createRequirefalls back tofile:///whenimport.meta.urlis undefined (CommonJS bundles), so importing a bundled pdfkit no longer throws. A#standard-fonts/<Name>lookup that fails withMODULE_NOT_FOUNDnow throws an error that names the font and the two fixes (mark pdfkit external, orregisterStdFonts()with data frompdfkit/standard-fonts/<Name>), with the original error ascause.registerStdFontsis exported from the Node build, as it already is from the browser build.lib/mixins/pdfa.js: the ICC profile URL is computed on first PDF/A use (getIccProfilePath()) instead of at import time, with a clear error whenimport.meta.urlis unavailable. The browser build registers its inline profile under the same path as before.rollup.config.mjs: the CommonJS footer exposesregisterStdFontstoo.What does not change
require('#standard-fonts/<Name>')calls stay literal and bound tocreateRequire, so file tracers keep working.@vercel/nfttraces the same 18 files from the builtjs/pdfkit.node.mjsbefore and after this change: all 14 fonts, their shared chunk, the ICC profile andpackage.json.js/standard-fonts/*.cjson first use, andnpm run test:packagestill passes.Tests
tests/unit/bundling.spec.jsbundleslib/document.node.jswith rollup into a directory that has its ownpackage.json(undernode_modules/.cache, so pdfkit's dependencies still resolve and Vitest leaves the file to Node), once as ESM and once as CommonJS withimport.meta.urlreplaced byundefined, which is what esbuild produces. It asserts that both bundles load, that an unregistered standard font throws the new error withMODULE_NOT_FOUNDascause, that a document renders afterregisterStdFonts(Helvetica), and the PDF/A behaviour of each output. Onmasterit fails in both formats (ESM:registerStdFontsmissing and the bareCannot find moduleerror; CommonJS:Invalid URLwhile loading). It runs in about half a second.tests/package-resolution.{cjs,mjs}assert the new export.@react-pdf/renderer4.9 bundled by esbuild 0.28 into ESM and CommonJS: without registration both bundles fail with the new message, with the 14 fonts registered before react-pdf is imported both render.npm test,npm run lint,npm run prettier -- --checkandnpm run buildpass locally on Node 24.Docs
README gains a "Bundling for Node" section; CHANGELOG has an entry under Unreleased.
Disclosure: this pull request and #1801 were written with an AI coding assistant (Claude Code). The tests, the tracer comparison and the end-to-end check described above were run, not only written.