Skip to content

Commit 66f5a51

Browse files
Quadriphobs1thymikee
authored andcommitted
chore: convert bundle command to TS (#695)
* convert bundle from flow to typescript * fix ReadonlyArray from filterPlatformAssetScales * fix eslint and types * Supress eslint import/default error * disable eslint for concerned line * merge imports to one line * set ios as the default platform * make platform required * type adjustments * fix default outputBundle regression * moar comments * restart CI
1 parent fde227d commit 66f5a51

13 files changed

+102
-70
lines changed

packages/cli/src/commands/bundle/assetPathUtils.js renamed to packages/cli/src/commands/bundle/assetPathUtils.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@
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
8-
* @flow strict
97
*/
108

11-
export type PackagerAsset = {
12-
+httpServerLocation: string,
13-
+name: string,
14-
+type: string,
15-
};
9+
export interface PackagerAsset {
10+
httpServerLocation: string;
11+
name: string;
12+
type: string;
13+
}
1614

1715
/**
1816
* FIXME: using number to represent discrete scale numbers is fragile in essence because of
@@ -38,7 +36,7 @@ function getAndroidAssetSuffix(scale: number): string {
3836
}
3937

4038
// See https://developer.android.com/guide/topics/resources/drawable-resource.html
41-
const drawableFileTypes = new Set([
39+
const drawableFileTypes = new Set<string>([
4240
'gif',
4341
'jpeg',
4442
'jpg',
@@ -48,7 +46,10 @@ const drawableFileTypes = new Set([
4846
'xml',
4947
]);
5048

51-
function getAndroidResourceFolderName(asset: PackagerAsset, scale: number) {
49+
function getAndroidResourceFolderName(
50+
asset: PackagerAsset,
51+
scale: number,
52+
): string {
5253
if (!drawableFileTypes.has(asset.type)) {
5354
return 'raw';
5455
}
@@ -64,7 +65,7 @@ function getAndroidResourceFolderName(asset: PackagerAsset, scale: number) {
6465
return androidFolder;
6566
}
6667

67-
function getAndroidResourceIdentifier(asset: PackagerAsset) {
68+
function getAndroidResourceIdentifier(asset: PackagerAsset): string {
6869
const folderPath = getBasePath(asset);
6970
return `${folderPath}/${asset.name}`
7071
.toLowerCase()
@@ -73,7 +74,7 @@ function getAndroidResourceIdentifier(asset: PackagerAsset) {
7374
.replace(/^assets_/, ''); // Remove "assets_" prefix
7475
}
7576

76-
function getBasePath(asset: PackagerAsset) {
77+
function getBasePath(asset: PackagerAsset): string {
7778
let basePath = asset.httpServerLocation;
7879
if (basePath[0] === '/') {
7980
basePath = basePath.substr(1);

packages/cli/src/commands/bundle/buildBundle.js renamed to packages/cli/src/commands/bundle/buildBundle.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,44 @@
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-
* @flow
87
*/
98

9+
// @ts-ignore - no typed definition for the package
1010
import Server from 'metro/src/Server';
11-
11+
// @ts-ignore - no typed definition for the package
1212
import outputBundle from 'metro/src/shared/output/bundle';
1313
import path from 'path';
1414
import chalk from 'chalk';
15-
import type {CommandLineArgs} from './bundleCommandLineArgs';
16-
import type {ConfigT} from 'types';
15+
import {CommandLineArgs} from './bundleCommandLineArgs';
16+
import {Config} from '@react-native-community/cli-types';
1717
import saveAssets from './saveAssets';
18-
// $FlowFixMe - converted to typescript
1918
import loadMetroConfig from '../../tools/loadMetroConfig';
2019
import {logger} from '@react-native-community/cli-tools';
2120

21+
interface RequestOptions {
22+
entryFile: string;
23+
sourceMapUrl: string | undefined;
24+
dev: boolean;
25+
minify: boolean;
26+
platform: string | undefined;
27+
}
28+
29+
export interface AssetData {
30+
__packager_asset: boolean;
31+
fileSystemLocation: string;
32+
hash: string;
33+
height: number | null;
34+
httpServerLocation: string;
35+
name: string;
36+
scales: number[];
37+
type: string;
38+
width: number | null;
39+
files: string[];
40+
}
41+
2242
async function buildBundle(
2343
args: CommandLineArgs,
24-
ctx: ConfigT,
44+
ctx: Config,
2545
output: typeof outputBundle = outputBundle,
2646
) {
2747
const config = await loadMetroConfig(ctx, {
@@ -73,7 +93,7 @@ async function buildBundle(
7393
await output.save(bundle, args, logger.info);
7494

7595
// Save the assets of the bundle
76-
const outputAssets = await server.getAssets({
96+
const outputAssets: AssetData[] = await server.getAssets({
7797
...Server.DEFAULT_BUNDLE_OPTIONS,
7898
...requestOpts,
7999
bundleType: 'todo',

packages/cli/src/commands/bundle/bundle.js renamed to packages/cli/src/commands/bundle/bundle.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,20 @@
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
*/
9-
8+
import {Config} from '@react-native-community/cli-types';
109
import buildBundle from './buildBundle';
11-
import bundleCommandLineArgs from './bundleCommandLineArgs';
10+
import bundleCommandLineArgs, {CommandLineArgs} from './bundleCommandLineArgs';
1211

1312
/**
1413
* Builds the bundle starting to look for dependencies at the given entry path.
1514
*/
16-
function bundleWithOutput(_, config, args, output) {
15+
function bundleWithOutput(
16+
_: Array<string>,
17+
config: Config,
18+
args: CommandLineArgs,
19+
output: any, // untyped metro/src/shared/output/bundle or metro/src/shared/output/RamBundle
20+
) {
1721
return buildBundle(args, config, output);
1822
}
1923

packages/cli/src/commands/bundle/bundleCommandLineArgs.js renamed to packages/cli/src/commands/bundle/bundleCommandLineArgs.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,28 @@
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-
* @flow
87
*/
98

109
import path from 'path';
1110

12-
export type CommandLineArgs = {
13-
assetsDest?: string,
14-
entryFile: string,
15-
resetCache: boolean,
16-
resetGlobalCache: boolean,
17-
transformer?: string,
18-
minify?: boolean,
19-
config?: string,
20-
platform?: string,
21-
dev: boolean,
22-
bundleOutput: string,
23-
bundleEncoding?: string,
24-
maxWorkers?: number,
25-
sourcemapOutput?: string,
26-
sourcemapSourcesRoot?: string,
27-
sourcemapUseAbsolutePath: boolean,
28-
verbose: boolean,
29-
};
11+
export interface CommandLineArgs {
12+
assetsDest?: string;
13+
entryFile: string;
14+
resetCache: boolean;
15+
resetGlobalCache: boolean;
16+
transformer?: string;
17+
minify?: boolean;
18+
config?: string;
19+
platform: string;
20+
dev: boolean;
21+
bundleOutput: string;
22+
bundleEncoding?: string;
23+
maxWorkers?: number;
24+
sourcemapOutput?: string;
25+
sourcemapSourcesRoot?: string;
26+
sourcemapUseAbsolutePath: boolean;
27+
verbose: boolean;
28+
}
3029

3130
export default [
3231
{

packages/cli/src/commands/bundle/filterPlatformAssetScales.js renamed to packages/cli/src/commands/bundle/filterPlatformAssetScales.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,17 @@
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-
* @flow strict
8-
* @format
97
*/
108

11-
const ALLOWED_SCALES = {
9+
const ALLOWED_SCALES: {[key: string]: number[]} = {
1210
ios: [1, 2, 3],
1311
};
1412

1513
function filterPlatformAssetScales(
1614
platform: string,
17-
scales: $ReadOnlyArray<number>,
18-
): $ReadOnlyArray<number> {
19-
const whitelist = ALLOWED_SCALES[platform];
15+
scales: ReadonlyArray<number>,
16+
): ReadonlyArray<number> {
17+
const whitelist: number[] = ALLOWED_SCALES[platform];
2018
if (!whitelist) {
2119
return scales;
2220
}

packages/cli/src/commands/bundle/getAssetDestPathAndroid.js renamed to packages/cli/src/commands/bundle/getAssetDestPathAndroid.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,10 @@
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
8-
* @flow strict
97
*/
108

119
import path from 'path';
12-
import type {PackagerAsset} from './assetPathUtils';
13-
14-
import assetPathUtils from './assetPathUtils';
10+
import assetPathUtils, {PackagerAsset} from './assetPathUtils';
1511

1612
function getAssetDestPathAndroid(asset: PackagerAsset, scale: number): string {
1713
const androidFolder = assetPathUtils.getAndroidResourceFolderName(

packages/cli/src/commands/bundle/getAssetDestPathIOS.js renamed to packages/cli/src/commands/bundle/getAssetDestPathIOS.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
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
8-
* @flow strict
97
*/
108

119
import path from 'path';
12-
import type {PackagerAsset} from './assetPathUtils';
10+
import {PackagerAsset} from './assetPathUtils';
1311

1412
function getAssetDestPathIOS(asset: PackagerAsset, scale: number): string {
1513
const suffix = scale === 1 ? '' : `@${scale}x`;

packages/cli/src/commands/bundle/ramBundle.js renamed to packages/cli/src/commands/bundle/ramBundle.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
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
*/
8+
// @ts-ignore - no typed definition for the package
99
import outputUnbundle from 'metro/src/shared/output/RamBundle';
10-
1110
import {withOutput as bundleWithOutput} from './bundle';
12-
import bundleCommandLineArgs from './bundleCommandLineArgs';
11+
import bundleCommandLineArgs, {CommandLineArgs} from './bundleCommandLineArgs';
12+
import {Config} from '@react-native-community/cli-types';
1313

1414
/**
1515
* Builds the bundle starting to look for dependencies at the given entry path.
1616
*/
17-
function ramBundle(argv, config, args) {
17+
function ramBundle(argv: Array<string>, config: Config, args: CommandLineArgs) {
1818
return bundleWithOutput(argv, config, args, outputUnbundle);
1919
}
2020

packages/cli/src/commands/bundle/saveAssets.js renamed to packages/cli/src/commands/bundle/saveAssets.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
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
*/
98

109
import mkdirp from 'mkdirp';
@@ -15,8 +14,17 @@ import filterPlatformAssetScales from './filterPlatformAssetScales';
1514
import getAssetDestPathAndroid from './getAssetDestPathAndroid';
1615
import getAssetDestPathIOS from './getAssetDestPathIOS';
1716
import {logger} from '@react-native-community/cli-tools';
17+
import {AssetData} from './buildBundle';
1818

19-
function saveAssets(assets, platform, assetsDest) {
19+
interface CopiedFiles {
20+
[src: string]: string;
21+
}
22+
23+
function saveAssets(
24+
assets: AssetData[],
25+
platform: string,
26+
assetsDest: string | undefined,
27+
) {
2028
if (!assetsDest) {
2129
logger.warn('Assets destination folder is not set, skipping...');
2230
return Promise.resolve();
@@ -25,7 +33,7 @@ function saveAssets(assets, platform, assetsDest) {
2533
const getAssetDestPath =
2634
platform === 'android' ? getAssetDestPathAndroid : getAssetDestPathIOS;
2735

28-
const filesToCopy = Object.create(null); // Map src -> dest
36+
const filesToCopy: CopiedFiles = Object.create(null); // Map src -> dest
2937
assets.forEach(asset => {
3038
const validScales = new Set(
3139
filterPlatformAssetScales(platform, asset.scales),
@@ -43,15 +51,15 @@ function saveAssets(assets, platform, assetsDest) {
4351
return copyAll(filesToCopy);
4452
}
4553

46-
function copyAll(filesToCopy) {
54+
function copyAll(filesToCopy: CopiedFiles) {
4755
const queue = Object.keys(filesToCopy);
4856
if (queue.length === 0) {
4957
return Promise.resolve();
5058
}
5159

5260
logger.info(`Copying ${queue.length} asset files`);
5361
return new Promise((resolve, reject) => {
54-
const copyNext = error => {
62+
const copyNext = (error?: NodeJS.ErrnoException) => {
5563
if (error) {
5664
reject(error);
5765
return;
@@ -60,7 +68,8 @@ function copyAll(filesToCopy) {
6068
logger.info('Done copying assets');
6169
resolve();
6270
} else {
63-
const src = queue.shift();
71+
// queue.length === 0 is checked in previous branch, so this is string
72+
const src = queue.shift() as string;
6473
const dest = filesToCopy[src];
6574
copy(src, dest, copyNext);
6675
}
@@ -69,9 +78,13 @@ function copyAll(filesToCopy) {
6978
});
7079
}
7180

72-
function copy(src, dest, callback) {
81+
function copy(
82+
src: string,
83+
dest: string,
84+
callback: (error: NodeJS.ErrnoException) => void,
85+
): void {
7386
const destDir = path.dirname(dest);
74-
mkdirp(destDir, err => {
87+
mkdirp(destDir, (err?: NodeJS.ErrnoException) => {
7588
if (err) {
7689
callback(err);
7790
return;

packages/cli/src/tools/loadMetroConfig.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const INTERNAL_CALLSITES_REGEX = new RegExp(
3232
].join('|'),
3333
);
3434

35-
export interface DefaultConfigOption {
35+
export interface MetroConfig {
3636
resolver: {
3737
resolverMainFields: string[];
3838
blacklistRE: RegExp;
@@ -64,7 +64,7 @@ export interface DefaultConfigOption {
6464
* @todo(grabbou): As a separate PR, haste.platforms should be added before "native".
6565
* Otherwise, a.native.js will not load on Windows or other platforms
6666
*/
67-
export const getDefaultConfig = (ctx: Config): DefaultConfigOption => {
67+
export const getDefaultConfig = (ctx: Config): MetroConfig => {
6868
const hasteImplPath = path.join(ctx.reactNativePath, 'jest/hasteImpl.js');
6969
return {
7070
resolver: {
@@ -125,7 +125,10 @@ export interface ConfigOptionsT {
125125
*
126126
* This allows the CLI to always overwrite the file settings.
127127
*/
128-
export default function load(ctx: Config, options?: ConfigOptionsT) {
128+
export default function load(
129+
ctx: Config,
130+
options?: ConfigOptionsT,
131+
): Promise<MetroConfig> {
129132
const defaultConfig = getDefaultConfig(ctx);
130133
if (options && options.reporter) {
131134
/**

0 commit comments

Comments
 (0)