diff --git a/packages/community-cli-plugin/src/commands/__tests__/reactNativeSubpathResolution-test.js b/packages/community-cli-plugin/src/commands/__tests__/reactNativeSubpathResolution-test.js new file mode 100644 index 00000000000..a7808616608 --- /dev/null +++ b/packages/community-cli-plugin/src/commands/__tests__/reactNativeSubpathResolution-test.js @@ -0,0 +1,43 @@ +/** + * 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 + */ + +const {execFileSync} = require('node:child_process'); +const fs = require('node:fs'); +const path = require('node:path'); + +const COMMANDS_DIR = path.join(__dirname, '..'); +const REPO_ROOT = path.resolve(__dirname, '../../../../..'); + +// The wrappers load scripts as `react-native/`, resolved through +// react-native's `exports` map: no extension guessing, no index.js fallback. +// Must run in a real node process — Jest's moduleNameMapper bypasses `exports` +// and would pass either way. +const specifiers = fs + .readdirSync(COMMANDS_DIR) + .filter(name => name.endsWith('.js')) + .flatMap(name => + [ + ...fs + .readFileSync(path.join(COMMANDS_DIR, name), 'utf8') + .matchAll(/'(react-native\/[^']+)'/g), + ].map(match => ({file: name, spec: match[1]})), + ); + +test('found specifiers to check', () => { + expect(specifiers.length).toBeGreaterThan(0); +}); + +test.each(specifiers)('$file resolves $spec', ({spec}) => { + execFileSync( + process.execPath, + ['-e', `require.resolve(${JSON.stringify(spec)})`], + {cwd: REPO_ROOT, stdio: 'ignore'}, + ); +}); diff --git a/packages/community-cli-plugin/src/commands/codegen.js b/packages/community-cli-plugin/src/commands/codegen.js index cb158a1e8bb..75fa43b34d1 100644 --- a/packages/community-cli-plugin/src/commands/codegen.js +++ b/packages/community-cli-plugin/src/commands/codegen.js @@ -47,7 +47,7 @@ const codegenCommand: Command = { args: CodegenCommandArgs, ): void => { const generateArtifactsExecutor = require.resolve( - 'react-native/scripts/codegen/generate-artifacts-executor', + 'react-native/scripts/codegen/generate-artifacts-executor/index.js', {paths: [config.root]}, ); // $FlowFixMe[unsupported-syntax] dynamic require of a resolved path diff --git a/packages/community-cli-plugin/src/commands/spm.js b/packages/community-cli-plugin/src/commands/spm.js index 181ad4ff812..df8d3c0ce77 100644 --- a/packages/community-cli-plugin/src/commands/spm.js +++ b/packages/community-cli-plugin/src/commands/spm.js @@ -107,7 +107,7 @@ const spmCommand: Command = { } } const setupAppleSpm = require.resolve( - 'react-native/scripts/setup-apple-spm', + 'react-native/scripts/setup-apple-spm.js', {paths: [config.root]}, ); // $FlowFixMe[unsupported-syntax] dynamic require of a resolved path