Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: compatibility with modern web bundlers and browsers #1891

Merged
merged 29 commits into from Jul 11, 2022

Conversation

carlobeltrame
Copy link
Contributor

@carlobeltrame carlobeltrame commented Jun 17, 2022

As discussed in #1317, react-pdf currently cannot be used out of the box with modern ES bundlers such as Vite or Rollup (which react-pdf even uses itself for building the various packages). The reason was that react-pdf contains code which references node.js builtin modules such as Buffer, stream, zlib etc., which are not natively available in browsers.

This PR creates new browser-specific builds for all the @react-pdf packages that need it. This way, I was able to leave the node.js-specific builds almost untouched. After this PR, react-pdf can be used in an app without having to add any bundler config (such as described here for Webpack 4 and 5) or bundler shims (such as this one for Vite). You can simply install @react-pdf/renderer and start using it right away, the way it should be.

Fixes #1317, fixes #1645, fixes #1899, fixes #1847, fixes #1886, fixes #1744, fixes #1670, fixes #1669, fixes #1915, fixes #1786, fixes #1944, fixes #1966

Screenshot from 2022-06-17 09-46-22

To acheive this, I had to bundle some commonjs dependencies with the browser versions of react-pdf:

  • blob-stream
  • restructure
  • dfa (was already bundled before)
  • vite-compatible-readable-stream
  • browserify-zlib

This was necessary because these packages are in commonjs format (instead of ES6 module format) and will be misinterpreted when using a modern ES6 module bundler.

(Fun fact, I actually did the whole thing twice, but the first time around I learned so much about rollup that I decided it was worth doing a second time because the resulting rollup configs would be much cleaner 😆)

While I was at it, I also updated the restructure package to the latest version, which has been requested in #1451 for a long time now.

TODO:

@carlobeltrame carlobeltrame changed the title Browser compatibility Out-of-the-box compatibility with modern web bundlers and browsers Jun 17, 2022
@diegomura
Copy link
Owner

Thanks for working on this @carlobeltrame ! Having full support of bundlers is certainly tricky.

I have doubts though regarding bundling all those libs inside react-pdf. Wouldn't that have as a consequence duplicated dependencies being bundled in projects? Ex. react-pdf is bundled with browserify-zlib, and a project has another dep that needs it. Now your webpage ships two copies of browserify-zlib and there's no way to reconcile them into one. That's why the recommended way is still configuring the bundlers yourself.

I'm not that familiarized with Vite, but there isn't a way to polyfill these objects as it is with webpack5?

@carlobeltrame
Copy link
Contributor Author

Thanks for your concern! I will try to explain why I think bundling the dependencies is the better alternative. Sorry if this is a little long, but I think it's worth to consider all the intricacies of this matter.

Vite does have configuration options to alias certain packages to others. But if you want to go that route, it will be necessary to create and maintain either plugins/shims or documentation for all popular current and future web bundlers, of which there are now many (Webpack 4, Webpack 5, Rollup, ESBuild, Vite, Parcel, Snowpack, ...) and there will be more in the future. The times of everyone using Webpack are over - sadly or not, depending on who you ask.

While these bundlers all have different ways to configure workarounds such as aliases and polyfills, they do agree on the ES6 module standard. So the end goal for every package in the javascript ecosystem should be to follow that standard. If a package does that, it will work with any of the above bundlers.

Bundling these dependencies with react-pdf does prevent reconciling them if a project happens to require the same package in some other place. But consider that this is just a temporary measure: Ideally, an isomorphic package such as react-pdf shouldn't use node builtins at all. So one solution would be to switch react-pdf also on the server side to all isomorphic dependencies, i.e. stop using Buffer, stream and any third-party packages which depend on them.

A good example is the restructure package: While I was working on this PR, Devon Govett started working on dropping all node builtin dependencies from that package: foliojs/restructure#48. The way forward for react-pdf would be to wait for all its dependencies to do the same modernization, and once they did react-pdf can stop bundling these dependencies and return to the ES6 module way of just importing them.

Let's look at the packages which I had to bundle in this PR in a little more detail:

  • blob-stream is a package by pdfkit author (and creator of the Parcel bundler) Devon Govett, and he hasn't updated it since 2014. There is an unanswered open PR from January this year which attempts to fix this. I would say the probability of this package ever upgrading is fairly low, and it's also a very small package. So the impact on our bundle should be bearable. Alternative would be to stop using blob-stream for converting the PDF stream to a browser blob in toBlob in the renderer package. TBH, in my eyes it was wrong from the start to use this node.js-dependent package in the toBlob function which is only available in browsers (no offense, the pdfkit documentation recommends blob-stream for exactly this.) Another more modern package for this would be stream-to-blob, or we could also implement this ourselves, because it is quite trivial to do.
  • restructure is another package by Devon Govett. As mentioned above, he actually just created a new version which is completely isomorphic. But he also raised the minimum Node requirement to Node 14. So once you are ready to release a breaking change version of react-pdf and drop Node 12 support, we can update restructure, adapt our copy of fontkit to the breaking changes Devon had to make (i.e. no more streams, only Uint8Array buffers which are available in Node and in browsers) and we will no longer have to bundle restructure.
  • dfa, yet another of Devon's packages, was bundled with react-pdf before this PR by @jeetiss, so I assume it's okay to keep it bundled.
  • vite-compatible-readable-stream was created by @thekevinbrown for his Vite shim. Before doing that, he took part in the discussion about rollup compatibility in readable-stream. The discussion issue has been closed a month ago, but I tried with the current version of readable-stream and it did not work for me. But since the vite-compatible-readable-stream package was created specifically for the Vite shim, I think the probability of duplicating this dependency in peoples projects is quite low so far. Ideally, the nodejs team would publish a fully ES6 compatible version of readable-stream, without circular dependencies, now that node has (at least partially?) adapted the reference implementation.
  • browserify-zlib once again was created by Devon Govett, and was last updated in 2017. This one I think is the most likely to be duplicated in people's project dependencies. To remedy this, we could switch to the isomorphic pako package, which does not directly aim to recreate the node.js builtin zlib, but appears to be faster. We use zlib in pdfkit and in png-js, in a total of 3 separate source files. Should be doable. Let me know if you'd like me to work on this.

Please also consider that these dependencies are only bundled in the new browser-ready versions of the @react-pdf packages. The node versions should be completely unaffected.
If you still insist on leaving these dependencies out of the bundle, and require every user of react-pdf to change their web project's build config by default, I can change that in this PR, most of the work I did will still be a valid step forward.

@carlobeltrame
Copy link
Contributor Author

@Belkacem If you want to help out by testing this PR, you can follow the instructions in https://github.com/diegomura/react-pdf/blob/master/.github/CONTRIBUTING.md, they are well written. I followed them myself for working on this PR, and it was quite easy to do.
I would avoid using this in production for now, the debate on the details is still very much open and it's possible that @diegomura will insist on restrictions that will prevent you from adopting it. I would really like him to agree and support the direction we are taking with react-pdf, since he has so much experience developing this library. (Also I don't really want to clutter npm with another temporary package. I don't have write permissions on the @react-pdf npm organization, this is one of my first PRs in this repository).
If you really need a published package on npm at any cost, you can fork my fork and publish it to your own separate npm organization.

@devongovett
Copy link

Hi guys. I've been slowly working on updating my old libraries. When I started working on them (over 10 years ago), there wasn't even a way to represent binary data in JS, so things have come a long way since then 😄. I released restructure v3 and fontkit v2 recently, which drop all node-specific dependencies. Here’s a demo working in the browser with no additional build step.

The plan would be to get there with pdfkit as well. It'll take a bit of work to drop Node streams, and other node dependencies like Buffer, zlib and crypto for browser versions, but I think it can be done. Ideally we'd synchronize with the react-pdf community as well, and get you back on the mainline versions rather than custom forks where possible. @diegomura is already a maintainer in the foliojs org on GitHub, with write access to the repos, and I'm happy to add others as needed as well. Please let me know if you'd like to help with this effort. I have very limited time, but I'm trying to fit it in.

@carlobeltrame
Copy link
Contributor Author

That sounds absolutely great. Thanks so much for the huge amount of work you did already!

I could definitely imagine helping out with replacing node dependencies in pdfkit, but I am still relatively new to the whole PDF ecosystem, so I'll probably start out helping in small pieces.

Returning react-pdf to using the original foliojs packages would be great in my opinion. But I don't know why @diegomura chose to hard fork them in the first place. In fontkit for example, I see almost no react-pdf-specific changes, except for #1839 which actually caused another regression for non-webpack browser users.
In fact, these forks may also result in "duplicated dependencies being bundled in projects" themselves (to cite @diegomura's own comment from above), and in duplicated work across the two forcibly separated communities (such as #1557 and foliojs/fontkit#267).

@diegomura
Copy link
Owner

Hey guys! Sorry for the late response. Been very busy and also sick this past week.

Thanks so much @carlobeltrame for such a clear and detailed explanation! This is a field in which I don't really have much experience. I now agree this is the right direction, specially considering @devongovett efforts on making the foliojs packages really isomorphic. I'll test with webpack4 and webpack5. What else you think it's blocking this to get merged? Would love to rely on you to lead this effort 😄

Hey @devongovett ! Nice to talk to you again. Thanks for your new work on the restructure and textkit repos! I would love to get back to the mainline repo. Haven't yet take a look, but is there anywhere I can read about how to migrate to textkit v2? @carlobeltrame how this bump would affect this PR?

I'd love to get back to the foliojs packages and join both communities efforts 😄 This is completely my fault. I've been a foliojs maintainer for awhile, but some time ago decided to fork because was simpler to me not having to think about how changes in those packages affected other users of the libs. Maintaining the react-pdf org demands me more time that I have already, so thinking of maintaining two orgs was more than I could take. Also, considering react-pdf is quite big already (mostly due to Yoga), was a good strategy to trim some pieces of the foliojs projects I didn't need and make it smaller. But I now see that leads to repetitive work and sometimes more effort on my side trying to keep up with the changes. I'll make removing the textkit fork a prio

@carlobeltrame
Copy link
Contributor Author

Apart from testing (especially on node.js), CI is currently failing during the size check. I am trying to find out which commit exactly broke it, and find a fix.
Other than that, I'd say this is ready, and we can then work on top of this basis to return to the foliojs originals and upgraded devongovett packages, and start dropping node-only dependencies this way. As mentioned above, this will likely require a major version change of react-pdf, because Devon dropped support for Node v12. End of life of Node v12 was on April 30th 2022.

@diegomura
Copy link
Owner

Something I haven't confirmed yet it's broken but it might be: in some places we import some textkit files as @react-pdf/textkit/lib/*.js. I started a branch to fix this, but couldn't wrap it up. Maybe you found a way to fix this already

@devongovett
Copy link

devongovett commented Jun 28, 2022

@diegomura I haven't touched textkit to be clear - only fontkit. As for migration, you can see the changes here - there weren't many. Upgrade is going to happen in PDFKit here: foliojs/pdfkit#1367. Would be great if you want to test that with react-pdf. Let me know if there are other changes you need back ported from your forks to any of the foliojs repos.

@carlobeltrame
Copy link
Contributor Author

Something I haven't confirmed yet it's broken but it might be: in some places we import some textkit files as @react-pdf/textkit/lib/*.js. I started a branch to fix this, but couldn't wrap it up. Maybe you found a way to fix this already

You mean like here? Yeah, I replaced those imports, by exporting anything that's needed externally from textkit. This is something that might need backporting to foliojs textkit I guess. Not sure what you mean by "broken", but basic text layouting definitely works. I haven't tested svg yet, will do that as well then.

carlobeltrame added a commit to carlobeltrame/react-pdf that referenced this pull request Jun 29, 2022
This is necessary because we had to add some browser-compatible
alternatives for node-only dependencies and builtins.
See diegomura#1891 for more details.
@diegomura
Copy link
Owner

Yes meant fontkit. Typo 😄 I'll work this weekend on trying to get on the fontkit mainline repo. That also includes unicode-properties that is also forked under this repo. I then work on pdfkit, but that won't be that straightforward unfortunately, specially because of text rendering. foliojs used to have a renderGlyphs method I added but got deleted at some moment. We might need to add that back, or move that logic to react-pdf side. I also added some simple extra params that I'll add on the foliojs repo eventually

diegomura pushed a commit to carlobeltrame/react-pdf that referenced this pull request Jul 2, 2022
This is necessary because we had to add some browser-compatible
alternatives for node-only dependencies and builtins.
See diegomura#1891 for more details.
Comment on lines 24 to 38
const babelConfig = ({ browser }) => ({
babelrc: false,
babelHelpers: 'runtime',
exclude: 'node_modules/**',
presets: [
[
'@babel/preset-env',
{
loose: true,
modules: false,
targets: { node: '12', browsers: 'last 2 versions' },
},
}),
),
external: ['fs'],
],
],
plugins: [['@babel/plugin-transform-runtime', { version: '^7.16.4' }]],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use babelrc: true as config so we don't duplicate config here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I went ahead and did this for all packages.

@diegomura
Copy link
Owner

diegomura commented Jul 2, 2022

@carlobeltrame rebased with upstream changes. Hope you don't mind. Would like to prioritize this!

However, testing this branch, building pdfkit and textkit fails. Do the same happen to you?

Also, what makes the new restructure version incompatible with Node 12? If we need to bump the minimum Node version to 14 to use isomorphic APIs I'd say we should just do it

@alexn-s
Copy link

alexn-s commented Jul 3, 2022

just encountered the same issue. i also tried using the shim but sadly could not get it to work for me.

@thekevinbrown
Copy link

There was a new usage of Buffer put in recently which broke the shim. I'll be pushing a new release today.

diegomura pushed a commit to carlobeltrame/react-pdf that referenced this pull request Jul 4, 2022
This is necessary because we had to add some browser-compatible
alternatives for node-only dependencies and builtins.
See diegomura#1891 for more details.
@diegomura
Copy link
Owner

diegomura commented Jul 4, 2022

@carlobeltrame I was just able to run builds. I noticed that pdfkit.browser.cjs.js goes from ~380kb to ~960kb. This is huge. I understand we are now bundling all these shims inside the lib but is it really that heavy? I feel a bit reluctant about shipping bundles that big. Master now uses latest restructure and mainline fontkit. When we can shift to isomorphic pdfkit will all these configs be necessary?

@alexn-s
Copy link

alexn-s commented Jul 4, 2022

There was a new usage of Buffer put in recently which broke the shim. I'll be pushing a new release today.

awesome. i appreciate it. btw does anyone get react-pdf to work with storybook. i am having issue after issue and cant get it to work

@carlobeltrame
Copy link
Contributor Author

@carlobeltrame pdfkit.browser.cjs.js goes from ~380kb to ~960kb

I can have a look at what takes up this much space.

When we can shift to isomorphic pdfkit will all these configs be necessary?

As soon as pdfkit is isomorphic and we switch to that, all these rollup configs can of course be deleted along with the @react-pdf/xyz forks of the packages.

@carlobeltrame
Copy link
Contributor Author

I analyzed the package size using rollup-plugin-sizes. Here is what I found:

Before this PR, just app code (~380kB)
src/index.js:
app - 272.47 KB (99.77%)
	font/data/index.json - 163.55 KB (60.02%)
	path.js - 11.16 KB (4.09%)
	mixins/acroform.js - 10.11 KB (3.71%)
	mixins/vector.js - 8.86 KB (3.25%)
	mixins/color.js - 8 KB (2.93%)
	document.js - 7.83 KB (2.88%)
	font/embedded.js - 7.68 KB (2.82%)
	font/afm.js - 7.29 KB (2.68%)
	gradient.js - 5.95 KB (2.18%)
	mixins/text.js - 5.3 KB (1.94%)
	image/png.js - 4.96 KB (1.82%)
	mixins/attachments.js - 3.59 KB (1.32%)
	page.js - 3.56 KB (1.31%)
	mixins/annotations.js - 3.47 KB (1.27%)
	object.js - 2.81 KB (1.03%)
	mixins/images.js - 2.25 KB (0.83%)
	outline.js - 2.07 KB (0.76%)
	reference.js - 2.01 KB (0.74%)
	font/standard.js - 1.93 KB (0.71%)
	mixins/fonts.js - 1.9 KB (0.70%)
	image/jpeg.js - 1.78 KB (0.65%)
	font.js - 1.75 KB (0.64%)
	tree.js - 1.4 KB (0.52%)
	image.js - 809 B (0.29%)
	security.js - 749 B (0.27%)
	font/data/expandData.js - 633 B (0.23%)
	mixins/outline.js - 377 B (0.14%)
	utils/range.js - 306 B (0.11%)
	name_tree.js - 298 B (0.11%)
	index.js - 91 B (0.03%)
	utils/capitalize.js - 85 B (0.03%)
@babel/runtime - 657 B (0.23%)
	helpers/esm/createClass.js - 657 B (100.00%)
With this PR, before any manual externalizing (~960kB)
src/index.js:
app - 272.47 KB (31.90%)
	font/data/index.json - 163.55 KB (60.02%)
	path.js - 11.16 KB (4.09%)
	mixins/acroform.js - 10.11 KB (3.71%)
	mixins/vector.js - 8.86 KB (3.25%)
	mixins/color.js - 8 KB (2.93%)
	document.js - 7.83 KB (2.88%)
	font/embedded.js - 7.68 KB (2.82%)
	font/afm.js - 7.29 KB (2.68%)
	gradient.js - 5.95 KB (2.18%)
	mixins/text.js - 5.3 KB (1.94%)
	image/png.js - 4.96 KB (1.82%)
	mixins/attachments.js - 3.59 KB (1.32%)
	page.js - 3.56 KB (1.31%)
	mixins/annotations.js - 3.47 KB (1.27%)
	object.js - 2.81 KB (1.03%)
	mixins/images.js - 2.25 KB (0.83%)
	outline.js - 2.07 KB (0.76%)
	reference.js - 2.01 KB (0.74%)
	font/standard.js - 1.93 KB (0.71%)
	mixins/fonts.js - 1.9 KB (0.70%)
	image/jpeg.js - 1.78 KB (0.65%)
	font.js - 1.75 KB (0.64%)
	tree.js - 1.4 KB (0.52%)
	image.js - 809 B (0.29%)
	security.js - 749 B (0.27%)
	font/data/expandData.js - 633 B (0.23%)
	mixins/outline.js - 377 B (0.14%)
	utils/range.js - 306 B (0.11%)
	name_tree.js - 298 B (0.11%)
	index.js - 91 B (0.03%)
	utils/capitalize.js - 85 B (0.03%)
pako - 183.62 KB (21.50%)
	lib/zlib/deflate.js - 59.75 KB (32.54%)
	lib/zlib/inflate.js - 49.11 KB (26.74%)
	lib/zlib/trees.js - 38.94 KB (21.21%)
	lib/zlib/inffast.js - 12.37 KB (6.74%)
	lib/zlib/inftrees.js - 12.21 KB (6.65%)
	lib/utils/common.js - 2.39 KB (1.30%)
	lib/zlib/constants.js - 2.26 KB (1.23%)
	lib/zlib/zstream.js - 1.77 KB (0.96%)
	lib/zlib/crc32.js - 1.71 KB (0.93%)
	lib/zlib/adler32.js - 1.62 KB (0.88%)
	lib/zlib/messages.js - 1.5 KB (0.82%)
vite-compatible-readable-stream - 96.08 KB (11.25%)
	lib/_stream_readable.js - 35.04 KB (36.47%)
	lib/_stream_writable.js - 21.26 KB (22.13%)
	lib/_stream_transform.js - 7.8 KB (8.12%)
	lib/internal/streams/buffer_list.js - 6.19 KB (6.44%)
	lib/internal/streams/async_iterator.js - 5.82 KB (6.05%)
	lib/_stream_duplex.js - 4.29 KB (4.46%)
	errors-browser.js - 4.1 KB (4.27%)
	lib/internal/streams/destroy.js - 3.04 KB (3.17%)
	lib/internal/streams/end-of-stream.js - 3.03 KB (3.15%)
	lib/internal/streams/pipeline.js - 2.37 KB (2.47%)
	lib/_stream_passthrough.js - 1.6 KB (1.66%)
	lib/internal/streams/state.js - 749 B (0.76%)
	readable-browser.js - 656 B (0.67%)
	lib/internal/streams/from-browser.js - 101 B (0.10%)
	lib/internal/streams/stream-browser.js - 49 B (0.05%)
	lib/_registry.js - 21 B (0.02%)
assert - 67.8 KB (7.94%)
	build/internal/assert/assertion_error.js - 21.39 KB (31.55%)
	build/internal/util/comparisons.js - 20.23 KB (29.83%)
	build/assert.js - 19.04 KB (28.09%)
	build/internal/errors.js - 7.14 KB (10.53%)
rollup helpers - 61.93 KB (7.25%)
	polyfill-node.buffer.js - 53.08 KB (85.71%)
	polyfill-node.process.js - 6.22 KB (10.04%)
	commonjsHelpers.js - 1.27 KB (2.05%)
	node-resolve:empty.js?commonjs-proxy - 196 B (0.31%)
	polyfill-node.global.js - 143 B (0.23%)
	/home/cbeltrame/git/react-pdf/node_modules/inherits/inherits_browser.js?commonjs-module - 75 B (0.12%)
	/home/cbeltrame/git/react-pdf/node_modules/vite-compatible-readable-stream/readable-browser.js?commonjs-module - 73 B (0.12%)
	/home/cbeltrame/git/react-pdf/node_modules/safe-buffer/index.js?commonjs-module - 63 B (0.10%)
	/home/cbeltrame/git/react-pdf/node_modules/string_decoder/lib/string_decoder.js?commonjs-exports - 61 B (0.10%)
	/home/cbeltrame/git/react-pdf/node_modules/vite-compatible-readable-stream/errors-browser.js?commonjs-exports - 59 B (0.09%)
	/home/cbeltrame/git/react-pdf/node_modules/call-bind/index.js?commonjs-module - 59 B (0.09%)
	/home/cbeltrame/git/react-pdf/node_modules/events/events.js?commonjs-module - 55 B (0.09%)
	/home/cbeltrame/git/react-pdf/node_modules/assert/build/assert.js?commonjs-module - 55 B (0.09%)
	/home/cbeltrame/git/react-pdf/node_modules/base64-js/index.js?commonjs-exports - 49 B (0.08%)
	/home/cbeltrame/git/react-pdf/node_modules/ieee754/index.js?commonjs-exports - 47 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/browserify-zlib/lib/binding.js?commonjs-exports - 47 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/pako/lib/zlib/deflate.js?commonjs-exports - 47 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/pako/lib/zlib/inflate.js?commonjs-exports - 47 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/buffer/index.js?commonjs-exports - 45 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/assert/build/internal/errors.js?commonjs-exports - 45 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/pako/lib/utils/common.js?commonjs-exports - 45 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/util/support/types.js?commonjs-exports - 43 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/pako/lib/zlib/trees.js?commonjs-exports - 43 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/util/util.js?commonjs-exports - 41 B (0.06%)
	/home/cbeltrame/git/react-pdf/node_modules/browserify-zlib/lib/index.js?commonjs-exports - 39 B (0.06%)
	node-resolve:empty.js - 18 B (0.03%)
buffer - 48.92 KB (5.73%)
	index.js - 48.92 KB (100.00%)
util - 27.92 KB (3.27%)
	util.js - 19.25 KB (68.95%)
	support/types.js - 8.47 KB (30.34%)
	support/isBufferBrowser.js - 203 B (0.71%)
browserify-zlib - 27.09 KB (3.17%)
	lib/index.js - 16.31 KB (60.19%)
	lib/binding.js - 10.79 KB (39.81%)
events - 14.54 KB (1.70%)
	events.js - 14.54 KB (100.00%)
get-intrinsic - 12.21 KB (1.43%)
	index.js - 12.21 KB (100.00%)
string_decoder - 9.24 KB (1.08%)
	lib/string_decoder.js - 9.24 KB (100.00%)
object-keys - 4.36 KB (0.51%)
	implementation.js - 3.14 KB (72.10%)
	index.js - 823 B (18.44%)
	isArguments.js - 422 B (9.46%)
base64-js - 3.84 KB (0.45%)
	index.js - 3.84 KB (100.00%)
has-symbols - 2.13 KB (0.25%)
	shams.js - 1.72 KB (80.74%)
	index.js - 420 B (19.26%)
ieee754 - 2.1 KB (0.25%)
	index.js - 2.1 KB (100.00%)
is-typed-array - 1.77 KB (0.21%)
	index.js - 1.77 KB (100.00%)
call-bind - 1.68 KB (0.20%)
	index.js - 1.28 KB (75.97%)
	callBound.js - 413 B (24.03%)
safe-buffer - 1.63 KB (0.19%)
	index.js - 1.63 KB (100.00%)
which-typed-array - 1.63 KB (0.19%)
	index.js - 1.63 KB (100.00%)
util-deprecate - 1.58 KB (0.18%)
	browser.js - 1.58 KB (100.00%)
define-properties - 1.57 KB (0.18%)
	index.js - 1.57 KB (100.00%)
function-bind - 1.55 KB (0.18%)
	implementation.js - 1.43 KB (92.07%)
	index.js - 126 B (7.93%)
is-nan - 1.2 KB (0.14%)
	index.js - 462 B (37.56%)
	shim.js - 387 B (31.46%)
	polyfill.js - 225 B (18.29%)
	implementation.js - 156 B (12.68%)
es6-object-assign - 1.14 KB (0.13%)
	index.js - 1.14 KB (100.00%)
object-is - 1.14 KB (0.13%)
	index.js - 390 B (33.53%)
	shim.js - 306 B (26.31%)
	implementation.js - 286 B (24.59%)
	polyfill.js - 181 B (15.56%)
is-arguments - 1012 B (0.12%)
	index.js - 1012 B (100.00%)
is-generator-function - 964 B (0.11%)
	index.js - 964 B (100.00%)
inherits - 753 B (0.09%)
	inherits_browser.js - 753 B (100.00%)
@babel/runtime - 657 B (0.08%)
	helpers/esm/createClass.js - 657 B (100.00%)
foreach - 555 B (0.06%)
	index.js - 555 B (100.00%)
available-typed-arrays - 519 B (0.06%)
	index.js - 519 B (100.00%)
es-abstract - 262 B (0.03%)
	helpers/getOwnPropertyDescriptor.js - 262 B (100.00%)
has-tostringtag - 162 B (0.02%)
	shams.js - 162 B (100.00%)
has - 129 B (0.01%)
	src/index.js - 129 B (100.00%)
After this PR, when externalizing `pako` (~780kB)
src/index.js:
app - 272.47 KB (40.65%)
	font/data/index.json - 163.55 KB (60.02%)
	path.js - 11.16 KB (4.09%)
	mixins/acroform.js - 10.11 KB (3.71%)
	mixins/vector.js - 8.86 KB (3.25%)
	mixins/color.js - 8 KB (2.93%)
	document.js - 7.83 KB (2.88%)
	font/embedded.js - 7.68 KB (2.82%)
	font/afm.js - 7.29 KB (2.68%)
	gradient.js - 5.95 KB (2.18%)
	mixins/text.js - 5.3 KB (1.94%)
	image/png.js - 4.96 KB (1.82%)
	mixins/attachments.js - 3.59 KB (1.32%)
	page.js - 3.56 KB (1.31%)
	mixins/annotations.js - 3.47 KB (1.27%)
	object.js - 2.81 KB (1.03%)
	mixins/images.js - 2.25 KB (0.83%)
	outline.js - 2.07 KB (0.76%)
	reference.js - 2.01 KB (0.74%)
	font/standard.js - 1.93 KB (0.71%)
	mixins/fonts.js - 1.9 KB (0.70%)
	image/jpeg.js - 1.78 KB (0.65%)
	font.js - 1.75 KB (0.64%)
	tree.js - 1.4 KB (0.52%)
	image.js - 809 B (0.29%)
	security.js - 749 B (0.27%)
	font/data/expandData.js - 633 B (0.23%)
	mixins/outline.js - 377 B (0.14%)
	utils/range.js - 306 B (0.11%)
	name_tree.js - 298 B (0.11%)
	index.js - 91 B (0.03%)
	utils/capitalize.js - 85 B (0.03%)
vite-compatible-readable-stream - 96.08 KB (14.34%)
	lib/_stream_readable.js - 35.04 KB (36.47%)
	lib/_stream_writable.js - 21.26 KB (22.13%)
	lib/_stream_transform.js - 7.8 KB (8.12%)
	lib/internal/streams/buffer_list.js - 6.19 KB (6.44%)
	lib/internal/streams/async_iterator.js - 5.82 KB (6.05%)
	lib/_stream_duplex.js - 4.29 KB (4.46%)
	errors-browser.js - 4.1 KB (4.27%)
	lib/internal/streams/destroy.js - 3.04 KB (3.17%)
	lib/internal/streams/end-of-stream.js - 3.03 KB (3.15%)
	lib/internal/streams/pipeline.js - 2.37 KB (2.47%)
	lib/_stream_passthrough.js - 1.6 KB (1.66%)
	lib/internal/streams/state.js - 749 B (0.76%)
	readable-browser.js - 656 B (0.67%)
	lib/internal/streams/from-browser.js - 101 B (0.10%)
	lib/internal/streams/stream-browser.js - 49 B (0.05%)
	lib/_registry.js - 21 B (0.02%)
assert - 67.8 KB (10.12%)
	build/internal/assert/assertion_error.js - 21.39 KB (31.55%)
	build/internal/util/comparisons.js - 20.23 KB (29.83%)
	build/assert.js - 19.04 KB (28.09%)
	build/internal/errors.js - 7.14 KB (10.53%)
rollup helpers - 61.75 KB (9.21%)
	polyfill-node.buffer.js - 53.08 KB (85.96%)
	polyfill-node.process.js - 6.22 KB (10.07%)
	commonjsHelpers.js - 1.27 KB (2.05%)
	node-resolve:empty.js?commonjs-proxy - 196 B (0.31%)
	polyfill-node.global.js - 143 B (0.23%)
	/home/cbeltrame/git/react-pdf/node_modules/inherits/inherits_browser.js?commonjs-module - 75 B (0.12%)
	/home/cbeltrame/git/react-pdf/node_modules/vite-compatible-readable-stream/readable-browser.js?commonjs-module - 73 B (0.12%)
	/home/cbeltrame/git/react-pdf/node_modules/safe-buffer/index.js?commonjs-module - 63 B (0.10%)
	/home/cbeltrame/git/react-pdf/node_modules/string_decoder/lib/string_decoder.js?commonjs-exports - 61 B (0.10%)
	/home/cbeltrame/git/react-pdf/node_modules/vite-compatible-readable-stream/errors-browser.js?commonjs-exports - 59 B (0.09%)
	/home/cbeltrame/git/react-pdf/node_modules/call-bind/index.js?commonjs-module - 59 B (0.09%)
	/home/cbeltrame/git/react-pdf/node_modules/events/events.js?commonjs-module - 55 B (0.09%)
	/home/cbeltrame/git/react-pdf/node_modules/assert/build/assert.js?commonjs-module - 55 B (0.09%)
	/home/cbeltrame/git/react-pdf/node_modules/base64-js/index.js?commonjs-exports - 49 B (0.08%)
	/home/cbeltrame/git/react-pdf/node_modules/ieee754/index.js?commonjs-exports - 47 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/browserify-zlib/lib/binding.js?commonjs-exports - 47 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/buffer/index.js?commonjs-exports - 45 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/assert/build/internal/errors.js?commonjs-exports - 45 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/util/support/types.js?commonjs-exports - 43 B (0.07%)
	/home/cbeltrame/git/react-pdf/node_modules/util/util.js?commonjs-exports - 41 B (0.06%)
	/home/cbeltrame/git/react-pdf/node_modules/browserify-zlib/lib/index.js?commonjs-exports - 39 B (0.06%)
	node-resolve:empty.js - 18 B (0.03%)
buffer - 48.92 KB (7.30%)
	index.js - 48.92 KB (100.00%)
util - 27.92 KB (4.17%)
	util.js - 19.25 KB (68.95%)
	support/types.js - 8.47 KB (30.34%)
	support/isBufferBrowser.js - 203 B (0.71%)
browserify-zlib - 27.09 KB (4.04%)
	lib/index.js - 16.31 KB (60.19%)
	lib/binding.js - 10.79 KB (39.81%)
events - 14.54 KB (2.17%)
	events.js - 14.54 KB (100.00%)
get-intrinsic - 12.21 KB (1.82%)
	index.js - 12.21 KB (100.00%)
string_decoder - 9.24 KB (1.38%)
	lib/string_decoder.js - 9.24 KB (100.00%)
object-keys - 4.36 KB (0.65%)
	implementation.js - 3.14 KB (72.10%)
	index.js - 823 B (18.44%)
	isArguments.js - 422 B (9.46%)
base64-js - 3.84 KB (0.57%)
	index.js - 3.84 KB (100.00%)
has-symbols - 2.13 KB (0.32%)
	shams.js - 1.72 KB (80.74%)
	index.js - 420 B (19.26%)
ieee754 - 2.1 KB (0.31%)
	index.js - 2.1 KB (100.00%)
is-typed-array - 1.77 KB (0.26%)
	index.js - 1.77 KB (100.00%)
call-bind - 1.68 KB (0.25%)
	index.js - 1.28 KB (75.97%)
	callBound.js - 413 B (24.03%)
safe-buffer - 1.63 KB (0.24%)
	index.js - 1.63 KB (100.00%)
which-typed-array - 1.63 KB (0.24%)
	index.js - 1.63 KB (100.00%)
util-deprecate - 1.58 KB (0.24%)
	browser.js - 1.58 KB (100.00%)
define-properties - 1.57 KB (0.23%)
	index.js - 1.57 KB (100.00%)
function-bind - 1.55 KB (0.23%)
	implementation.js - 1.43 KB (92.07%)
	index.js - 126 B (7.93%)
is-nan - 1.2 KB (0.18%)
	index.js - 462 B (37.56%)
	shim.js - 387 B (31.46%)
	polyfill.js - 225 B (18.29%)
	implementation.js - 156 B (12.68%)
es6-object-assign - 1.14 KB (0.17%)
	index.js - 1.14 KB (100.00%)
object-is - 1.14 KB (0.17%)
	index.js - 390 B (33.53%)
	shim.js - 306 B (26.31%)
	implementation.js - 286 B (24.59%)
	polyfill.js - 181 B (15.56%)
is-arguments - 1012 B (0.15%)
	index.js - 1012 B (100.00%)
is-generator-function - 964 B (0.14%)
	index.js - 964 B (100.00%)
inherits - 753 B (0.11%)
	inherits_browser.js - 753 B (100.00%)
@babel/runtime - 657 B (0.10%)
	helpers/esm/createClass.js - 657 B (100.00%)
foreach - 555 B (0.08%)
	index.js - 555 B (100.00%)
available-typed-arrays - 519 B (0.08%)
	index.js - 519 B (100.00%)
es-abstract - 262 B (0.04%)
	helpers/getOwnPropertyDescriptor.js - 262 B (100.00%)
has-tostringtag - 162 B (0.02%)
	shams.js - 162 B (100.00%)
has - 129 B (0.02%)
	src/index.js - 129 B (100.00%)

By externalizing the transitive dependency pako (which is used by unicode-trie and browserify-zlib), I was able to reduce the package size somewhat. As stated before, the way forward will yield larger size reductions, but I think pako was an ideal candidate for reducing the size right now.

@carlobeltrame
Copy link
Contributor Author

carlobeltrame commented Jul 5, 2022

From my perspective, this PR is ready to merge now. I also tested a basic SVG. I haven't gotten it to run in a web worker, but I can have a look at that later. @diegomura let me know in case you see anything else you'd like me to change before merging, or if you find anything that does not work in a Node.js environment (which I did not test, because I only develop for the browser).

@diegomura
Copy link
Owner

Thanks so much @carlobeltrame ! You're great. Couple of follow up questions if you don't mind. Not trying to block it (sorry, I would like to merge this asap as well), but trying to still understand some things

I think we need externalize assert as well. That's a incredibly popular library and adding 70kb to react-pdf for it doesn't make sense

Also, what are rollup helpers? With this and vite-compatible-readable-stream aren't we shipping specific bundler tooling inside this lib now? That's what I'm most concerned about

@Uzaaft
Copy link

Uzaaft commented Aug 11, 2022

@terragady See the issues above. We're waiting for a release.

@terragady
Copy link

@Uzaaft yes I know and asking what is the current status of that if it is planned in near future?

@Uzaaft
Copy link

Uzaaft commented Aug 11, 2022

And as you can see above, we haven't gotten a response.

@terragady
Copy link

well ok you are not really helpful so not sure why you bother commenting.
Anyway is there any trick to use renderer from master?
this does not work unofrtunatelly
"@react-pdf/renderer": "diegomura/react-pdf#master"
tried also some other options but not sure how to grab the rendered package

@carlobeltrame
Copy link
Contributor Author

carlobeltrame commented Aug 11, 2022

Unfortunately I don't know any trick which you could use for a productive app, since this is a lerna monorepo which npm and yarn don't understand natively. To test locally whether master works in your project you can follow the instructions in .github/CONTRIBUTING.md and use yarn link. Or you could fork the project and publish your own version of the packages to npm. But apart from that, it looks like the maintainer of this package is on vacation or something, so we'll just have to wait.

@Uzaaft
Copy link

Uzaaft commented Aug 11, 2022

@Uzaaft
Copy link

Uzaaft commented Aug 11, 2022

For everyone that's waiting for a release, here is a PR that will include these changes as a release that you guys can track

@dhitimedin
Copy link

https://react-pdf.org/advanced#webpack-5

Hi @carlobeltrame, I did the installation using yarn and followed the steps prescribed for webpack-5. I have react ^18.2.0. The application works by the rendering of the sample application https://react-pdf.org/#2.-create-your-pdf-document is happening only in a portion of the window i.e. in a 300 X 150 px box. Any workaround or/and explanation for this?

So you are using the PDFViewer component and the iframe is only 300x150px, did I get that correctly? You can set the width and height attributes on the PDFViewer, see documentation at https://react-pdf.org/components

Thank you @carlobeltrame, this piece is done. I still am facing an issue while viewing in a responsive frame on Chrome. No text is appearing in this frame. Any Reason for this type of behaviour?

@carlobeltrame
Copy link
Contributor Author

carlobeltrame commented Aug 11, 2022

Thank you @carlobeltrame, this piece is done. I still am facing an issue while viewing in a responsive frame on Chrome. No text is appearing in this frame. Any Reason for this type of behaviour?

Sorry, but I have no idea what you are talking about, and it definitely has nothing to do with this PR here, since this hasn't even been released. This PR is not a general-purpose support channel for react-pdf. Please open a new issue including a reproduction project or REPL.

@jepek
Copy link

jepek commented Aug 11, 2022

Anyway is there any trick to use renderer from master?

@terragady you can try to use @react-pdf-jepek/renderer instead. I have built the packages and published them to the npm while waiting for #1912 to be done.

@terragady
Copy link

@jepek yeah I have used it but there was some error about the _a somewhere and after long fight of upgrading React I just gave up on renderer. I just switched to jspdf for now

@jepek
Copy link

jepek commented Aug 12, 2022

@terragady Ah yea, I am aware of it, something went wrong on postbuild script in yoga (subpackage of react-pdf). I will fix that soon so people who want to use react-pdf/renderer@3.0.0 will be able to use @react-pdf-jepek/renderer

BTW I am experimenting and probably will be switching to pdfmake

@terragady
Copy link

yes I have considered it as well, just use jspdf because it was easy to change as they have htnl2pdf plugin which seemed to be easy (but it is not :) ). Pdfmake is nice but it does not come with Viewer for example, just "open" and "save", where "open" just works with 3 browsers.

I am starting to think to generate PDF on server side, might be easier and better. I am already doing this with shipping labels.

@jepek
Copy link

jepek commented Aug 12, 2022

@terragady for displaying the PDF I am using the react-pdf - works fine.

client vs server - there are always some tradeoffs - whatever works better for you :)

BTW It is so confusing (the names) using react-pdf and @react-pdf/renderer ;)

@terragady
Copy link

terragady commented Aug 15, 2022

@jepek
I still get an error while trying to use your fork (3.0.1):

image

carlobeltrame added a commit to carlobeltrame/ecamp3 that referenced this pull request Aug 30, 2022
@Gratify-Ocelot
Copy link

Hi, I believe this should fix problem with create-react-app v5 using webpack 5. But unfortunately when creating fresh cra application with instruction from quick-start https://react-pdf.org/ I see following errors:

Failed to compile.

Module not found: Error: Can't resolve 'buffer' in '/Users/user/Documents/Code/cra-pdf-test/node_modules/base64-to-uint8array'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
ERROR in ./node_modules/base64-to-uint8array/index.js 8:10-32
Module not found: Error: Can't resolve 'buffer' in '/Users/user/Documents/Code/cra-pdf-test/node_modules/base64-to-uint8array'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }

webpack compiled with 1 error
Files successfully emitted, waiting for typecheck results...
Issues checking in progress...
No issues found.

here is reproduction repo: https://github.com/Gratify-Ocelot/cra-pdf-test

cc: @diegomura @carlobeltrame

@carlobeltrame
Copy link
Contributor Author

carlobeltrame commented Sep 8, 2022

Thanks for reporting! I see that in #1908, @diegomura added base64-to-uint8array as a new dependency to the font package. This happened more or less in parallel to this PR.

The base64-to-uint8array actually doesn't use buffer in a browser context, so the code will still work. But since webpack 5 does not do tree shaking by default, it still tries to compile the node.js code as well, which fails. You can see in the source code that the author tried to work around this problem by splitting the buffer string into two parts.

The node.js-specific code using Buffer in that package is actually completely unnecessary nowadays, since Uint8Array is also available on node.js since node 10. So, given that the base64-to-uint8array package has never been updated since its initial commit 5 years ago, I think we could just replace the single use of that package with the single line of code line which is relevant for us.

@Gratify-Ocelot
Copy link

Cool, should we expect this change in the next version? Seems like a good opportunity to remove some unnecessary dependency

@carlobeltrame
Copy link
Contributor Author

I probably don't have time for it before the second half of the month. If it's urgent for you, you should be able to create the fix yourself, based on the information above.

@Gratify-Ocelot
Copy link

Sure, no worries, take your time. Is there any possibility to subscribe to some issue or pull request to be notified when it's done?

@Gratify-Ocelot
Copy link

thanks @thekevinbrown,

@carlobeltrame can you create draft issue or pull-request for this change so I can subscribe for notifications?

@carlobeltrame
Copy link
Contributor Author

Sorry, no time. Feel free to open a new bug issue yourself with the info from your first comment. I'll make sure to reference that if I'm the first person to fix it

@hj462
Copy link

hj462 commented May 29, 2023

Screenshot 2023-05-29 at 8 54 51 pm

Its working for me on local, But when I build app. It throws this error. Please need help here

React v18

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment