Conversation
Is this a breaking change, albeit a good one? Is there ever a scenario where including "json" in both sourceExts and assetExts behaves differently than if it were just in sourceExts? All imports/requires for JSON files presumably would have returned the bundled JSON, not the uploaded-as-an-asset JSON. I think we should document this as a breaking change regardless in case there are edge cases we haven't anticipated, but outside of contrived scenarios I imagine this works well for 99% of apps. |
From Christoph Nakazawa in the Metro discord:
I think changing how JSON is loaded is a pretty major change, I'm not sure how to proceed. |
My understanding of the situation is that it's undesirable for apps to include JSON twice: obviously we don't want each JSON file to be both bundled and included as a standalone asset at the same time. However, it sounds like there are also some edge cases that we might not anticipate. What if we made it so that by default, we excluded JSON from assetExts, but allowed developers to add it back explicitly the same way they'd add any other assetExt? This way the change in behavior would be a breaking change with a straightforward way to restore the old behavior by opting into it: high ceilings with good defaults. |
By that reasoning, can't the user already filter json from either assetExts or sourceExts themselves in their project metro config, depending on their needs and desired behavior, without this change to the defaults? Because if so, is changing the default to something that also is not the default for RN worth the risk of introducing a breaking change to an unknown subset of existing users? |
The principle we're striving for is high ceilings with good defaults and the current default isn't fundamentally good. From Evan's comment it sounds like there are some cases where accidental complexity relies on duplicate JSON files and while we want to allow that if an app wants to take on that cost, I imagine most apps don't need it. |
Following up here. A summary: In either case, developers can specify which Removing
Keeping
I tested this on 3 of my apps, however, I can't possibly test on a wide enough array of projects to know for certain that this will be safe. To me, the upsides outweigh the downsides/risk. The worst-case scenario seems like it's relatively easy to address. Would love to hear your thoughts on this + any other upsides/downsides. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to communicate these clearly in the next SDK's release notes but this looks good. I would expect it to reduce update sizes significantly.
Co-authored-by: James Ide <ide@users.noreply.github.com>
Why
When we create update bundles, metro includes all assets necessary to run the app in its output. Part of our metro
resolver
configuration includesassetExts
andsourceExts
.assetExts
are file extensions that metro will include as discreet assets alongside the JS bundles.sourceExts
are file extensions that metro will include inside the JS bundle, inline.I noticed that we have
json
in bothassetExts
andsourceExts
, which means we are inliningjson
files in the main JS bundle and then including them again as discreet assets. In other words, alljson
files in update bundles are duplicated.With EAS Update, developers often have node modules that include many
json
files (like translations etc), which we then count against our 400 asset limit. This can make it hard for larger apps to publish. Since those apps do not need the extrajson
assets because they are also inlined, this PR removesjson
fromassetExts
.Below I ran
expod export --experimental-bundle
on a project:Before
After
How
getDefaultConfig()
, I filtered outjson
from the defaultassetExts
, then added tests.Test Plan
This change affects development and production bundles. To see the result of this change, pull this branch, then run
yarn link
in expo-cli/packages/metro-config. Then, in an Expo project runyarn link @expo/metro-config
. Back in expo-cli, runyarn start
to build the packages.Back in the Expo project, you can run
expod export --experimental-bundle
(I haveexpod
as an alias:alias expod="~/<your-file-path>/expo-cli/packages/expo-cli/bin/expo.js"
).After running this, you should see that
json
files are not emitted as part of the bundle.Also:
expod start
and see changesexpod publish
andeas update
. Make sure there are no json files in the metadata.json file.json
inassetExts
, that it does includejson
files in the outputted bundle as assets.