-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes issues with packaged asset resolution (#10621)
* Fixes issues with packaged asset resolution `Image.resolveAssetSource` has two different code paths - one for resolving assets from the packager server when running in standard debug builds and one for resolving assets when the JS package is pre-bundled. Previously, we were not providing the bundle root path to the `SourceCodeModule` for pre-bundled apps, and it was up to each individual native module and view manager that depends on resolving asset paths with `Image.resolveAssetSource` to replace `file://` with the bundle root path pulled from the InstanceSettingsSnapshot. Even after fixing the issue with `SourceCodeModule`, there is still one more issue for unpackaged apps, whose asset paths may be Windows file paths (e.g., `C:\...`) rather than packaged asset paths (e.g., `ms-appx://`). This change ensures that SourceCodeModule provides the bundle root path as the `scriptURL` constant and patches the bug in the upstream `resolveAssetSource` module to skip coersion of the bundle root path to a form like `file://`. Resolves #10620 * Change files
- Loading branch information
Showing
7 changed files
with
131 additions
and
7 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
change/react-native-windows-06a66b00-cc43-451b-9087-1b0c52b44ab4.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"type": "prerelease", | ||
"comment": "[PR] Fixes issues with packaged asset resolution (#10621)", | ||
"packageName": "react-native-windows", | ||
"email": "[email protected]", | ||
"dependentChangeType": "patch" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
vnext/src/Libraries/Image/resolveAssetSource.windows.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/** | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
* | ||
* @format | ||
* @flow | ||
*/ | ||
|
||
// Resolves an asset into a `source` for `Image`. | ||
|
||
'use strict'; | ||
|
||
import type {ResolvedAssetSource} from './AssetSourceResolver'; | ||
|
||
const AssetSourceResolver = require('./AssetSourceResolver'); | ||
const Platform = require('../Utilities/Platform'); | ||
const {pickScale} = require('./AssetUtils'); | ||
const AssetRegistry = require('@react-native/assets-registry/registry'); | ||
|
||
let _customSourceTransformer, _serverURL, _scriptURL; | ||
|
||
let _sourceCodeScriptURL: ?string; | ||
function getSourceCodeScriptURL(): ?string { | ||
if (_sourceCodeScriptURL) { | ||
return _sourceCodeScriptURL; | ||
} | ||
|
||
let sourceCode = | ||
global.nativeExtensions && global.nativeExtensions.SourceCode; | ||
if (!sourceCode) { | ||
sourceCode = require('../NativeModules/specs/NativeSourceCode').default; | ||
} | ||
_sourceCodeScriptURL = sourceCode.getConstants().scriptURL; | ||
return _sourceCodeScriptURL; | ||
} | ||
|
||
function getDevServerURL(): ?string { | ||
if (_serverURL === undefined) { | ||
const sourceCodeScriptURL = getSourceCodeScriptURL(); | ||
const match = | ||
sourceCodeScriptURL && sourceCodeScriptURL.match(/^https?:\/\/.*?\//); | ||
if (match) { | ||
// jsBundle was loaded from network | ||
_serverURL = match[0]; | ||
} else { | ||
// jsBundle was loaded from file | ||
_serverURL = null; | ||
} | ||
} | ||
return _serverURL; | ||
} | ||
|
||
function _coerceLocalScriptURL(scriptURL: ?string): ?string { | ||
if (Platform.OS === 'windows') { | ||
return scriptURL; | ||
} | ||
|
||
if (scriptURL) { | ||
if (scriptURL.startsWith('assets://')) { | ||
// android: running from within assets, no offline path to use | ||
return null; | ||
} | ||
scriptURL = scriptURL.substring(0, scriptURL.lastIndexOf('/') + 1); | ||
if (!scriptURL.includes('://')) { | ||
// Add file protocol in case we have an absolute file path and not a URL. | ||
// This shouldn't really be necessary. scriptURL should be a URL. | ||
scriptURL = 'file://' + scriptURL; | ||
} | ||
} | ||
return scriptURL; | ||
} | ||
|
||
function getScriptURL(): ?string { | ||
if (_scriptURL === undefined) { | ||
_scriptURL = _coerceLocalScriptURL(getSourceCodeScriptURL()); | ||
} | ||
return _scriptURL; | ||
} | ||
|
||
function setCustomSourceTransformer( | ||
transformer: (resolver: AssetSourceResolver) => ResolvedAssetSource, | ||
): void { | ||
_customSourceTransformer = transformer; | ||
} | ||
|
||
/** | ||
* `source` is either a number (opaque type returned by require('./foo.png')) | ||
* or an `ImageSource` like { uri: '<http location || file path>' } | ||
*/ | ||
function resolveAssetSource(source: any): ?ResolvedAssetSource { | ||
if (typeof source === 'object') { | ||
return source; | ||
} | ||
|
||
const asset = AssetRegistry.getAssetByID(source); | ||
if (!asset) { | ||
return null; | ||
} | ||
|
||
const resolver = new AssetSourceResolver( | ||
getDevServerURL(), | ||
getScriptURL(), | ||
asset, | ||
); | ||
if (_customSourceTransformer) { | ||
return _customSourceTransformer(resolver); | ||
} | ||
return resolver.defaultAsset(); | ||
} | ||
|
||
resolveAssetSource.pickScale = pickScale; | ||
resolveAssetSource.setCustomSourceTransformer = setCustomSourceTransformer; | ||
module.exports = resolveAssetSource; |