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.
Summary
inquire() will always return null in browsers with default CPS settings, even if the requested module is present. This PR fixes that issue while maintaining all desired bundling behavior or inquire.
Problem
While investigating protobufjs#1483 I found that browsers are blocking the execution of eval() in inquire(). This repl reproduces and investigates the issue.
The purpose of inquire is to require a module if it is already available in the environment, but "hide" the module from bundlers so that it is not included as a dependency. To do this, inquire js used eval() and regex as a workaround so that bundlers do not notice the require call during static code analysis:
Unfortunately, today's browsers have CPS settings that block eval() by default, so inquire() cannot require any modules at all (including modules that are available in the environment). Changing the defaults so that 'unsafe-eval' is allowed, which affects the entire page and is not recommended for security. In addition to the functional issues, many less experienced web developers using protobufJS see warning messages in the browser console and think that they must allow unsafe-eval to use protobufjs, for example protobufjs#593, protobufjs#1483.
We can show that inquire() does not work with CPS defaults by simulating the browser environment like this:
We can reason that result will always be null.
Solution
Using eval() for this made sense 10+ years ago. There is now an accepted "standard" way of configuring "externals" so dynamic requires can be made while excluding those modules from the bundles. It is implemented by all major bundlers including webpack, browserify (gulp), rollup, and possibly others. By using this standard we can exclude inquired modules (
long
andbuffer
) from protobufjs distributions.There is also now a way to instruct bundlers not to include dependencies of protobufJS distributions: https://github.com/defunctzombie/package-browser-field-spec#ignore-a-module. This can be used to prevent webpack from bundling
long
with my website that uses protobufjs.Implementation