Greg Westneat 260562e484
feat(expo): update expo sync-deps executor (#26086)
## Current Behavior

When running `@nx/expo:sync-deps` it includes many unexpected
dependencies.

If you add a backend project as an implicit dependency to the expo
project, then all of the backend project's dependencies are included in
the expo package.json when running `@nx/expo:sync-deps`

You can use the `exclude` option, but with hundreds of excluded
packages, this adds a lot of bloat to the targets in `project.json`

## Expected Behavior

Ideally, when using `sync-deps` as a part of the `build`, only packages
necessary in the context of the `build` would be synced.

Since the packages from `implicitDependencies` aren't typically relevant
to the expo build, we should optionally be able to not include them.

## Notes

### Default Value

I made the default `excludeImplicit: false` so that it doesn't diverge
from current behavior/expectations — but it's possible that it would
make more sense to have it be `true` by default — would defer to y'all
on that question.


## Additional Considerations

### Other Possible Options 


> [!NOTE]
> Let me know if you're interested in PRs to add any of these


<details>
  <summary>Other Possible Options</summary>

Here are some other options which might be worth considering.

- [x] `excludeImplicit` <- _added in this PR_
- [ ] `onlyNativeDependencies`*
- [ ] `onlyPodInstallDependencies`*
- [ ] `traceDependencyPaths`**
- [ ] `excludeDevDependencies`***
- [ ] `matchRootPackageJsonCatgeory`***
- [ ] `onlySrcFiles`****
- [ ] `filterByCacheInputs`****


#### Only Native / Pod Installs*
Based on the discussion in issue #18788 it seem like the primary reason
for `sync-deps`, is to support pod install.

#### Trace Dependency Paths**

When I was originally debugging "why is axios being added?" — before I'd
realized about the `implicitDependencies` — I wrote a utility to output
the trace for the included packages — that's how I realized what was
going on. Could be a useful feature addition.


![image](https://github.com/nrwl/nx/assets/2213636/e1cb1511-c518-47d8-85fb-69c6a6d88058)


#### Deps vs DevDeps***

By default, the `sync-deps` feature will find all dependencies
including(eg jest, storybook) and add them to `package.json` under the
`"dependencies":` key.

It might be useful to either match the root `package.json`'s
categorization or just exclude devDependencies altogether.

#### File aware filtering****

Currently the `findAllNpmDependencies` is filtering some hardcoded
external nodes:
```
  'npm:@nx/react-native',
  'npm:@nrwl/react-native',
  'npm:@nx/expo',
  'npm:@nrwl/expo',
```
These are in the dependency graph because they are used as executors in
`project.json` targets.

It might be useful to derive these exclusions dynamically, by only
considering relevant productions files.

A simple approach would be to only consider dependencies that stem from
files in the `src` directory

A more robust alternative would be to read the cache inputs from the
calling target, and filter dependencies based on matching files

</details>

### Fingerprinting?

<details>
  <summary>Fingerprinting</summary>

There's a related matter having to do with `@expo/fingerprint` where
having the native dependencies visible from the project-level
`package.json` is important to getting accurate project-level
fingerprints.

The more ideal solution would be to use the Nx graph to handle the
"fingerprinting" hash generation, but it would require some thought /
feature design.

So in the meantime the `sync-deps` (only need native deps) +
`@expo/fingerprint` recourse seems like the best option.

</details>

Thanks!
2024-06-05 01:04:10 -04:00
..