metro
metro copied to clipboard
Named and default exports have different resolving strategies/behaviors
Problem
Hello! Lately I've been working on optimizing the startup time of our application. I learned a lot about how hermes works and how it incrementally resolves imports as we use the values. I followed this snippet to analyze how many modules were loaded at the Home page of our page and realized it was way too high (5300, which is crazy).
After many attempts at understanding why it would resolve flows and components that were not required in the Home page, I found that Hermes resolves default export by default. Plus the fact that it will initialize data and allocate to memory currently unwanted stuff and execute top level code.
Explanation:
// FileB.tsx
import {View} from "react-native";
console.log("This will log before first render");
export default function ComponentB() {
return <View />;
}
// FileA.tsx
import ComponentB from "./FileB";
export default function ComponentA() {
return <ComponentB />;
}
// App.tsx
import ComponentA from "./FileA";
// Insert here the snippet provided above
// The snippet will log that FileB is resolved and loaded
export default function App() {
return <ComponentA />;
}
Whereas
// FileB.tsx
import {View} from "react-native";
console.log("This will NOT log before first render");
export function ComponentB() {
return <View />;
}
// FileA.tsx
import {ComponentB} from "./FileB";
export function ComponentA() {
return <ComponentB />;
}
// App.tsx
import {ComponentA} from "./FileA";
// Insert here the snippet provided above
// The snippet will log that FileA is resolved and loaded but **not** FileB
export default function App() {
return <ComponentA />;
}
has a completely different behavior.
Is this behavior wanted or not? I feel like I should rewrite all the imports to named imports to work this around. But would be happy to know if there is any other way and if not why it's technically not possible.
Thanks for your answers.
:warning: | Missing Reproducible Example |
---|---|
:information_source: | We could not detect a reproducible example in your issue report. Please provide either:
|
:warning: | Missing Reproducible Example |
---|---|
:information_source: | We could not detect a reproducible example in your issue report. Please provide either:
|
Hi, when building a RN app, import
and export
are handled by the bundler (Metro), not by Hermes. The bundler combines all source files together into a single file, transforms the JS to implement import/export (among other things), and only then passes the result to Hermes.
I am moving this issue to React Native.
Passing over to Metro (cc @robhogan @huntie)
Facing the same issue. Because of this inline requires does not work, and entire project has to be parsed just to run app. After switching to named exports, problem solved itself. But logically there should be no difference