Skip to content

Overriding resolution through Babel poisons Metro's transformer cache #9

@byCedric

Description

@byCedric

Hi! After I created PR #8, I noticed something in packages/vega that I don't have a fix for but thought you should know.

TL;DR; @amazon-devices/kepler-module-resolver-preset should be a Metro resolution override, not a Babel plugin.

As you know, Metro is a bundler that heavily leverages caching to stay performant. The main thing Metro is caching is the transform results from Metro's own transform pipeline, which by default is Babel. While it's perfectly fine to mutate code during the transformation stage, there are also some heavy pitfalls that we (at Expo) came to learn the hard way.

Both babel-plugin-module-resolver and babel-plugin-transform-inline-environment-variables (and similar) actually mutate code during transformation. The first is just for resolution, to change the resolution mechanism based on overrides or redirects. The second one just swaps out environment variable references with it's value at the time of transformation. Unfortunately, both poison the Metro cache, as both transform actions get cached without Metro being aware of this without being able to invalidate these caches when things change.

I see that packages/vega uses @amazon-devices/kepler-module-resolver-preset in

'module:@amazon-devices/kepler-module-resolver-preset', // Enables usage of VegaModuleResolverPreset
, which AFAICS is exactly the same pitfall as babel-plugin-module-resolver. When users have a warm cache, but the package wants to change any resolutions, users have to force-reset the cache as the previous resolutions are cached in the transformer stage. This is also the primary reason why we added support for .env files and environment variables in Expo, to make Metro aware of these values and be able to cache correctly.

Ideally, you'd want to use Metro's own config.resolver.resolveRequest override to customize resolutions. Instead of these resolutions being cached in the transform stage, these types of resolutions are not cached (but are still fast, we really worked on them). Meaning that if you'd add, remove, or change resolutions in @amazon-devices/kepler-module-resolver-preset, even with a warm cache the right resolutions are hit and no force-clear is required.

I think this is the gist of the issue, happy to elaborate more if needed.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions