[BREAKING/v3] Exclude node builtins from build #1604
Merged
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.
TL;DR: exclude node builtins from build to make packages that import them but don't use them at runtime work. Works in esbuild mode and webpack mode, althought slightly differently.
Webpack v5 has stopped providing polyfills for imported Node builtins, as it's considered bad practice to import a "node" package in a "browser" app. Create React App is similarly opinionated, and doesn't provide any polyfill or fallback. I think modular should follow this opinion, unless we get overwhelming feedback indicating the contrary.
The problem is that some third party packages that provide both browser and node implementation don't distribute it into different files (there's a mechanism to do that, but it's not widely used yet), but they expose a single file that initially
require()
s everything (built-in modules included) and decides what to use at runtime, based - I guess - on capability sniffing (require(builtin); if (isNode) { useBuiltin() } else { useBrowseEquivalent() }
). These modules, that would normally work without polyfills, now break the build. This happens, for example, withsolclientjs
anddotenv
.This PR adds
fallback: false
for all the node builtins required in the build, so that they get a non-meaningful value at runtime. If they're never used, that won't make a difference, but they won't break the build. This is breaking in respect to what modular v2 does (-> modular v2 uses webpack 4 that automatically provides polyfills)This PR also externalises all node builtins in esbuild mode. This is analogous to what we do in Webpack mode, with the difference that if there is an npm module with the same name as a npm builtin in the extended dependencies, it will be excluded from the build (while webpack will use the homonym npm module instead). npm packages that are homonym to builtin packages are a legacy residue and are mainly deprecated, but if they're used by any third party library, they won't work in esbuild mode. I don't know a way to provide a fallback behaviour similar to webpack with esbuild. This is breaking in respect to what modular v2 in esbuild mode does (-> modular v2 always breaks when there is a builtin package in the build)