mirror of
https://github.com/react/react-native.git
synced 2026-09-28 21:33:11 +08:00
Summary: `saveAssets` filters an asset's scales through `filterPlatformAssetScales`, but `getImageSet` indexes the unfiltered `asset.files`, so an asset with scales `[1, 1.5, 2, 3]` gets the 1.5x file in its 2x catalog slot and the 2x file in its 3x slot: `Assets.car` ships the wrong images. An asset with no standard scale at all (only `1.5x`, say) produces an imageset actool silently drops from the car, which makes the image unloadable when `RCTUseAssetCatalog` is on, since the catalog runtime has no filesystem fallback (https://github.com/react/react-native/issues/30129). Fix, in `assetCatalogIOS.js`: - Each catalog slot (1x/2x/3x) is paired with its own file. - An asset with no valid scale maps its closest variant into the nearest valid slot, the same "closest larger" rule loose files already get, and warns in the build log. Every imageset now holds at least one rendition actool will compile. Related: expo/expo#48525 applies the same fix to Expo CLI's mirrored implementation. ## Changelog: [IOS] [FIXED] - Asset catalog imagesets paired wrong files for assets with non-standard scales Pull Request resolved: https://github.com/react/react-native/pull/57825 Test Plan: New unit tests in `assetCatalogIOS-test.js`: standard 1x/2x/3x pairing, mixed `[1, 1.5, 2, 3]` (regression for the file shift), fractional-only `[1.5]`, and `[4]` clamping to the 3x slot. ``` yarn jest packages/community-cli-plugin/src/commands/bundle Tests: 18 passed, 18 total ``` ### End-to-end Bundled a test app through the real pipeline (Metro → `saveAssets` → actool → `assetutil --info` on the compiled `Assets.car`) with two assets: `logo` at scales `[1, 1.5, 2, 3]` (100/150/200/300 px) and `star` with only a `1.5x` file (150 px). | Rendition in `Assets.car` | before | after | |---|---|---| | `img_logo` 1x | 100 px | 100 px | | `img_logo` 2x | **150 px (the 1.5x file)** | 200 px | | `img_logo` 3x | **200 px (the 2x file)** | 300 px | | `img_star` | **absent (actool dropped the `1.5x` imageset)** | 150 px in the 2x slot, with a build-log warning | Running on an iPhone 17 Pro simulator (3x), same app built with the buggy and fixed CLI — the labeled tiles show which file the catalog actually served, and `star` goes from missing to rendering: | Before | After | |---|---| | <img src="https://github.com/user-attachments/assets/4ebdbd33-74ec-4731-a2c4-f1a2d9b5838b" width="320" /> | <img src="https://github.com/user-attachments/assets/cd461b0a-5763-4388-8771-1ae6df383817" width="320" /> | <details> <summary>Repro app used for the screenshots</summary> Built `private/helloworld` (Release, simulator) with `RCTUseAssetCatalog` set to `true` in its Info.plist, and these assets in `img/`, where each file is a solid tile with its scale label and pixel size baked into the image so a screenshot shows exactly which file got served: `logo.png` (100px, "1x"), `logo@1.5x.png` (150px, "1.5x"), `logo@2x.png` (200px, "2x"), `logo@3x.png` (300px, "3x"), and `star@1.5x.png` (150px, "STAR") with no other variants. ```js // index.js import React from 'react'; import {AppRegistry, Image, Text, View, StyleSheet} from 'react-native'; const styles = StyleSheet.create({ root: {flex: 1, backgroundColor: 'https://github.com/react/react-native/issues/111', alignItems: 'center', justifyContent: 'center'}, label: {color: '#fff', fontSize: 16, marginTop: 24, marginBottom: 8, fontWeight: '600'}, box: {width: 100, height: 100, borderWidth: 2, borderColor: 'https://github.com/react/react-native/issues/666'}, img: {width: 100, height: 100}, }); const App = () => ( <View style={styles.root}> <Text style={styles.label}>logo.png (has 1x/1.5x/2x/3x)</Text> <View style={styles.box}> <Image style={styles.img} source={require('./img/logo.png')} /> </View> <Text style={styles.label}>star.png (only 1.5x)</Text> <View style={styles.box}> <Image style={styles.img} source={require('./img/star.png')} /> </View> </View> ); AppRegistry.registerComponent('HelloWorld', () => App); ``` On the 3x simulator JS resolves `logo` to the 3x variant, so the tile that renders is the file the catalog's 3x slot actually contains: the 2x-labeled tile before the fix, the 3x tile after. `star` resolves to its only variant (`1.5x`); before the fix its imageset is dropped by actool and the box renders empty. </details> Reviewed By: christophpurrer Differential Revision: D116956049 Pulled By: javache fbshipit-source-id: 4405c235098ea7f8a4ebc03ca6876a3981894e71
@react-native/community-cli-plugin
This is an internal dependency of React Native. Please don't depend on it directly.
CLI entry points supporting core React Native development features.
Formerly @react-native-community/cli-plugin-metro.
Commands
start
Start the React Native development server.
Usage
npx @react-native-community/cli start [options]
Options
| Option | Description |
|---|---|
--port <number> |
Set the server port. |
--host <string> |
Set the server host. |
--projectRoot <path> |
Set the path to the project root. |
--watchFolders <list> |
Specify additional folders to be added to the watch list. |
--assetPlugins <list> |
Specify additional asset plugins. |
--sourceExts <list> |
Specify additional source extensions to bundle. |
--max-workers <number> |
Set the maximum number of workers the worker-pool will spawn for transforming files. Defaults to the number of the cores available on your machine. |
--transformer <string> |
Specify a custom transformer. |
--reset-cache |
Remove cached files. |
--custom-log-reporter-path <string> |
Specify a module path exporting a replacement for TerminalReporter. |
--https |
Enable HTTPS connections. |
--key <path> |
Specify path to a custom SSL key. |
--cert <path> |
Specify path to a custom SSL cert. |
--config <string> |
Path to the CLI configuration file. |
--no-interactive |
Disable interactive mode. |
--client-logs |
[Deprecated] Enable plain text JavaScript log streaming for all connected apps. |
bundle
Build the bundle for the provided JavaScript entry file.
Usage
npx @react-native-community/cli bundle --entry-file <path> [options]
Options
| Option | Description |
|---|---|
--entry-file <path> |
Set the path to the root JavaScript entry file. |
--platform <string> |
Set the target platform (either "android" or "ios"). Defaults to "ios". |
--transformer <string> |
Specify a custom transformer. |
--dev [boolean] |
If false, warnings are disabled and the bundle is minified. Defaults to true. |
--minify [boolean] |
Allows overriding whether bundle is minified. Defaults to false if --dev is set. Disabling minification can be useful for speeding up production builds for testing purposes. |
--bundle-output <string> |
Specify the path to store the resulting bundle. |
--bundle-encoding <string> |
Specify the encoding for writing the bundle (https://nodejs.org/api/buffer.html#buffer_buffer). |
--resolver-option <string...> |
Custom resolver options of the form key=value. URL-encoded. May be specified multiple times. |
--sourcemap-output <string> |
Specify the path to store the source map file for the resulting bundle. |
--sourcemap-sources-root <string> |
Set the root path for source map entries. |
--sourcemap-use-absolute-path |
Report SourceMapURL using its full path. |
--max-workers <number> |
Set the maximum number of workers the worker-pool will spawn for transforming files. Defaults to the number of the cores available on your machine. |
--assets-dest <string> |
Specify the directory path for storing assets referenced in the bundle. |
--reset-cache |
Remove cached files. |
--read-global-cache |
Attempt to fetch transformed JS code from the global cache, if configured. Defaults to false. |
--config <string> |
Path to the CLI configuration file. |
codegen
Run the React Native codegen, generating native boilerplate from JS spec files.
Usage
npx @react-native-community/cli codegen [options]
Options
| Option | Description |
|---|---|
--path <path> |
Path to the React Native project root. Defaults to the current working directory. |
--platform <string> |
Target platform. Supported values: "android", "ios", "all". Defaults to "all". |
--outputPath <path> |
Path where generated artifacts will be output to. |
--source <string> |
Whether the script is invoked from an app or a library. Defaults to "app". |
spm [action]
Set up or maintain Swift Package Manager support for the iOS/macOS app. Actions: add, update, deinit, scaffold. With no action: add (or update if SPM is already set up).
Usage
npx @react-native-community/cli spm [action] [options]
Options
| Option | Description |
|---|---|
--version <string> |
React Native version (e.g. 0.80.0). Defaults to the version in node_modules/react-native/package.json. |
--yes |
Skip the dirty-pbxproj confirmation prompt. |
--xcodeproj <path> |
[add] Path to the .xcodeproj to inject SPM packages into (disambiguates when several exist). |
--productName <string> |
[add] App target to inject into (disambiguates when several exist). |
--deintegrate |
[add] Run pod deintegrate and strip React Native from the Podfile before injecting (CocoaPods → SwiftPM migration). |
--artifacts <path> |
[advanced] Local artifact root containing complete debug/ and release/ slots. |
--download <string> |
[advanced] Artifact download policy: auto (default), skip, or force. |
--skipCodegen |
[advanced] Skip the react-native codegen step. |
Contributing
Changes to this package can be made locally and tested against the rn-tester app, per the Contributing guide. During development, this package is automatically run from source with no build step.