Skip to content

Commit

Permalink
feat: merge view+module native templates (#562)
Browse files Browse the repository at this point in the history
## Summary

This adds new templates that use `Kotlin` and `Objective-C`. The
templates each have a native view and a native module included.

### Other Changes / Side Effects

1. With 993d5cd, the new arch and mixed
arch views will no longer have the `View` suffix in their codegen names.
This doesn't break codegen as the name field is arbitrary as it isn't
stated otherwise [in the new arch working group
documents](https://github.com/reactwg/react-native-new-architecture/blob/main/docs/enable-libraries-prerequisites.md#configure-codegen).
One important matter to remember here is to make sure we pass the `RN`
prefix since headers can conflict.
2. No more Java templates! I've removed them all for the sake of Kotlin.
3. I've removed templates like view-new (new arch-only view template)
since we now have view+module templates and it would be hard to maintain
the old model.
4. I kept `module-legacy`, `module-mixed`, and `module-new` since they
are used by cpp.
5. I kept `module-legacy`, and `view-legacy` since they are used by
Swift.

## Test plan

1. Go to `packages/create-react-native-library`.
7. Call `yarn prepare` to build the CLI.
8. Run `./bin/create-react-native-library` to run the CLI you built.
9. Fill in the name, email, etc., and make sure to select ` Fabric view
and Turbo module with backward compat`.
10. Go to the library you created and make sure to build the following:
    a. Android with old architecture
    b. iOS with old architecture
    c. Android with new architecture
    d. iOS with new architecture
  • Loading branch information
atlj authored Jun 20, 2024
1 parent 3676c71 commit a75cf32
Show file tree
Hide file tree
Showing 68 changed files with 638 additions and 762 deletions.
70 changes: 25 additions & 45 deletions .github/workflows/build-templates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,57 +28,41 @@ jobs:
- module-legacy
- module-mixed
- module-new
- view-legacy
- view-mixed
- view-new
- view-module-legacy
- view-module-mixed
- view-module-new
language:
- java-objc
- java-swift
- kotlin-objc
- kotlin-swift
- cpp
exclude:
- os: macos-14
- type: view-module-legacy
language: cpp
- type: view-module-mixed
language: cpp
- type: view-module-new
language: cpp
- type: module-legacy
language: kotlin-objc
- type: module-mixed
language: kotlin-objc
- os: macos-14
language: kotlin-swift
- type: module-new
language: java-swift
- type: module-new
language: kotlin-objc
include:
- os: ubuntu-latest
type: view-legacy
language: kotlin-swift
- type: module-mixed
language: java-swift
- type: module-mixed
- os: macos-14
type: view-legacy
language: kotlin-swift
- type: view-new
language: java-swift
- type: view-new
- os: ubuntu-latest
type: module-legacy
language: kotlin-swift
- type: view-mixed
language: java-swift
- type: view-mixed
- os: macos-14
type: module-legacy
language: kotlin-swift
include:
- os: ubuntu-latest
type: library
language: js
- os: ubuntu-latest
type: module-legacy
language: cpp
- os: ubuntu-latest
type: module-mixed
language: cpp
- os: ubuntu-latest
type: module-new
language: cpp
- os: macos-14
type: module-legacy
language: cpp
- os: macos-14
type: module-mixed
language: cpp
- os: macos-14
type: module-new
language: cpp

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.os }}-${{ matrix.type }}-${{ matrix.language }}
Expand Down Expand Up @@ -138,17 +122,13 @@ jobs:
working-directory: ${{ env.work_dir }}
run: |
# Build Android for only some matrices to skip redundant builds
if [[ ${{ matrix.os }} == ubuntu-latest ]]; then
if [[ ${{ matrix.type }} == view-* && ${{ matrix.language }} == *-objc ]] || [[ ${{ matrix.type }} == module-* && ${{ matrix.language }} == *-objc ]] || [[ ${{ matrix.type }} == module-* && ${{ matrix.language }} == cpp ]]; then
if [[ ${{ matrix.os }} == ubuntu-latest ]] && [[ ${{ matrix.language }} != js ]] ; then
echo "android_build=1" >> $GITHUB_ENV
fi
fi
# Build iOS for only some matrices to skip redundant builds
if [[ ${{ matrix.os }} == macos-14 ]]; then
if [[ ${{ matrix.type }} == view-* && ${{ matrix.language }} == java-* ]] || [[ ${{ matrix.type }} == module-* && ${{ matrix.language }} == java-* ]] || [[ ${{ matrix.type }} == module-* && ${{ matrix.language }} == cpp ]]; then
if [[ ${{ matrix.os }} == macos-14 ]] && [[ ${{ matrix.language }} != js ]]; then
echo "ios_build=1" >> $GITHUB_ENV
fi
fi
- name: Cache turborepo
Expand Down
202 changes: 96 additions & 106 deletions packages/create-react-native-library/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,42 +38,70 @@ const NATIVE_COMMON_EXAMPLE_FILES = path.resolve(
);

const NATIVE_FILES = {
module_legacy: path.resolve(__dirname, '../templates/native-library-legacy'),
module_new: path.resolve(__dirname, '../templates/native-library-new'),
module_mixed: path.resolve(__dirname, '../templates/native-library-mixed'),
view_legacy: path.resolve(__dirname, '../templates/native-view-legacy'),
view_mixed: path.resolve(__dirname, '../templates/native-view-mixed'),
view_new: path.resolve(__dirname, '../templates/native-view-new'),
} as const;

const JAVA_FILES = {
module_legacy: path.resolve(__dirname, '../templates/java-library-legacy'),
module_new: path.resolve(__dirname, '../templates/java-library-new'),
module_mixed: path.resolve(__dirname, '../templates/java-library-mixed'),
view_legacy: path.resolve(__dirname, '../templates/java-view-legacy'),
view_mixed: path.resolve(__dirname, '../templates/java-view-mixed'),
view_new: path.resolve(__dirname, '../templates/java-view-new'),
'module-legacy': path.resolve(
__dirname,
'../templates/native-library-legacy'
),
'module-new': path.resolve(__dirname, '../templates/native-library-new'),
'module-mixed': path.resolve(__dirname, '../templates/native-library-mixed'),
'view-legacy': path.resolve(__dirname, '../templates/native-view-legacy'),
'view-module-legacy': path.resolve(
__dirname,
'../templates/native-view-library-legacy'
),
'view-module-mixed': path.resolve(
__dirname,
'../templates/native-view-library-mixed'
),
'view-module-new': path.resolve(
__dirname,
'../templates/native-view-library-new'
),
} as const;

const OBJC_FILES = {
module_common: path.resolve(__dirname, '../templates/objc-library'),
view_legacy: path.resolve(__dirname, '../templates/objc-view-legacy'),
view_mixed: path.resolve(__dirname, '../templates/objc-view-mixed'),
view_new: path.resolve(__dirname, '../templates/objc-view-new'),
'module-legacy': path.resolve(__dirname, '../templates/objc-library'),
'module-mixed': path.resolve(__dirname, '../templates/objc-library'),
'module-new': path.resolve(__dirname, '../templates/objc-library'),
'view-module-legacy': path.resolve(
__dirname,
'../templates/objc-view-library-legacy'
),
'view-module-mixed': path.resolve(
__dirname,
'../templates/objc-view-library-mixed'
),
'view-module-new': path.resolve(
__dirname,
'../templates/objc-view-library-new'
),
} as const;

const KOTLIN_FILES = {
module_legacy: path.resolve(__dirname, '../templates/kotlin-library-legacy'),
module_new: path.resolve(__dirname, '../templates/kotlin-library-new'),
module_mixed: path.resolve(__dirname, '../templates/kotlin-library-mixed'),
view_legacy: path.resolve(__dirname, '../templates/kotlin-view-legacy'),
view_mixed: path.resolve(__dirname, '../templates/kotlin-view-mixed'),
view_new: path.resolve(__dirname, '../templates/kotlin-view-new'),
'module-legacy': path.resolve(
__dirname,
'../templates/kotlin-library-legacy'
),
'module-new': path.resolve(__dirname, '../templates/kotlin-library-new'),
'module-mixed': path.resolve(__dirname, '../templates/kotlin-library-mixed'),
'view-legacy': path.resolve(__dirname, '../templates/kotlin-view-legacy'),
'view-module-legacy': path.resolve(
__dirname,
'../templates/kotlin-view-library-legacy'
),
'view-module-mixed': path.resolve(
__dirname,
'../templates/kotlin-view-library-mixed'
),
'view-module-new': path.resolve(
__dirname,
'../templates/kotlin-view-library-new'
),
} as const;

const SWIFT_FILES = {
module_legacy: path.resolve(__dirname, '../templates/swift-library-legacy'),
view_legacy: path.resolve(__dirname, '../templates/swift-view-legacy'),
'module-legacy': path.resolve(__dirname, '../templates/swift-library-legacy'),
'view-legacy': path.resolve(__dirname, '../templates/swift-view-legacy'),
} as const;

type ArgName =
Expand All @@ -89,22 +117,17 @@ type ArgName =
| 'example'
| 'react-native-version';

type ProjectLanguages =
| 'java-objc'
| 'java-swift'
| 'kotlin-objc'
| 'kotlin-swift'
| 'cpp'
| 'js';
type ProjectLanguages = 'kotlin-objc' | 'kotlin-swift' | 'cpp' | 'js';

type ProjectType =
| 'library'
| 'module-legacy'
| 'module-new'
| 'module-mixed'
| 'view-mixed'
| 'view-new'
| 'module-new'
| 'view-legacy'
| 'library';
| 'view-module-legacy'
| 'view-module-mixed'
| 'view-module-new';

type Answers = {
slug: string;
Expand All @@ -127,37 +150,13 @@ const LANGUAGE_CHOICES: {
{
title: 'Kotlin & Objective-C',
value: 'kotlin-objc',
types: [
'module-legacy',
'module-new',
'module-mixed',
'view-mixed',
'view-new',
'view-legacy',
],
},
{
title: 'Java & Objective-C',
value: 'java-objc',
types: [
'module-legacy',
'module-new',
'module-mixed',
'view-mixed',
'view-new',
'view-legacy',
],
types: ['view-module-legacy', 'view-module-mixed', 'view-module-new'],
},
{
title: 'Kotlin & Swift',
value: 'kotlin-swift',
types: ['module-legacy', 'view-legacy'],
},
{
title: 'Java & Swift',
value: 'java-swift',
types: ['module-legacy', 'view-legacy'],
},
{
title: 'C++ for Android & iOS',
value: 'cpp',
Expand All @@ -178,6 +177,21 @@ const TYPE_CHOICES: {
value: ProjectType;
description: string;
}[] = [
{
title: 'Fabric view and Turbo module with backward compat',
value: 'view-module-mixed',
description: BACKCOMPAT_DESCRIPTION,
},
{
title: 'Fabric view and Turbo module',
value: 'view-module-new',
description: NEWARCH_DESCRIPTION,
},
{
title: 'Native module and Native view',
value: 'view-module-legacy',
description: 'bridge for native APIs and views to JS',
},
{
title: 'JavaScript library',
value: 'library',
Expand All @@ -203,16 +217,6 @@ const TYPE_CHOICES: {
value: 'module-new',
description: NEWARCH_DESCRIPTION,
},
{
title: 'Fabric view with backward compat',
value: 'view-mixed',
description: BACKCOMPAT_DESCRIPTION,
},
{
title: 'Fabric view',
value: 'view-new',
description: NEWARCH_DESCRIPTION,
},
];

const args: Record<ArgName, yargs.Options> = {
Expand Down Expand Up @@ -501,8 +505,8 @@ async function create(argv: yargs.Arguments<any>) {
authorEmail,
authorUrl,
repoUrl,
type = 'module-mixed',
languages = type === 'library' ? 'js' : 'java-objc',
type = 'view-module-mixed',
languages = type === 'library' ? 'js' : 'kotlin-objc',
example: hasExample,
reactNativeVersion,
} = {
Expand Down Expand Up @@ -561,13 +565,11 @@ async function create(argv: yargs.Arguments<any>) {
version = FALLBACK_BOB_VERSION;
}

const moduleType = type.startsWith('view-') ? 'view' : 'module';
const arch =
type === 'module-new' || type === 'view-new'
? 'new'
: type === 'module-mixed' || type === 'view-mixed'
? 'mixed'
: 'legacy';
const arch = type.endsWith('new')
? 'new'
: type.endsWith('mixed')
? 'mixed'
: 'legacy';

const example =
hasExample && !local ? (type === 'library' ? 'expo' : 'native') : 'none';
Expand Down Expand Up @@ -610,10 +612,9 @@ async function create(argv: yargs.Arguments<any>) {
native: languages !== 'js',
arch,
cpp: languages === 'cpp',
kotlin: languages === 'kotlin-objc' || languages === 'kotlin-swift',
swift: languages === 'java-swift' || languages === 'kotlin-swift',
view: moduleType === 'view',
module: moduleType === 'module',
swift: languages === 'kotlin-swift',
view: type.includes('view'),
module: type.includes('module'),
},
author: {
name: authorName,
Expand Down Expand Up @@ -697,7 +698,7 @@ async function create(argv: yargs.Arguments<any>) {
}
}

if (languages === 'js') {
if (type === 'library') {
await copyDir(JS_FILES, folder);
await copyDir(EXPO_FILES, folder);
} else {
Expand All @@ -714,29 +715,18 @@ async function create(argv: yargs.Arguments<any>) {
await copyDir(NATIVE_COMMON_EXAMPLE_FILES, folder);
}

if (moduleType === 'module') {
await copyDir(NATIVE_FILES[`${moduleType}_${arch}`], folder);
} else {
await copyDir(NATIVE_FILES[`${moduleType}_${arch}`], folder);
}
await copyDir(NATIVE_FILES[type], folder);

if (options.project.swift) {
await copyDir(SWIFT_FILES[`${moduleType}_legacy`], folder);
if (
type === 'view-legacy' ||
(type === 'module-legacy' && options.project.swift)
) {
await copyDir(SWIFT_FILES[type], folder);
} else {
if (moduleType === 'module') {
await copyDir(OBJC_FILES[`${moduleType}_common`], folder);
} else {
await copyDir(OBJC_FILES[`view_${arch}`], folder);
}
await copyDir(OBJC_FILES[type], folder);
}

const templateType = `${moduleType}_${arch}` as const;

if (options.project.kotlin) {
await copyDir(KOTLIN_FILES[templateType], folder);
} else {
await copyDir(JAVA_FILES[templateType], folder);
}
await copyDir(KOTLIN_FILES[type], folder);

if (options.project.cpp) {
await copyDir(CPP_FILES, folder);
Expand Down
Loading

0 comments on commit a75cf32

Please sign in to comment.