Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 25.2k
Build assets-registry for general consumption#39440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
145131ecc3f507c16d521c05181816a72c5387c27c9ba56ebc2a1793File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Dependencies | ||
| /node_modules | ||
| # Build output | ||
| /dist |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -4,89 +4,10 @@ | ||||||||||
| * This source code is licensed under the MIT license found in the | ||||||||||
| * LICENSE file in the root directory of this source tree. | ||||||||||
| * | ||||||||||
| * @format | ||||||||||
| * @flow strict | ||||||||||
| * @format strict | ||||||||||
| * @flow | ||||||||||
Comment on lines
+7
to
+8
Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like this line was accidentally rearranged first! Also, feel free to use
Suggested change
| ||||||||||
| */ | ||||||||||
| 'use strict'; | ||||||||||
| import type {PackagerAsset} from './registry.js'; | ||||||||||
| const androidScaleSuffix = { | ||||||||||
| '0.75': 'ldpi', | ||||||||||
| '1': 'mdpi', | ||||||||||
| '1.5': 'hdpi', | ||||||||||
| '2': 'xhdpi', | ||||||||||
| '3': 'xxhdpi', | ||||||||||
| '4': 'xxxhdpi', | ||||||||||
| }; | ||||||||||
| const ANDROID_BASE_DENSITY = 160; | ||||||||||
| /** | ||||||||||
| * FIXME: using number to represent discrete scale numbers is fragile in essence because of | ||||||||||
| * floating point numbers imprecision. | ||||||||||
| */ | ||||||||||
| function getAndroidAssetSuffix(scale: number): string { | ||||||||||
| if (scale.toString() in androidScaleSuffix) { | ||||||||||
| return androidScaleSuffix[scale.toString()]; | ||||||||||
| } | ||||||||||
| // NOTE: Android Gradle Plugin does not fully support the nnndpi format. | ||||||||||
| // See https://issuetracker.google.com/issues/72884435 | ||||||||||
| if (Number.isFinite(scale) && scale > 0) { | ||||||||||
| return Math.round(scale * ANDROID_BASE_DENSITY) + 'dpi'; | ||||||||||
| } | ||||||||||
| throw new Error('no such scale ' + scale.toString()); | ||||||||||
| } | ||||||||||
| // See https://developer.android.com/guide/topics/resources/drawable-resource.html | ||||||||||
| const drawableFileTypes = new Set([ | ||||||||||
| 'gif', | ||||||||||
| 'jpeg', | ||||||||||
| 'jpg', | ||||||||||
| 'ktx', | ||||||||||
| 'png', | ||||||||||
| 'svg', | ||||||||||
| 'webp', | ||||||||||
| 'xml', | ||||||||||
| ]); | ||||||||||
| function getAndroidResourceFolderName( | ||||||||||
| asset: PackagerAsset, | ||||||||||
| scale: number, | ||||||||||
| ): string | $TEMPORARY$string<'raw'> { | ||||||||||
| if (!drawableFileTypes.has(asset.type)) { | ||||||||||
| return 'raw'; | ||||||||||
| } | ||||||||||
| const suffix = getAndroidAssetSuffix(scale); | ||||||||||
| if (!suffix) { | ||||||||||
| throw new Error( | ||||||||||
| "Don't know which android drawable suffix to use for scale: " + | ||||||||||
| scale + | ||||||||||
| '\nAsset: ' + | ||||||||||
| JSON.stringify(asset, null, '\t') + | ||||||||||
| '\nPossible scales are:' + | ||||||||||
| JSON.stringify(androidScaleSuffix, null, '\t'), | ||||||||||
| ); | ||||||||||
| } | ||||||||||
| return 'drawable-' + suffix; | ||||||||||
| } | ||||||||||
| function getAndroidResourceIdentifier(asset: PackagerAsset): string { | ||||||||||
| return (getBasePath(asset) + '/' + asset.name) | ||||||||||
| .toLowerCase() | ||||||||||
| .replace(/\//g, '_') // Encode folder structure in file name | ||||||||||
| .replace(/([^a-z0-9_])/g, '') // Remove illegal chars | ||||||||||
| .replace(/^assets_/, ''); // Remove "assets_" prefix | ||||||||||
| } | ||||||||||
| function getBasePath(asset: PackagerAsset): string { | ||||||||||
| const basePath = asset.httpServerLocation; | ||||||||||
| return basePath.startsWith('/') ? basePath.slice(1) : basePath; | ||||||||||
| } | ||||||||||
| module.exports = { | ||||||||||
| getAndroidResourceFolderName, | ||||||||||
| getAndroidResourceIdentifier, | ||||||||||
| getBasePath, | ||||||||||
| }; | ||||||||||
| module.exports = require('./src/path-support'); | ||||||||||
huntie marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To enable running from source, let's add You can find an example of this pattern in And the file structure you'll need: assets
├── path-support.js.flow # (Flow only) Re-export all types and values
├── registry.js.flow
└── src
├── path-support.js # Entry point - babel-register
├── path-support.flow.js # Implementation
├── registry.js
└── registry.flow.jsCollaboratorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I didn't quite understand what those files were. Makes sense now!
| ||||||||||
| module.exports=require('./src/path-support'); | |
| export*from'./src/path-support'; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -10,29 +10,4 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'use strict'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export type PackagerAsset = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +__packager_asset: boolean, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +fileSystemLocation: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +httpServerLocation: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +width: ?number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +height: ?number, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +scales: Array<number>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +hash: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +name: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| +type: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ... | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const assets: Array<PackagerAsset> = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function registerAsset(asset: PackagerAsset): number { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // `push` returns new array length, so the first asset will | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // get id 1 (not 0) to make the value truthy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return assets.push(asset); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function getAssetByID(assetId: number): PackagerAsset { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return assets[assetId - 1]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| module.exports = {registerAsset, getAssetByID}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| module.exports = require('./src/registry.flow'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
11
to
+13
Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| /** | ||
| * 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 strict | ||
| */ | ||
| import type {PackagerAsset} from './registry.flow.js'; | ||
| const androidScaleSuffix = { | ||
| '0.75': 'ldpi', | ||
| '1': 'mdpi', | ||
| '1.5': 'hdpi', | ||
| '2': 'xhdpi', | ||
| '3': 'xxhdpi', | ||
| '4': 'xxxhdpi', | ||
| }; | ||
| const ANDROID_BASE_DENSITY = 160; | ||
| /** | ||
| * FIXME: using number to represent discrete scale numbers is fragile in essence because of | ||
| * floating point numbers imprecision. | ||
| */ | ||
| function getAndroidAssetSuffix(scale: number): string { | ||
| if (scale.toString() in androidScaleSuffix) { | ||
| return androidScaleSuffix[scale.toString()]; | ||
| } | ||
| // NOTE: Android Gradle Plugin does not fully support the nnndpi format. | ||
| // See https://issuetracker.google.com/issues/72884435 | ||
| if (Number.isFinite(scale) && scale > 0) { | ||
| return Math.round(scale * ANDROID_BASE_DENSITY) + 'dpi'; | ||
| } | ||
| throw new Error('no such scale ' + scale.toString()); | ||
| } | ||
| // See https://developer.android.com/guide/topics/resources/drawable-resource.html | ||
| const drawableFileTypes = new Set([ | ||
| 'gif', | ||
| 'jpeg', | ||
| 'jpg', | ||
| 'ktx', | ||
| 'png', | ||
| 'svg', | ||
| 'webp', | ||
| 'xml', | ||
| ]); | ||
| export function getAndroidResourceFolderName( | ||
| asset: PackagerAsset, | ||
| scale: number, | ||
| ): string | $TEMPORARY$string<'raw'> { | ||
| if (!drawableFileTypes.has(asset.type)) { | ||
| return 'raw'; | ||
| } | ||
| const suffix = getAndroidAssetSuffix(scale); | ||
| if (!suffix) { | ||
| throw new Error( | ||
| "Don't know which android drawable suffix to use for scale: " + | ||
| scale + | ||
| '\nAsset: ' + | ||
| JSON.stringify(asset, null, '\t') + | ||
| '\nPossible scales are:' + | ||
| JSON.stringify(androidScaleSuffix, null, '\t'), | ||
| ); | ||
| } | ||
| return 'drawable-' + suffix; | ||
| } | ||
| export function getAndroidResourceIdentifier(asset: PackagerAsset): string { | ||
| return (getBasePath(asset) + '/' + asset.name) | ||
| .toLowerCase() | ||
| .replace(/\//g, '_') // Encode folder structure in file name | ||
| .replace(/([^a-z0-9_])/g, '') // Remove illegal chars | ||
| .replace(/^assets_/, ''); // Remove "assets_" prefix | ||
| } | ||
| export function getBasePath(asset: PackagerAsset): string { | ||
| const basePath = asset.httpServerLocation; | ||
| return basePath.startsWith('/') ? basePath.slice(1) : basePath; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| /** | ||
| * 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. | ||
| * | ||
| * @flow strict-local | ||
| * @format | ||
| * @oncall react_native | ||
| */ | ||
| /*:: | ||
| export type * from './path-support.flow'; | ||
| */ | ||
| if (process.env.BUILD_EXCLUDE_BABEL_REGISTER != null) { | ||
| require('../../../scripts/build/babel-register').registerForMonorepo(); | ||
| } | ||
| export * from './path-support.flow'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| /** | ||
| * 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. | ||
| * | ||
| * @flow strict | ||
| * @format | ||
| */ | ||
| export type PackagerAsset = { | ||
| +__packager_asset: boolean, | ||
| +fileSystemLocation: string, | ||
| +httpServerLocation: string, | ||
| +width: ?number, | ||
| +height: ?number, | ||
| +scales: Array<number>, | ||
| +hash: string, | ||
| +name: string, | ||
| +type: string, | ||
| ... | ||
| }; | ||
| const assets: Array<PackagerAsset> = []; | ||
| export function registerAsset(asset: PackagerAsset): number { | ||
| // `push` returns new array length, so the first asset will | ||
| // get id 1 (not 0) to make the value truthy | ||
| return assets.push(asset); | ||
| } | ||
| export function getAssetByID(assetId: number): PackagerAsset { | ||
| return assets[assetId - 1]; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| /** | ||
| * 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. | ||
| * | ||
| * @flow strict-local | ||
| * @format | ||
| * @oncall react_native | ||
| */ | ||
| /*:: | ||
| export type * from './registry.flow'; | ||
| */ | ||
| if (process.env.BUILD_EXCLUDE_BABEL_REGISTER != null) { | ||
| require('../../../scripts/build/babel-register').registerForMonorepo(); | ||
| } | ||
| export * from './registry.flow'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -23,6 +23,7 @@ const config = { | ||
| // Make Metro able to resolve required external dependencies | ||
| watchFolders: [ | ||
| path.resolve(__dirname, '../../node_modules'), | ||
| path.resolve(__dirname, '../../scripts/build'), // babel-register.js | ||
| ||
| path.resolve(__dirname, '../assets'), | ||
| path.resolve(__dirname, '../community-cli-plugin'), | ||
| path.resolve(__dirname, '../dev-middleware'), | ||
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.
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.
This suggestion still applies — all other files do not need to be packaged, but are instead present at dev-time.