Add "bundle" cli option to make js bundling optional #1634
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Copied from #1390 (comment):
pbjs generates a single bundle of JS for all of the transitive .protos. Therefore if you run pbjs on proto A and then proto B, and both depend on C, then you'll end up with two copies of C's generated JS code -- a.js will contain it, as well as b.js. This is a problem if you need to load proto A and B on the same page for two reasons:
code bloat - you're loading C's code twice. If you need to load many protos and they share dependencies, you'll end up with an explosion of duplicate code.
orphaned object references - because of the way protobuf creates the roots data structure at runtime, every time C is loaded into memory it replaces the previous instance of C. Therefore you can potentially end up with references to different instances of C. Practically I'm not sure what issues this could cause but best to be avoided.
To work around this you could use pbjs to generate one bundle of JS bundle per page, but this isn't ideal for two reasons:
You could also generate one bundle for all pages, but this does not scale.
The fact that pbjs bundles at all is a little weird. The protoc tool doesn't do this for any language, including JS. And even for web browsers this isn't ideal for the reasons stated. If bundling is needed, asset bundlers (e.g. rollup / webpack) should be used for this.
Example
my/protos/c.proto
my/protos/a.proto
my/protos/b.proto
Strategy 1: run pbjs on each proto
pbjs --target static-module --out a.js a.proto
pbjs --target static-module --out b.js b.proto
Strategy 2: generate one js bundle per page with pbjs
pbjs --target static-module --out page_1.js a.proto
pbjs --target static-module --out page_2.js b.proto
page 1
page 2
Strategy 3: generate one .js file for every .proto
pbjs --target static-module --path out/ --no-bundle a.proto
pbjs --target static-module --path out/ --no-bundle b.proto
pbjs --target static-module --path out/ --no-bundle c.proto
page 1
page 2