Metro: Package deduplication

Created on 31 Jan 2019  路  4Comments  路  Source: facebook/metro

Is this a feature request? Yes

I often work on multiple packages at the same time. When two of these "locally developed" packages have the same exact dependency, I expect Metro to "deduplicate" the dependency instead of throwing.

Currently, the only workaround is to install everything into a flattened node_modules in the project root. This isn't practical, because I use symlinks during development (which is why I implemented #257).

Most helpful comment

When I disable throwOnModuleCollision here, the error moves to the following line in Metro:

https://github.com/facebook/metro/blob/8cd36549042ed3d70e65130d5d496fdd3afa15a0/packages/metro/src/node-haste/DependencyGraph/ResolutionRequest.js#L91-L93

This comment explains why using jest-haste-map to detect package "collisions" is a problem.

I propose the following behavior for package deduplication:
 

  1. When duplicate haste candidates are encountered...

    • Metro should mimic the Node.js resolution algorithm in order to determine which "duplicate" package path corresponds to the depending module.
       
  2. When one of the "duplicate" package paths is matched...

    • Metro should check which (if any) of the other "duplicate" package paths have already been resolved. For those package paths, check if one has an SHA1 hash that is identical to the matched path. Otherwise, use the matched path.
       

The developer is responsible for ensuring only one version of a package exists in the bundle. Metro should have no opinion on the matter.

Note: I wouldn't be against an option that tells Metro to emit warnings when multiple versions of the same package exist, but it should definitely be opt-in.
 

All 4 comments

When I disable throwOnModuleCollision here, the error moves to the following line in Metro:

https://github.com/facebook/metro/blob/8cd36549042ed3d70e65130d5d496fdd3afa15a0/packages/metro/src/node-haste/DependencyGraph/ResolutionRequest.js#L91-L93

This comment explains why using jest-haste-map to detect package "collisions" is a problem.

I propose the following behavior for package deduplication:
 

  1. When duplicate haste candidates are encountered...

    • Metro should mimic the Node.js resolution algorithm in order to determine which "duplicate" package path corresponds to the depending module.
       
  2. When one of the "duplicate" package paths is matched...

    • Metro should check which (if any) of the other "duplicate" package paths have already been resolved. For those package paths, check if one has an SHA1 hash that is identical to the matched path. Otherwise, use the matched path.
       

The developer is responsible for ensuring only one version of a package exists in the bundle. Metro should have no opinion on the matter.

Note: I wouldn't be against an option that tells Metro to emit warnings when multiple versions of the same package exist, but it should definitely be opt-in.
 

Alternatively, we could add an option to jest-haste-map which skips reading of package.json files when building the haste map. This is probably the easiest, so I'm gonna take a whack at this one first. I'm not sure if this will fix the problem entirely, but it will definitely affect performance negatively.

@aleclarson Any updates on this PR?

@prerakd The PR at #353 works great in my local fork. Waiting on response from Facebook...

Was this page helpful?
0 / 5 - 0 ratings