Skip to content

Commit e570fcf

Browse files
tido64huntie
authored andcommitted
Build assets-registry for general consumption
1 parent d97bc05 commit e570fcf

12 files changed

Lines changed: 228 additions & 112 deletions

File tree

packages/assets/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Dependencies
2+
/node_modules
3+
4+
# Build output
5+
/dist

packages/assets/package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@
1616
"support"
1717
],
1818
"bugs": "https://github.com/facebook/react-native/issues",
19+
"exports": {
20+
"./path-support": "./src/path-support.js",
21+
"./path-support.js": "./src/path-support.js",
22+
"./registry": "./src/registry.js",
23+
"./registry.js": "./src/registry.js",
24+
"./package.json": "./package.json"
25+
},
26+
"files": [
27+
"dist",
28+
"path-support.js",
29+
"registry.js"
30+
],
1931
"engines": {
2032
"node": ">=18"
2133
}

packages/assets/path-support.js

Lines changed: 19 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -4,89 +4,26 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @format
87
* @flow strict
8+
* @format
9+
* @oncall react_native
910
*/
1011

11-
'use strict';
12-
13-
import type {PackagerAsset} from './registry.js';
14-
15-
const androidScaleSuffix = {
16-
'0.75': 'ldpi',
17-
'1': 'mdpi',
18-
'1.5': 'hdpi',
19-
'2': 'xhdpi',
20-
'3': 'xxhdpi',
21-
'4': 'xxxhdpi',
22-
};
23-
24-
const ANDROID_BASE_DENSITY = 160;
25-
26-
/**
27-
* FIXME: using number to represent discrete scale numbers is fragile in essence because of
28-
* floating point numbers imprecision.
29-
*/
30-
function getAndroidAssetSuffix(scale: number): string {
31-
if (scale.toString() in androidScaleSuffix) {
32-
return androidScaleSuffix[scale.toString()];
33-
}
34-
// NOTE: Android Gradle Plugin does not fully support the nnndpi format.
35-
// See https://issuetracker.google.com/issues/72884435
36-
if (Number.isFinite(scale) && scale > 0) {
37-
return Math.round(scale * ANDROID_BASE_DENSITY) + 'dpi';
38-
}
39-
throw new Error('no such scale ' + scale.toString());
40-
}
41-
42-
// See https://developer.android.com/guide/topics/resources/drawable-resource.html
43-
const drawableFileTypes = new Set([
44-
'gif',
45-
'jpeg',
46-
'jpg',
47-
'ktx',
48-
'png',
49-
'svg',
50-
'webp',
51-
'xml',
52-
]);
53-
54-
function getAndroidResourceFolderName(
55-
asset: PackagerAsset,
56-
scale: number,
57-
): string | $TEMPORARY$string<'raw'> {
58-
if (!drawableFileTypes.has(asset.type)) {
59-
return 'raw';
60-
}
61-
const suffix = getAndroidAssetSuffix(scale);
62-
if (!suffix) {
63-
throw new Error(
64-
"Don't know which android drawable suffix to use for scale: " +
65-
scale +
66-
'\nAsset: ' +
67-
JSON.stringify(asset, null, '\t') +
68-
'\nPossible scales are:' +
69-
JSON.stringify(androidScaleSuffix, null, '\t'),
70-
);
71-
}
72-
return 'drawable-' + suffix;
73-
}
74-
75-
function getAndroidResourceIdentifier(asset: PackagerAsset): string {
76-
return (getBasePath(asset) + '/' + asset.name)
77-
.toLowerCase()
78-
.replace(/\//g, '_') // Encode folder structure in file name
79-
.replace(/([^a-z0-9_])/g, '') // Remove illegal chars
80-
.replace(/^assets_/, ''); // Remove "assets_" prefix
81-
}
82-
83-
function getBasePath(asset: PackagerAsset): string {
84-
const basePath = asset.httpServerLocation;
85-
return basePath.startsWith('/') ? basePath.slice(1) : basePath;
12+
// Compatibility module for tools which don't support the "exports" field:
13+
// - Flow (type exports)
14+
// - Metro (runtime exports)
15+
16+
/*::
17+
export * from './src/path-support.flow';
18+
*/
19+
20+
try {
21+
// $FlowIgnore[cannot-resolve-module]
22+
// $FlowIgnore[invalid-export]
23+
// $FlowIgnore[module-type-conflict]
24+
module.exports = require('./dist/path-support.flow');
25+
} catch (e) {
26+
// $FlowIgnore[invalid-export]
27+
// $FlowIgnore[module-type-conflict]
28+
module.exports = require('./src/path-support');
8629
}
87-
88-
module.exports = {
89-
getAndroidResourceFolderName,
90-
getAndroidResourceIdentifier,
91-
getBasePath,
92-
};

packages/assets/registry.js

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,24 @@
66
*
77
* @flow strict
88
* @format
9+
* @oncall react_native
910
*/
1011

11-
'use strict';
12+
// Compatibility module for tools which don't support the "exports" field:
13+
// - Flow (type exports)
14+
// - Metro (runtime exports)
1215

13-
export type PackagerAsset = {
14-
+__packager_asset: boolean,
15-
+fileSystemLocation: string,
16-
+httpServerLocation: string,
17-
+width: ?number,
18-
+height: ?number,
19-
+scales: Array<number>,
20-
+hash: string,
21-
+name: string,
22-
+type: string,
23-
...
24-
};
16+
/*::
17+
export * from './src/registry.flow';
18+
*/
2519

26-
const assets: Array<PackagerAsset> = [];
27-
28-
function registerAsset(asset: PackagerAsset): number {
29-
// `push` returns new array length, so the first asset will
30-
// get id 1 (not 0) to make the value truthy
31-
return assets.push(asset);
32-
}
33-
34-
function getAssetByID(assetId: number): PackagerAsset {
35-
return assets[assetId - 1];
20+
try {
21+
// $FlowIgnore[cannot-resolve-module]
22+
// $FlowIgnore[invalid-export]
23+
// $FlowIgnore[module-type-conflict]
24+
module.exports = require('./dist/registry.flow');
25+
} catch (e) {
26+
// $FlowIgnore[invalid-export]
27+
// $FlowIgnore[module-type-conflict]
28+
module.exports = require('./src/registry');
3629
}
37-
38-
module.exports = {registerAsset, getAssetByID};
File renamed without changes.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
import type {PackagerAsset} from './registry.flow';
13+
14+
const androidScaleSuffix = {
15+
'0.75': 'ldpi',
16+
'1': 'mdpi',
17+
'1.5': 'hdpi',
18+
'2': 'xhdpi',
19+
'3': 'xxhdpi',
20+
'4': 'xxxhdpi',
21+
};
22+
23+
const ANDROID_BASE_DENSITY = 160;
24+
25+
/**
26+
* FIXME: using number to represent discrete scale numbers is fragile in essence because of
27+
* floating point numbers imprecision.
28+
*/
29+
function getAndroidAssetSuffix(scale: number): string {
30+
if (scale.toString() in androidScaleSuffix) {
31+
return androidScaleSuffix[scale.toString()];
32+
}
33+
// NOTE: Android Gradle Plugin does not fully support the nnndpi format.
34+
// See https://issuetracker.google.com/issues/72884435
35+
if (Number.isFinite(scale) && scale > 0) {
36+
return Math.round(scale * ANDROID_BASE_DENSITY) + 'dpi';
37+
}
38+
throw new Error('no such scale ' + scale.toString());
39+
}
40+
41+
// See https://developer.android.com/guide/topics/resources/drawable-resource.html
42+
const drawableFileTypes = new Set([
43+
'gif',
44+
'jpeg',
45+
'jpg',
46+
'ktx',
47+
'png',
48+
'svg',
49+
'webp',
50+
'xml',
51+
]);
52+
53+
export function getAndroidResourceFolderName(
54+
asset: PackagerAsset,
55+
scale: number,
56+
): string | $TEMPORARY$string<'raw'> {
57+
if (!drawableFileTypes.has(asset.type)) {
58+
return 'raw';
59+
}
60+
const suffix = getAndroidAssetSuffix(scale);
61+
if (!suffix) {
62+
throw new Error(
63+
"Don't know which android drawable suffix to use for scale: " +
64+
scale +
65+
'\nAsset: ' +
66+
JSON.stringify(asset, null, '\t') +
67+
'\nPossible scales are:' +
68+
JSON.stringify(androidScaleSuffix, null, '\t'),
69+
);
70+
}
71+
return 'drawable-' + suffix;
72+
}
73+
74+
export function getAndroidResourceIdentifier(asset: PackagerAsset): string {
75+
return (getBasePath(asset) + '/' + asset.name)
76+
.toLowerCase()
77+
.replace(/\//g, '_') // Encode folder structure in file name
78+
.replace(/([^a-z0-9_])/g, '') // Remove illegal chars
79+
.replace(/^assets_/, ''); // Remove "assets_" prefix
80+
}
81+
82+
export function getBasePath(asset: PackagerAsset): string {
83+
const basePath = asset.httpServerLocation;
84+
return basePath.startsWith('/') ? basePath.slice(1) : basePath;
85+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
/*::
13+
export type * from './path-support.flow';
14+
*/
15+
16+
if (process.env.BUILD_EXCLUDE_BABEL_REGISTER !== true) {
17+
// $FlowIgnore[nonstrict-import]
18+
require('../../../scripts/build/babel-register').registerForMonorepo();
19+
}
20+
21+
export * from './path-support.flow';
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
export type PackagerAsset = {
13+
+__packager_asset: boolean,
14+
+fileSystemLocation: string,
15+
+httpServerLocation: string,
16+
+width: ?number,
17+
+height: ?number,
18+
+scales: Array<number>,
19+
+hash: string,
20+
+name: string,
21+
+type: string,
22+
...
23+
};
24+
25+
const assets: Array<PackagerAsset> = [];
26+
27+
export function registerAsset(asset: PackagerAsset): number {
28+
// `push` returns new array length, so the first asset will
29+
// get id 1 (not 0) to make the value truthy
30+
return assets.push(asset);
31+
}
32+
33+
export function getAssetByID(assetId: number): PackagerAsset {
34+
return assets[assetId - 1];
35+
}

packages/assets/src/registry.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
/*::
13+
export type * from './registry.flow';
14+
*/
15+
16+
if (process.env.BUILD_EXCLUDE_BABEL_REGISTER !== true) {
17+
// $FlowIgnore[nonstrict-import]
18+
require('../../../scripts/build/babel-register').registerForMonorepo();
19+
}
20+
21+
export * from './registry.flow';

packages/rn-tester/.babelrc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
{
2-
"presets": [
3-
"module:@react-native/babel-preset"
4-
],
5-
"plugins": [
6-
"babel-plugin-transform-flow-enums"
2+
"presets": ["module:@react-native/babel-preset"],
3+
"plugins": [
4+
"babel-plugin-transform-flow-enums",
5+
[
6+
"babel-plugin-transform-define",
7+
{
8+
"process.env.BUILD_EXCLUDE_BABEL_REGISTER": true
9+
}
710
]
11+
]
812
}

0 commit comments

Comments
 (0)