Bugs when transformer.allowOptionalDependencies=true
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 5.6k
- Forks
- 696
- Avg merge
- 8m
- Merged PRs (30d)
- 7
Description
This issue tracks known bugs in the implementation of allowOptionalDependencies in https://github.com/facebook/metro/pull/511.
While allowOptionalDependencies is off by default in Metro, it is on by default for apps built using the React Native CLI: https://github.com/react-native-community/cli/pull/1350.
Bug 1: Unresolved optional dependencies are broken at runtime, along with subsequent requires/imports in the same file.
Repro: https://github.com/motiz88/metro-optional-deps-bug-1
const A = require('./a.js');
let B;
try {
B = require('./b.js');
} catch {}
const C = require('./c.js');
The above module compiles to
const A = metroRequire(dependencyMap[0]);
let B;
try {
B = metroRequire(dependencyMap[1]);
} catch {}
const C = metroRequire(dependencyMap[2]);
Where dependencyMap is assumed to have an entry for each required module. But if ./b.js is unresolved at build time, dependencyMap will only have entries for A and C. Therefore the following lines behave incorrectly:
B = metroRequire(dependencyMap[1]); // B evaluates to require('./c.js') !
const C = metroRequire(dependencyMap[2]); // C evaluates to metroRequire(undefined), which throws an error
Bug 2: If an optional dependency is unresolved and later becomes resolvable (e.g. the package is installed while Metro is running), Metro will not detect this unless the origin file is also modified (or Metro is restarted).
This is because we don't always invalidate dependency resolutions correctly. In this case, we do not track the relationship between the initially-missing dependency (and the paths it might appear in) and the origin file, so Metro has no reason to mark the origin file as modified when the dependency later appears. (This is a broader problem with our resolver architecture that affects more than just optional dependencies.)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the implementation introduced in PR 511 and reproduce Bug 1 with the linked metro-optional-deps-bug-1 project. Trace how unresolved optional dependencies are represented in the dependency map and how resolution invalidation tracks missing paths. Done means both the runtime dependency-map behavior and later resolution after installation work without requiring an origin-file change or Metro restart.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- build-system, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100