Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

preserve require.context call when unstable_disableModuleWrapping is enabled #1129

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

EvanBacon
Copy link
Contributor

Summary

One possible way to implement tree shaking would require calling collectDependencies with unstable_disableModuleWrapping for a first pass, and invoking it a second time with module wrapping. The issue with this is that the require.context mutation is mutated to a format that wouldn't work on subsequent runs.

This PR will prevent the additional mutation of require.context -> require.

Test plan

Tests continue working

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 2, 2023
@codecov-commenter
Copy link

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (6151e7e) 83.09% compared to head (3fd29e3) 83.09%.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1129   +/-   ##
=======================================
  Coverage   83.09%   83.09%           
=======================================
  Files         206      206           
  Lines       10547    10548    +1     
  Branches     2617     2618    +1     
=======================================
+ Hits         8764     8765    +1     
  Misses       1783     1783           
Files Coverage Δ
packages/metro-transform-worker/src/index.js 87.03% <ø> (ø)
...etro/src/ModuleGraph/worker/collectDependencies.js 98.46% <100.00%> (+<0.01%) ⬆️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Nov 2, 2023
EvanBacon added a commit to expo/expo that referenced this pull request Jul 3, 2024
…ns (#30140)

# Why

- The dependency collection system needs extra customizations for tree
shaking (tracking more import info, not mutating require context, etc.)
and for supporting SSR externals (required for RSC).
- Will pull in proposed changes such as
facebook/metro#1129 in the future.

<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

- Have ChatGPT rewrite the upstream collect dependencies module and
tests in TypeScript.
- No extra changes are applied on top of the module.

# Test Plan

- Pulled in the upstream tests to ensure compat with Metro.

---------

Co-authored-by: Expo Bot <[email protected]>
EvanBacon added a commit to expo/expo that referenced this pull request Jul 23, 2024
# Why

> Most of the original PR has been landed in
#30417

- Metro bundler does not have any form of graph-wide tree shaking
built-in. This can lead to bundle sizes that are larger than they need
to be, especially in the case of icon libraries.
- This PR (which is partially an RFC) aims to add a system for removing
unused imports and exports from a production bundle.

<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

- Leverage the new "optimize graph" mode to perform holistic
optimizations in the serializer. #30417
- Tree shaking can be enabled with the new env var
`EXPO_UNSTABLE_TREE_SHAKING=1`.
- This PR also adds a "barrel expansion" system which attempts to
replace `export * from '...'` statements with `export { View, Image, etc
} from '...'` statements to enable more graph reduction.
- Empty modules (containing only comments and directives) are removed
from the bundle.
- Side-effecty imports (imports with zero specifiers, `import "foo"` and
`import {} from "foo"`) are preserved unless marked otherwise by a
`package.json`'s `sideEffects` field.
- Custom imports such as `require.context` and `require.resolveWeak` are
left in place.
- Removed exports with source will trigger a recrawl to ensure any new
unused imports/exports are recursively removed.
- The feature is artificially forced to only run when
`EXPO_UNSTABLE_TREE_SHAKING=1` is set, and when bundling for production.
Tree shaking is disabled for SSR bundles. I may expand this to be
web-only too just due to a lack of continuous testing for native
runtimes.
- Added some external fixes
software-mansion/react-native-reanimated#6171
#30010
#29980
#29964
#29963
software-mansion/react-native-gesture-handler#2972

# Further work

Some ideas that I've had but aren't implemented in this PR:

- Use the worker farm to parallelize transformation in the serializer.
This could be tricky because we'd need to convert the AST to a serial
format then re-parse it back.
- ~~Fork collectDependencies to fully track the import/exports so we can
reuse the same import crawling code and references. This would also
speed up the bundling as we could parallelize and cache the pass.~~
#30140
- Use a totally custom syntax for matching import/exports, e.g.
`_$$_IMPORT_DEFAULT, _$$_IMPORT_ALL` (and some new export equivalents)
to reduce the number of transforms we run in the serializer. All
import/export's and the iife wrap could be run at transform-time and
we'd simply be mutating a valid JS bundle in the serializer. This would
be very challenging though and make it harder for users to contribute to
the implementation.
- ~~Upstream the hack on transformSyncRequire to support require.context
with one parameter. facebook/metro#1129
- Detect if a module is CJS according to Node.js heuristic, e.g. `.cjs`,
package exports, etc. then opt it out of tree shaking.
- [ ] update source maps

# Test Plan

- Added an e2e tree shaking test for web. 
- Added mini-metro tests to account for the known and expected tree
shaking behaviors.
- Added mini-metro tests for side-effect handling (need more here).
- Ensured all apps in expo/apps can be transformed and run with tree
shaking enabled.

---------

Co-authored-by: Expo Bot <[email protected]>
Co-authored-by: Aman Mittal <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants