Skip to content

Commit 592fbe3

Browse files
authored
fix: obtain asset size from first asset in group (#814)
* test: refactor to use jest each in assetLoader tests * fix: get asset size for scaled assets like in metro * chore: add changeset
1 parent 31d29b5 commit 592fbe3

File tree

7 files changed

+20
-45
lines changed

7 files changed

+20
-45
lines changed

.changeset/rude-points-ring.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@callstack/repack": patch
3+
---
4+
5+
Fix how size of a scaled assets is obtained (aligned with metro)

packages/repack/src/loaders/assetsLoader/__tests__/assetsLoader.test.ts

+3-30
Original file line numberDiff line numberDiff line change
@@ -126,36 +126,9 @@ describe('assetLoader', () => {
126126
127127
);
128128

129-
describe('on ios', () => {
129+
describe.each(['ios', 'android'])('on %s', (platform) => {
130130
it('should load and extract asset without scales', async () => {
131-
const { code, volume } = await compileBundle('ios', {
132-
...fixtures,
133-
'./index.js': "export { default } from './__fixtures__/logo.png';",
134-
});
135-
const context: { Export?: { default: Record<string, any> } } = {};
136-
vm.runInNewContext(code, context);
137-
138-
expect(context.Export?.default).toMatchSnapshot();
139-
expect(volume.toTree()).toMatchSnapshot();
140-
});
141-
142-
it('should load and extract asset with scales', async () => {
143-
const { code, volume } = await compileBundle('ios', {
144-
...fixtures,
145-
'./index.js': "export { default } from './__fixtures__/star.png';",
146-
});
147-
148-
const context: { Export?: { default: Record<string, any> } } = {};
149-
vm.runInNewContext(code, context);
150-
151-
expect(context.Export?.default).toMatchSnapshot();
152-
expect(volume.toTree()).toMatchSnapshot();
153-
});
154-
});
155-
156-
describe('on android', () => {
157-
it('should load and extract asset without scales', async () => {
158-
const { code, volume } = await compileBundle('android', {
131+
const { code, volume } = await compileBundle(platform, {
159132
...fixtures,
160133
'./index.js': "export { default } from './__fixtures__/logo.png';",
161134
});
@@ -168,7 +141,7 @@ describe('assetLoader', () => {
168141
});
169142

170143
it('should load and extract asset with scales', async () => {
171-
const { code, volume } = await compileBundle('android', {
144+
const { code, volume } = await compileBundle(platform, {
172145
...fixtures,
173146
'./index.js': "export { default } from './__fixtures__/star.png';",
174147
});

packages/repack/src/loaders/assetsLoader/assetsLoader.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,13 @@ export default async function repackAssetsLoader(
113113
}
114114
: null;
115115

116+
// assets are sorted by scale, in ascending order
116117
const assets = await Promise.all<Asset>(
117118
scaleKeys.map(async (scaleKey) => {
118119
const assetPath = scales[scaleKey];
119-
const isDefault = assetPath === resourcePath;
120+
const isLoaded = assetPath === resourcePath;
120121
// use raw Buffer passed to loader to avoid unnecessary read
121-
const content = isDefault ? assetData : await readFileAsync(assetPath);
122+
const content = isLoaded ? assetData : await readFileAsync(assetPath);
122123

123124
let destination: string;
124125

@@ -197,7 +198,6 @@ export default async function repackAssetsLoader(
197198

198199
return {
199200
data: content,
200-
default: isDefault,
201201
dimensions,
202202
filename: destination,
203203
scale,

packages/repack/src/loaders/assetsLoader/convertToRemoteAssets.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'node:path';
22
import dedent from 'dedent';
33
import type { Asset } from './types';
4-
import { getDefaultAsset } from './utils';
4+
import { getAssetSize } from './utils';
55

66
export function convertToRemoteAssets({
77
assets,
@@ -29,7 +29,8 @@ export function convertToRemoteAssets({
2929
// works on both unix & windows
3030
const publicPathURL = new URL(path.join(remotePublicPath, assetPath));
3131

32-
const size = getDefaultAsset(assets).dimensions;
32+
const size = getAssetSize(assets);
33+
3334
const asset = JSON.stringify({
3435
name: resourceFilename,
3536
type: resourceExtensionType,

packages/repack/src/loaders/assetsLoader/extractAssets.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import crypto from 'node:crypto';
22
import path from 'node:path';
33
import dedent from 'dedent';
44
import type { Asset } from './types';
5-
import { getDefaultAsset } from './utils';
5+
import { getAssetSize } from './utils';
66

77
export function extractAssets(
88
{
@@ -39,7 +39,7 @@ export function extractAssets(
3939
publicPath = path.join(customPublicPath, publicPath);
4040
}
4141

42-
const size = getDefaultAsset(assets).dimensions;
42+
const size = getAssetSize(assets);
4343
const scales = assets.map((asset) => asset.scale);
4444
const hashes = assets.map((asset) =>
4545
crypto.createHash('md5').update(asset.data).digest('hex')

packages/repack/src/loaders/assetsLoader/types.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
export interface Asset {
22
data: Buffer;
3-
default: boolean;
43
dimensions: AssetDimensions | null;
54
filename: string;
65
scale: number;

packages/repack/src/loaders/assetsLoader/utils.ts

+4-7
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@ export function getScaleNumber(scaleKey: string) {
66
return Number.parseFloat(scaleKey.replace(/[^\d.]/g, ''));
77
}
88

9-
/** Default asset is the one with scale that was originally requested in the loader */
10-
export function getDefaultAsset(assets: Asset[]) {
11-
const defaultAsset = assets.find((asset) => asset.default === true);
12-
if (!defaultAsset) {
13-
throw new Error('Malformed assets array - no default asset found');
14-
}
15-
return defaultAsset;
9+
export function getAssetSize(assets: Asset[]) {
10+
// Use first asset for reference as size, just like in metro:
11+
// https://github.com/facebook/metro/blob/main/packages/metro/src/Assets.js#L223
12+
return assets[0].dimensions;
1613
}
1714

1815
export function getAssetDimensions({

0 commit comments

Comments
 (0)