react-pdf: ESM contains server code, doesn't provide named exports

Describe the bug When using Vite to package a React app, we hit some issues because:

  1. The ESM that @react-pdf/renderer provides doesn’t seem to provide the same exports as the CJS module.
  2. There is server code included in the ESM, but this library is a browser module.

To Reproduce You can reproduce with this repository: https://github.com/thekevinbrown/vite-react-pdf-reproduction

Expected behavior I expected React PDF to be able to be bundled and used in an ESM context.

Screenshots

Uncaught ReferenceError: global is not defined
    at node_modules/blob/index.js (@react-pdf_renderer.js:554)
    at __require (chunk-KVFJW2XH.js:12)
    at node_modules/blob-stream/index.js (@react-pdf_renderer.js:616)
    at __require (chunk-KVFJW2XH.js:12)
    at @react-pdf_renderer.js:126368

Desktop (please complete the following information):

Additional Notes

An issue was logged with Vite here: https://github.com/vitejs/vite/issues/3405

This may be related to this issue as well: #1029

I’d be happy to help with a PR if one is welcome, just wanted to check to ensure I wasn’t duplicating effort and that this was something you’d accept a PR for.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 8
  • Comments: 33 (12 by maintainers)

Commits related to this issue

Most upvoted comments

Alrighty, finally found a set of shims and workarounds that make it work, both in Vite Dev and Production builds.

So, if you’re coming here from Google, you do the following in your Vite project:

$ yarn add --dev vite-plugin-shim-react-pdf

Then in vite.config.js:

import { defineConfig } from "vite";
import reactRefresh from "@vitejs/plugin-react-refresh";
import shimReactPdf from "vite-plugin-shim-react-pdf";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [reactRefresh(), shimReactPdf()],
});

Then you’ll also need to use the default import because of the missing exports. E.g.

Instead of:

import { Text, View, StyleSheet } from "@react-pdf/renderer";

You have to do:

import pdf from "@react-pdf/renderer";
const { Text, View, StyleSheet } = pdf;

React PDF also didn’t have a development project I could use to test changes, so I made a really rough one out of the examples: https://github.com/TechInSite/react-pdf-development-harness

@diegomura I’d be happy to transfer ownership of the development harness repo to you if you want to have it as part of the React PDF project moving forward. Could use quite a bit of CSS work, but I had enough to get through with the above that I didn’t put any time into making it pretty at all.

I created PR #1891 to fix this issue, please have a look 😃

I don’t think so. As far as I am aware, react-pdf is still broken in web bundlers newer than Webpack 4, which hasn’t seen any development in almost a year now: https://github.com/webpack/webpack/tree/webpack-4

The fixes from the shim in index.js and shim-react-pdf.js should be applied directly in the react-pdf code base, while making sure that server side operation of react-pdf still works. I can open a PR if @thekevinbrown does not have time for it, but I do not have the know-how to test whether it still works in a node.js environment.

This has now been released, sorry for the delay!

I’m having the same issue as well, and the shim of @thekevinbrown worked wonders, even for my special case of packing the react component into a webcomponent and using it inside a Vue.js app! Thanks a lot for that! Let’s hope this can be fixed directly in react-pdf in the future.

Edit: – Removed as I was using a older version, so comments were obsolete.—

Many thanks to the maintainers of the repo 🙌

Yeah, and even with my shim it still doesn’t provide named exports and you still have to do:

import pdf from "@react-pdf/renderer";
const { Text, View, StyleSheet } = pdf;

I’d say we should break this into two pieces that are separate issues:

  1. Fixing the named exports (should be relatively easy).
  2. Moving away from expecting Webpack to auto-shim node dependencies and instead requiring exactly what we need and depending on it in that way, e.g. users should be able to npm i @react-pdf/renderer, then run in Vite, Webpack 5, and Node without issue.

@carlobeltrame If you have time to work on a PR, we’re using React PDF in both Vite and Node, so I can test server side (and create an example project) for you if that helps.

I worked around the import issue by adding a file “reactPdf.js” like follows to my project that “converts” the default export to named exports:

import pdf from '@react-pdf/renderer'

export const StyleSheet = pdf.StyleSheet
export const Font = pdf.Font

// https://react-pdf.org/components
export const Document = pdf.Document
export const Page = pdf.Page
export const Image = pdf.Image
export const View = pdf.View
export const Text = pdf.Text
export const Link = pdf.Link
export const Note = pdf.Note
export const Canvas = pdf.Canvas

// https://react-pdf.org/svg
export const Svg = pdf.Svg
export const Line = pdf.Line
export const Polyline = pdf.Polyline
export const Polygon = pdf.Polygon
export const Path = pdf.Path
export const Rect = pdf.Rect
export const Circle = pdf.Circle
export const Ellipse = pdf.Ellipse
// export const Text = pdf.Text
export const Tspan = pdf.Tspan
export const G = pdf.G
export const Stop = pdf.Stop
export const Defs = pdf.Defs
export const ClipPath = pdf.ClipPath
export const LinearGradient = pdf.LinearGradient
export const RadialGradient = pdf.RadialGradient

And then I can import from that file normally:

import { Document, Page, Text } from './reactPdf.js'

This always loads all the primitives from react-pdf, but as @diegomura stated in #1119, that is not a big concern, since they are mostly just plain strings.

I’m have the same issue, I was generating a pdf using pdfRenderer in React and the @thekevinbrown solution works, I’m very thankful =D

Anyway, the react-pdf needs to fix the problem