Align Codegen between iOS and Android (#33864)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/33864 This Diff aligns the way in which iOS and Android codegen the modules and components. Android takes all the JS in the project root folder and creates components starting from there. iOS used to required to specify a specific path for each component, within a JSON field called `libraries`. This Diff let iOS work in the same way as android does **Backward compatibility:** This diff still support the old way for iOS, but we are deprecating it. ## Changelog [iOS][Added] - Support codegen from a single folder Reviewed By: cortinico Differential Revision: D36473005 fbshipit-source-id: 1e8cf0f9764f529c02e948984c74d1982a84030b
This commit is contained in:
Родитель
1c1fbce2d1
Коммит
05aaba9514
|
@ -65,7 +65,7 @@ rn_library(
|
|||
"pfh:ReactNative_CommonInfrastructurePlaceholder",
|
||||
"supermodule:xplat/default/public.react_native.playground",
|
||||
],
|
||||
native_component_spec_name = "MyNativeViewSpec",
|
||||
native_component_spec_name = "AppSpecs",
|
||||
skip_processors = True,
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
|
@ -317,7 +317,7 @@ rn_xplat_cxx_library2(
|
|||
reexport_all_header_dependencies = False,
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
":generated_components-MyNativeViewSpec",
|
||||
":generated_components-AppSpecs",
|
||||
"//xplat/js/react-native-github:RCTFabricComponentViewsBase",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
|
||||
#import "RNTMyNativeViewComponentView.h"
|
||||
|
||||
#import <react/renderer/components/MyNativeViewSpec/ComponentDescriptors.h>
|
||||
#import <react/renderer/components/MyNativeViewSpec/EventEmitters.h>
|
||||
#import <react/renderer/components/MyNativeViewSpec/Props.h>
|
||||
#import <react/renderer/components/MyNativeViewSpec/RCTComponentViewHelpers.h>
|
||||
#import <react/renderer/components/AppSpecs/ComponentDescriptors.h>
|
||||
#import <react/renderer/components/AppSpecs/EventEmitters.h>
|
||||
#import <react/renderer/components/AppSpecs/Props.h>
|
||||
#import <react/renderer/components/AppSpecs/RCTComponentViewHelpers.h>
|
||||
|
||||
#import "RCTFabricComponentsPlugins.h"
|
||||
|
||||
|
|
|
@ -31,21 +31,8 @@
|
|||
"ws": "^6.1.4"
|
||||
},
|
||||
"codegenConfig": {
|
||||
"libraries": [
|
||||
{
|
||||
"name": "ScreenshotManagerSpec",
|
||||
"type": "modules",
|
||||
"ios": {},
|
||||
"android": {},
|
||||
"jsSrcsDir": "NativeModuleExample"
|
||||
},
|
||||
{
|
||||
"name": "MyNativeViewSpec",
|
||||
"type": "components",
|
||||
"ios": {},
|
||||
"android": {},
|
||||
"jsSrcsDir": "NativeComponentExample/js"
|
||||
}
|
||||
]
|
||||
"name": "AppSpecs",
|
||||
"type": "all",
|
||||
"jsSrcsDir": "."
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,48 @@
|
|||
|
||||
'use-strict';
|
||||
|
||||
const SINGLE_LIBRARY_CODEGEN_CONFIG = {
|
||||
codegenConfig: {
|
||||
libraries: [
|
||||
{
|
||||
name: 'react-native',
|
||||
type: 'all',
|
||||
jsSrcsDir: '.',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const MULTIPLE_LIBRARIES_CODEGEN_CONFIG = {
|
||||
codegenConfig: {
|
||||
libraries: [
|
||||
{
|
||||
name: 'react-native',
|
||||
type: 'all',
|
||||
jsSrcsDir: '.',
|
||||
},
|
||||
{
|
||||
name: 'my-component',
|
||||
type: 'components',
|
||||
jsSrcsDir: 'component/js',
|
||||
},
|
||||
{
|
||||
name: 'my-module',
|
||||
type: 'module',
|
||||
jsSrcsDir: 'module/js',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const NO_LIBRARIES_CONFIG_FILE = {
|
||||
codegenConfig: {
|
||||
name: 'AppModules',
|
||||
type: 'all',
|
||||
jsSrcsDir: '.',
|
||||
},
|
||||
};
|
||||
|
||||
const SCHEMA_TEXT = `
|
||||
{
|
||||
"modules": {
|
||||
|
@ -84,4 +126,7 @@ const SCHEMA = JSON.parse(SCHEMA_TEXT);
|
|||
module.exports = {
|
||||
schemaText: SCHEMA_TEXT,
|
||||
schema: SCHEMA,
|
||||
noLibrariesConfigFile: NO_LIBRARIES_CONFIG_FILE,
|
||||
singleLibraryCodegenConfig: SINGLE_LIBRARY_CODEGEN_CONFIG,
|
||||
multipleLibrariesCodegenConfig: MULTIPLE_LIBRARIES_CODEGEN_CONFIG,
|
||||
};
|
||||
|
|
|
@ -11,8 +11,13 @@
|
|||
'use strict';
|
||||
|
||||
const underTest = require('../generate-artifacts-executor');
|
||||
const fixtures = require('../__test_fixtures__/fixtures');
|
||||
const path = require('path');
|
||||
|
||||
const codegenConfigKey = 'codegenConfig';
|
||||
const reactNativeDependencyName = 'react-native';
|
||||
const rootPath = path.join(__dirname, '../../..');
|
||||
|
||||
describe('generateCode', () => {
|
||||
it('executeNodes with the right arguents', () => {
|
||||
// Define variables and expected values
|
||||
|
@ -69,3 +74,130 @@ describe('generateCode', () => {
|
|||
expect(mkdirSyncInvocationCount).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractLibrariesFromJSON', () => {
|
||||
it('throws if in react-native and no dependencies found', () => {
|
||||
let libraries = [];
|
||||
let configFile = {};
|
||||
expect(() => {
|
||||
underTest._extractLibrariesFromJSON(
|
||||
configFile,
|
||||
libraries,
|
||||
codegenConfigKey,
|
||||
);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it('it skips if not into react-native and no dependencies found', () => {
|
||||
let libraries = [];
|
||||
let configFile = {};
|
||||
|
||||
underTest._extractLibrariesFromJSON(
|
||||
configFile,
|
||||
libraries,
|
||||
codegenConfigKey,
|
||||
'some-node-module',
|
||||
'node_modules/some',
|
||||
);
|
||||
expect(libraries.length).toBe(0);
|
||||
});
|
||||
|
||||
it('extracts a single dependency when config has no libraries', () => {
|
||||
let libraries = [];
|
||||
let configFile = fixtures.noLibrariesConfigFile;
|
||||
underTest._extractLibrariesFromJSON(
|
||||
configFile,
|
||||
libraries,
|
||||
codegenConfigKey,
|
||||
'my-app',
|
||||
'.',
|
||||
);
|
||||
expect(libraries.length).toBe(1);
|
||||
expect(libraries[0]).toEqual({
|
||||
library: 'my-app',
|
||||
config: {
|
||||
name: 'AppModules',
|
||||
type: 'all',
|
||||
jsSrcsDir: '.',
|
||||
},
|
||||
libraryPath: '.',
|
||||
});
|
||||
});
|
||||
|
||||
it("extract codegenConfig when it's empty", () => {
|
||||
const configFile = {codegenConfig: {libraries: []}};
|
||||
let libraries = [];
|
||||
underTest._extractLibrariesFromJSON(
|
||||
configFile,
|
||||
codegenConfigKey,
|
||||
libraries,
|
||||
reactNativeDependencyName,
|
||||
rootPath,
|
||||
);
|
||||
expect(libraries.length).toBe(0);
|
||||
});
|
||||
|
||||
it('extract codegenConfig when dependency is one', () => {
|
||||
const configFile = fixtures.singleLibraryCodegenConfig;
|
||||
let libraries = [];
|
||||
underTest._extractLibrariesFromJSON(
|
||||
configFile,
|
||||
libraries,
|
||||
codegenConfigKey,
|
||||
reactNativeDependencyName,
|
||||
rootPath,
|
||||
);
|
||||
expect(libraries.length).toBe(1);
|
||||
expect(libraries[0]).toEqual({
|
||||
library: reactNativeDependencyName,
|
||||
config: {
|
||||
name: 'react-native',
|
||||
type: 'all',
|
||||
jsSrcsDir: '.',
|
||||
},
|
||||
libraryPath: rootPath,
|
||||
});
|
||||
});
|
||||
|
||||
it('extract codegenConfig with multiple dependencies', () => {
|
||||
const configFile = fixtures.multipleLibrariesCodegenConfig;
|
||||
const myDependency = 'my-dependency';
|
||||
const myDependencyPath = path.join(__dirname, myDependency);
|
||||
let libraries = [];
|
||||
underTest._extractLibrariesFromJSON(
|
||||
configFile,
|
||||
libraries,
|
||||
codegenConfigKey,
|
||||
myDependency,
|
||||
myDependencyPath,
|
||||
);
|
||||
expect(libraries.length).toBe(3);
|
||||
expect(libraries[0]).toEqual({
|
||||
library: myDependency,
|
||||
config: {
|
||||
name: 'react-native',
|
||||
type: 'all',
|
||||
jsSrcsDir: '.',
|
||||
},
|
||||
libraryPath: myDependencyPath,
|
||||
});
|
||||
expect(libraries[1]).toEqual({
|
||||
library: myDependency,
|
||||
config: {
|
||||
name: 'my-component',
|
||||
type: 'components',
|
||||
jsSrcsDir: 'component/js',
|
||||
},
|
||||
libraryPath: myDependencyPath,
|
||||
});
|
||||
expect(libraries[2]).toEqual({
|
||||
library: myDependency,
|
||||
config: {
|
||||
name: 'my-module',
|
||||
type: 'module',
|
||||
jsSrcsDir: 'module/js',
|
||||
},
|
||||
libraryPath: myDependencyPath,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -52,6 +52,97 @@ function readPackageJSON(appRootDir) {
|
|||
}
|
||||
|
||||
// Reading Libraries
|
||||
function extractLibrariesFromConfigurationArray(
|
||||
configFile,
|
||||
codegenConfigKey,
|
||||
libraries,
|
||||
dependency,
|
||||
dependencyPath,
|
||||
) {
|
||||
console.log(`[Codegen] Found ${dependency}`);
|
||||
configFile[codegenConfigKey].libraries.forEach(config => {
|
||||
const libraryConfig = {
|
||||
library: dependency,
|
||||
config,
|
||||
libraryPath: dependencyPath,
|
||||
};
|
||||
libraries.push(libraryConfig);
|
||||
});
|
||||
}
|
||||
|
||||
function extractLibrariesFromJSON(
|
||||
configFile,
|
||||
libraries,
|
||||
codegenConfigKey,
|
||||
dependency,
|
||||
dependencyPath,
|
||||
) {
|
||||
var isBlocking = false;
|
||||
if (dependency == null) {
|
||||
dependency = REACT_NATIVE_DEPENDENCY_NAME;
|
||||
dependencyPath = RN_ROOT;
|
||||
// If we are exploring the ReactNative libraries, we want to raise an error
|
||||
// if the codegen is not properly configured.
|
||||
isBlocking = true;
|
||||
}
|
||||
|
||||
if (configFile[codegenConfigKey] == null) {
|
||||
if (isBlocking) {
|
||||
throw `[Codegen] Error: Could not find codegen config for ${dependency} .`;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (configFile[codegenConfigKey].libraries == null) {
|
||||
console.log(`[Codegen] Found ${dependency}`);
|
||||
var config = configFile[codegenConfigKey];
|
||||
libraries.push({
|
||||
library: dependency,
|
||||
config,
|
||||
libraryPath: dependencyPath,
|
||||
});
|
||||
} else {
|
||||
console.log(`[Codegen] CodegenConfig Deprecated Setup for ${dependency}.
|
||||
The configuration file still contains the codegen in the libraries array.
|
||||
If possible, replace it with a single object.
|
||||
`);
|
||||
console.debug(`BEFORE:
|
||||
{
|
||||
// ...
|
||||
"codegenConfig": {
|
||||
"libraries": [
|
||||
{
|
||||
"name": "libName1",
|
||||
"type": "all|components|modules",
|
||||
"jsSrcsRoot": "libName1/js"
|
||||
},
|
||||
{
|
||||
"name": "libName2",
|
||||
"type": "all|components|modules",
|
||||
"jsSrcsRoot": "libName2/src"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
AFTER:
|
||||
{
|
||||
"codegenConfig": {
|
||||
"name": "libraries",
|
||||
"type": "all",
|
||||
"jsSrcsRoot": "."
|
||||
}
|
||||
}
|
||||
`);
|
||||
extractLibrariesFromConfigurationArray(
|
||||
configFile,
|
||||
codegenConfigKey,
|
||||
libraries,
|
||||
dependency,
|
||||
dependencyPath,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function handleReactNativeCodeLibraries(
|
||||
libraries,
|
||||
|
@ -66,21 +157,7 @@ function handleReactNativeCodeLibraries(
|
|||
throw '[Codegen] Error: Could not find config file for react-native.';
|
||||
}
|
||||
const reactNativeConfigFile = JSON.parse(fs.readFileSync(reactNativePkgJson));
|
||||
if (
|
||||
reactNativeConfigFile[codegenConfigKey] == null ||
|
||||
reactNativeConfigFile[codegenConfigKey].libraries == null
|
||||
) {
|
||||
throw '[Codegen] Error: Could not find codegen config for react-native.';
|
||||
}
|
||||
console.log('[Codegen] Found react-native');
|
||||
reactNativeConfigFile[codegenConfigKey].libraries.forEach(config => {
|
||||
const libraryConfig = {
|
||||
library: REACT_NATIVE_DEPENDENCY_NAME,
|
||||
config,
|
||||
libraryPath: RN_ROOT,
|
||||
};
|
||||
libraries.push(libraryConfig);
|
||||
});
|
||||
extractLibrariesFromJSON(reactNativeConfigFile, libraries, codegenConfigKey);
|
||||
}
|
||||
|
||||
function handleThirdPartyLibraries(
|
||||
|
@ -109,20 +186,13 @@ function handleThirdPartyLibraries(
|
|||
);
|
||||
if (fs.existsSync(configFilePath)) {
|
||||
const configFile = JSON.parse(fs.readFileSync(configFilePath));
|
||||
if (
|
||||
configFile[codegenConfigKey] != null &&
|
||||
configFile[codegenConfigKey].libraries != null
|
||||
) {
|
||||
console.log(`[Codegen] Found ${dependency}`);
|
||||
configFile[codegenConfigKey].libraries.forEach(config => {
|
||||
const libraryConfig = {
|
||||
library: dependency,
|
||||
config,
|
||||
libraryPath: codegenConfigFileDir,
|
||||
};
|
||||
libraries.push(libraryConfig);
|
||||
});
|
||||
}
|
||||
extractLibrariesFromJSON(
|
||||
configFile,
|
||||
libraries,
|
||||
codegenConfigKey,
|
||||
dependency,
|
||||
codegenConfigFileDir,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -137,21 +207,13 @@ function handleInAppLibraries(
|
|||
'\n\n[Codegen] >>>>> Searching for codegen-enabled libraries in the app',
|
||||
);
|
||||
|
||||
// Handle in-app libraries
|
||||
if (
|
||||
pkgJson[codegenConfigKey] != null &&
|
||||
pkgJson[codegenConfigKey].libraries != null
|
||||
) {
|
||||
console.log(`[Codegen] Found ${pkgJson.name}`);
|
||||
pkgJson[codegenConfigKey].libraries.forEach(config => {
|
||||
const libraryConfig = {
|
||||
library: pkgJson.name,
|
||||
config,
|
||||
libraryPath: appRootDir,
|
||||
};
|
||||
libraries.push(libraryConfig);
|
||||
});
|
||||
}
|
||||
extractLibrariesFromJSON(
|
||||
pkgJson,
|
||||
libraries,
|
||||
codegenConfigKey,
|
||||
pkgJson.name,
|
||||
appRootDir,
|
||||
);
|
||||
}
|
||||
|
||||
// CodeGen
|
||||
|
@ -377,6 +439,8 @@ function execute(
|
|||
|
||||
module.exports = {
|
||||
execute: execute,
|
||||
_executeNodeScript: executeNodeScript, // exported for testing purposes only
|
||||
_generateCode: generateCode, // exported for testing purposes only
|
||||
// exported for testing purposes only:
|
||||
_extractLibrariesFromJSON: extractLibrariesFromJSON,
|
||||
_executeNodeScript: executeNodeScript,
|
||||
_generateCode: generateCode,
|
||||
};
|
||||
|
|
|
@ -356,10 +356,20 @@ def get_react_codegen_script_phases(options={})
|
|||
app_package_path = File.join(app_path, 'package.json')
|
||||
app_codegen_config = get_codegen_config_from_file(app_package_path, config_key)
|
||||
file_list = []
|
||||
app_codegen_config['libraries'].each do |library|
|
||||
library_dir = File.join(app_path, library['jsSrcsDir'])
|
||||
file_list.concat (`find #{library_dir} -type f \\( -name "Native*.js" -or -name "*NativeComponent.js" \\)`.split("\n").sort)
|
||||
if app_codegen_config['libraries'] then
|
||||
Pod::UI.warn '[Deprecated] You are using the old `libraries` array to list all your codegen.\nThis method will be removed in the future.\nUpdate your `package.json` with a single object.'
|
||||
app_codegen_config['libraries'].each do |library|
|
||||
library_dir = File.join(app_path, library['jsSrcsDir'])
|
||||
file_list.concat (`find #{library_dir} -type f \\( -name "Native*.js" -or -name "*NativeComponent.js" \\)`.split("\n").sort)
|
||||
end
|
||||
elsif app_codegen_config['jsSrcsDir'] then
|
||||
codegen_dir = File.join(app_path, app_codegen_config['jsSrcsDir'])
|
||||
file_list.concat (`find #{codegen_dir} -type f \\( -name "Native*.js" -or -name "*NativeComponent.js" \\)`.split("\n").sort)
|
||||
else
|
||||
Pod::UI.warn '[Error] Codegen not properly configured. Please add the `codegenConf` entry to your `package.json`'
|
||||
exit 1
|
||||
end
|
||||
|
||||
input_files = file_list.map { |filename| "${PODS_ROOT}/../#{Pathname.new(filename).realpath().relative_path_from(Pod::Config.instance.installation_root)}" }
|
||||
|
||||
# Add a script phase to trigger generate artifact.
|
||||
|
|
Загрузка…
Ссылка в новой задаче