Convert build scripts to regular Flow syntax (#49103)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/49103

Changelog: [Internal]

Reviewed By: j-piasecki

Differential Revision: D68960540

fbshipit-source-id: 0ac01529eaea97db98b85b6021532092997d633b
This commit is contained in:
Alex Hunt
2025-02-03 03:49:23 -08:00
committed by Facebook GitHub Bot
parent e1575857dd
commit 3cf400a51b
8 changed files with 63 additions and 43 deletions
+28 -2
View File
@@ -9,9 +9,14 @@
* @oncall react_native
*/
const {PACKAGES_DIR, RN_INTEGRATION_TESTS_RUNNER_DIR} = require('./consts');
const {
PACKAGES_DIR,
RN_INTEGRATION_TESTS_RUNNER_DIR,
SCRIPTS_DIR,
} = require('./consts');
let isRegisteredForMonorepo = false;
let isRegisteredForScriptsDir = false;
/**
* Calling this function enables all Node.js packages to run from source when
@@ -46,4 +51,25 @@ function registerForMonorepo() {
isRegisteredForMonorepo = true;
}
module.exports = {registerForMonorepo};
/**
* Calling this function enables entry points under scripts/ to run from source.
*
* ```js
* // Place in a script entry point
* require('../babel-register').registerForScript();
* ```
*/
function registerForScript() {
if (isRegisteredForScriptsDir) {
return;
}
require('metro-babel-register')([SCRIPTS_DIR]);
isRegisteredForScriptsDir = true;
}
module.exports = {
registerForMonorepo,
registerForScript,
};
+1 -3
View File
@@ -9,13 +9,11 @@
* @oncall react_native
*/
/*::
import type {BabelCoreOptions} from '@babel/core';
*/
const TARGET_NODE_VERSION = '18';
const config /*: BabelCoreOptions */ = {
const config: BabelCoreOptions = {
presets: [
require.resolve('@babel/preset-flow'),
[
+7 -5
View File
@@ -9,6 +9,8 @@
* @oncall react_native
*/
require('../babel-register').registerForScript();
const {PACKAGES_DIR, REPO_ROOT} = require('../consts');
const translateSourceFile = require('./build-types/translateSourceFile');
const chalk = require('chalk');
@@ -103,11 +105,11 @@ async function main() {
);
}
function getPackageName(file /*: string */) /*: string */ {
function getPackageName(file: string): string {
return path.relative(PACKAGES_DIR, file).split(path.sep)[0];
}
function getBuildPath(file /*: string */) /*: string */ {
function getBuildPath(file: string): string {
const packageDir = path.join(PACKAGES_DIR, getPackageName(file));
return path.join(
@@ -119,9 +121,9 @@ function getBuildPath(file /*: string */) /*: string */ {
);
}
function ignoreShadowedFiles(files /*: Array<string> */) /*: Array<string> */ {
const shadowedPrefixes /*: Record<string, boolean> */ = {};
const result /*: Array<string> */ = [];
function ignoreShadowedFiles(files: Array<string>): Array<string> {
const shadowedPrefixes: Record<string, boolean> = {};
const result: Array<string> = [];
// Find all flow definition files that shadow other files
for (const file of files) {
@@ -9,31 +9,29 @@
* @oncall react_native
*/
/*::
import type {TransformVisitor} from 'hermes-transform';
import type {TransformASTResult} from 'hermes-transform/dist/transform/transformAST';
import type {ParseResult} from 'hermes-transform/dist/transform/parse';
*/
import type {TransformASTResult} from 'hermes-transform/dist/transform/transformAST';
const {transformAST} = require('hermes-transform/dist/transform/transformAST');
const visitors /*: TransformVisitor */ = context => ({
ObjectTypeProperty(node) /*: void */ {
const visitors: TransformVisitor = context => ({
ObjectTypeProperty(node): void {
if (node.key.type === 'Identifier' && node.key.name.startsWith('_')) {
context.removeNode(node);
}
},
Property(node) /*: void */ {
Property(node): void {
if (node.key.type === 'Identifier' && node.key.name.startsWith('_')) {
context.removeNode(node);
}
},
PropertyDefinition(node) /*: void */ {
PropertyDefinition(node): void {
if (node.key.type === 'Identifier' && node.key.name.startsWith('_')) {
context.removeNode(node);
}
},
MethodDefinition(node) /*: void */ {
MethodDefinition(node): void {
if (node.key.type === 'Identifier' && node.key.name.startsWith('_')) {
context.removeNode(node);
}
@@ -41,8 +39,8 @@ const visitors /*: TransformVisitor */ = context => ({
});
async function stripPrivateProperties(
source /*: ParseResult */,
) /*: Promise<TransformASTResult> */ {
source: ParseResult,
): Promise<TransformASTResult> {
return transformAST(source, visitors);
}
@@ -9,19 +9,15 @@
* @oncall react_native
*/
/*::
import type {ParseResult} from 'hermes-transform/dist/transform/parse';
import type {TransformASTResult} from 'hermes-transform/dist/transform/transformAST';
*/
const translate = require('flow-api-translator');
const {parse, print} = require('hermes-transform');
/*::
type TransformFn = (ParseResult) => Promise<TransformASTResult>;
*/
type TransformFn = ParseResult => Promise<TransformASTResult>;
const preTransforms /*: Array<TransformFn> */ = [
const preTransforms: Array<TransformFn> = [
require('./transforms/stripPrivateProperties'),
];
const prettierOptions = {parser: 'babel'};
@@ -32,9 +28,7 @@ const prettierOptions = {parser: 'babel'};
* This uses [flow-api-translator](https://www.npmjs.com/package/flow-api-translator),
* and applies extra transformations such as stripping private properties.
*/
async function translateSourceFile(
source /*: string */,
) /*: Promise<string> */ {
async function translateSourceFile(source: string): Promise<string> {
// Parse Flow source
const parsed = await parse(source);
@@ -49,9 +43,9 @@ async function translateSourceFile(
}
async function applyTransforms(
source /*: ParseResult */,
transforms /*: $ReadOnlyArray<TransformFn> */,
) /*: Promise<ParseResult> */ {
source: ParseResult,
transforms: $ReadOnlyArray<TransformFn>,
): Promise<ParseResult> {
return transforms.reduce((input, transform) => {
return input.then(async result => {
const transformed = await transform(result);
+2
View File
@@ -9,6 +9,8 @@
* @oncall react_native
*/
require('../babel-register').registerForScript();
const {PACKAGES_DIR, REPO_ROOT} = require('../consts');
const {
buildConfig,
+2
View File
@@ -9,6 +9,8 @@
* @oncall react_native
*/
require('../babel-register').registerForScript();
const {BUILD_DIR, PACKAGES_DIR} = require('./build');
const {buildConfig} = require('./config');
const fs = require('fs');
+9 -11
View File
@@ -9,13 +9,12 @@
* @oncall react_native
*/
/*::
require('../babel-register').registerForScript();
import type {BabelCoreOptions} from '@babel/core';
*/
const {ModuleResolutionKind} = require('typescript');
/*::
export type BuildOptions = $ReadOnly<{
// The target runtime to compile for.
target: 'node',
@@ -31,7 +30,6 @@ export type BuildConfig = $ReadOnly<{
// The packages to include for build and their build options.
packages: $ReadOnly<{[packageName: string]: BuildOptions}>,
}>;
*/
/**
* - BUILD CONFIG -
@@ -40,7 +38,7 @@ export type BuildConfig = $ReadOnly<{
* setup. These must use a consistent package structure and (today) target
* Node.js packages only.
*/
const buildConfig /*: BuildConfig */ = {
const buildConfig: BuildConfig = {
/* eslint sort-keys: "error" */
packages: {
'community-cli-plugin': {
@@ -67,8 +65,8 @@ const defaultBuildOptions = {
};
function getBuildOptions(
packageName /*: $Keys<BuildConfig['packages']> */,
) /*: Required<BuildOptions> */ {
packageName: $Keys<BuildConfig['packages']>,
): Required<BuildOptions> {
return {
...defaultBuildOptions,
...buildConfig.packages[packageName],
@@ -76,8 +74,8 @@ function getBuildOptions(
}
function getBabelConfig(
packageName /*: $Keys<BuildConfig['packages']> */,
) /*: BabelCoreOptions */ {
packageName: $Keys<BuildConfig['packages']>,
): BabelCoreOptions {
const {target} = getBuildOptions(packageName);
switch (target) {
@@ -87,8 +85,8 @@ function getBabelConfig(
}
function getTypeScriptCompilerOptions(
packageName /*: $Keys<BuildConfig['packages']> */,
) /*: Object */ {
packageName: $Keys<BuildConfig['packages']>,
): Object {
const {target} = getBuildOptions(packageName);
switch (target) {