From 14992604d6edb0c2a6066a6fa326fb7399dd474b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Wed, 18 Dec 2024 16:48:21 +0300 Subject: [PATCH 01/67] feat: add script target --- .../react-native-builder-bob/src/index.ts | 1 + .../src/targets/script.ts | 47 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 packages/react-native-builder-bob/src/targets/script.ts diff --git a/packages/react-native-builder-bob/src/index.ts b/packages/react-native-builder-bob/src/index.ts index 1f1a26a8b..c07191907 100644 --- a/packages/react-native-builder-bob/src/index.ts +++ b/packages/react-native-builder-bob/src/index.ts @@ -13,6 +13,7 @@ import buildTypescript from './targets/typescript'; import buildCodegen from './targets/codegen'; import customTarget from './targets/custom'; import type { Options, Report, Target } from './types'; +import runScript from './targets/script'; type ArgName = 'target'; diff --git a/packages/react-native-builder-bob/src/targets/script.ts b/packages/react-native-builder-bob/src/targets/script.ts new file mode 100644 index 000000000..31195cfff --- /dev/null +++ b/packages/react-native-builder-bob/src/targets/script.ts @@ -0,0 +1,47 @@ +import kleur from 'kleur'; +import type { Input } from '../types'; +import { spawn } from '../utils/spawn'; +import dedent from 'dedent'; + +type Options = Input & { + options?: { + run?: string; + cwd?: string; + } +}; + +export default async function runScript({ + options, + root, + report +}: Options) { + if (options?.run === undefined) { + report.error( + dedent( + `No runnable provided with the script target. + Example: ${kleur.green('{["script", { run: "yarn generateTypes" }}')}` + ) + ) + process.exit(1) + } + + const [scriptBinary, ...scriptParams] = options.run.split(" "); + if (scriptBinary === undefined) { + report.error( + "No runnable provided with the script target." + ) + process.exit(1) + } + + const cwd = options?.cwd ?? root + + report.info( + `Running ${kleur.blue(options.run)} ` + ); + + await spawn(scriptBinary, scriptParams, { + cwd, + }) + + report.success(`Ran ${kleur.blue(options.run)} succesfully`) +} From 5d87d8b66748f9bf4095c31df7239ace8950df5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Thu, 19 Dec 2024 12:43:14 +0300 Subject: [PATCH 02/67] feat: add clean to the script target --- .../react-native-builder-bob/src/targets/script.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/react-native-builder-bob/src/targets/script.ts b/packages/react-native-builder-bob/src/targets/script.ts index 31195cfff..cd05d128c 100644 --- a/packages/react-native-builder-bob/src/targets/script.ts +++ b/packages/react-native-builder-bob/src/targets/script.ts @@ -1,12 +1,15 @@ import kleur from 'kleur'; +import path from 'path'; import type { Input } from '../types'; import { spawn } from '../utils/spawn'; import dedent from 'dedent'; +import del from 'del'; type Options = Input & { options?: { run?: string; cwd?: string; + clean?: string; } }; @@ -35,6 +38,15 @@ export default async function runScript({ const cwd = options?.cwd ?? root + if (options.clean) { + report.info( + `Cleaning up previous script target at ${kleur.blue(path.relative(root, options.clean))}` + ); + + await del([path.resolve(cwd, options.clean)]) + } + + report.info( `Running ${kleur.blue(options.run)} ` ); From a616c1a3faedd02ba69c013fe07ac0091feee8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Thu, 19 Dec 2024 13:23:30 +0300 Subject: [PATCH 03/67] feat: rename script target to custom --- .../react-native-builder-bob/src/index.ts | 1 - .../src/targets/script.ts | 59 ------------------- 2 files changed, 60 deletions(-) delete mode 100644 packages/react-native-builder-bob/src/targets/script.ts diff --git a/packages/react-native-builder-bob/src/index.ts b/packages/react-native-builder-bob/src/index.ts index c07191907..1f1a26a8b 100644 --- a/packages/react-native-builder-bob/src/index.ts +++ b/packages/react-native-builder-bob/src/index.ts @@ -13,7 +13,6 @@ import buildTypescript from './targets/typescript'; import buildCodegen from './targets/codegen'; import customTarget from './targets/custom'; import type { Options, Report, Target } from './types'; -import runScript from './targets/script'; type ArgName = 'target'; diff --git a/packages/react-native-builder-bob/src/targets/script.ts b/packages/react-native-builder-bob/src/targets/script.ts deleted file mode 100644 index cd05d128c..000000000 --- a/packages/react-native-builder-bob/src/targets/script.ts +++ /dev/null @@ -1,59 +0,0 @@ -import kleur from 'kleur'; -import path from 'path'; -import type { Input } from '../types'; -import { spawn } from '../utils/spawn'; -import dedent from 'dedent'; -import del from 'del'; - -type Options = Input & { - options?: { - run?: string; - cwd?: string; - clean?: string; - } -}; - -export default async function runScript({ - options, - root, - report -}: Options) { - if (options?.run === undefined) { - report.error( - dedent( - `No runnable provided with the script target. - Example: ${kleur.green('{["script", { run: "yarn generateTypes" }}')}` - ) - ) - process.exit(1) - } - - const [scriptBinary, ...scriptParams] = options.run.split(" "); - if (scriptBinary === undefined) { - report.error( - "No runnable provided with the script target." - ) - process.exit(1) - } - - const cwd = options?.cwd ?? root - - if (options.clean) { - report.info( - `Cleaning up previous script target at ${kleur.blue(path.relative(root, options.clean))}` - ); - - await del([path.resolve(cwd, options.clean)]) - } - - - report.info( - `Running ${kleur.blue(options.run)} ` - ); - - await spawn(scriptBinary, scriptParams, { - cwd, - }) - - report.success(`Ran ${kleur.blue(options.run)} succesfully`) -} From 0e41168c8410565d4aab27f0911b44f16e935c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 15:54:01 +0300 Subject: [PATCH 04/67] feat: add nitro option to cli --- .../create-react-native-library/src/input.ts | 100 ++++++++++-------- .../src/template.ts | 2 + 2 files changed, 55 insertions(+), 47 deletions(-) diff --git a/packages/create-react-native-library/src/input.ts b/packages/create-react-native-library/src/input.ts index 3e61e5426..00d303069 100644 --- a/packages/create-react-native-library/src/input.ts +++ b/packages/create-react-native-library/src/input.ts @@ -25,6 +25,7 @@ export type ProjectType = | 'fabric-view' | 'legacy-module' | 'legacy-view' + | 'nitro-module' | 'library'; const LANGUAGE_CHOICES: { @@ -32,27 +33,27 @@ const LANGUAGE_CHOICES: { value: ProjectLanguages; types: ProjectType[]; }[] = [ - { - title: 'Kotlin & Objective-C', - value: 'kotlin-objc', - types: ['turbo-module', 'fabric-view', 'legacy-module', 'legacy-view'], - }, - { - title: 'Kotlin & Swift', - value: 'kotlin-swift', - types: ['legacy-module', 'legacy-view'], - }, - { - title: 'C++ for Android & iOS', - value: 'cpp', - types: ['turbo-module', 'legacy-module'], - }, - { - title: 'JavaScript for Android, iOS & Web', - value: 'js', - types: ['library'], - }, -]; + { + title: 'Kotlin & Swift', + value: 'kotlin-swift', + types: ['nitro-module', 'legacy-module', 'legacy-view'], + }, + { + title: 'Kotlin & Objective-C', + value: 'kotlin-objc', + types: ['turbo-module', 'fabric-view', 'legacy-module', 'legacy-view'], + }, + { + title: 'C++ for Android & iOS', + value: 'cpp', + types: ['turbo-module', 'legacy-module'], + }, + { + title: 'JavaScript for Android, iOS & Web', + value: 'js', + types: ['library'], + }, + ]; const EXAMPLE_CHOICES = ( [ @@ -84,32 +85,37 @@ const TYPE_CHOICES: { value: ProjectType; description: string; }[] = [ - { - title: 'Turbo module', - value: 'turbo-module', - description: 'integration for native APIs to JS', - }, - { - title: 'Fabric view', - value: 'fabric-view', - description: 'integration for native views to JS', - }, - { - title: 'Legacy Native module', - value: 'legacy-module', - description: 'bridge for native APIs to JS (old architecture)', - }, - { - title: 'Legacy Native view', - value: 'legacy-view', - description: 'bridge for native views to JS (old architecture)', - }, - { - title: 'JavaScript library', - value: 'library', - description: 'supports Expo Go and Web', - }, -]; + { + title: 'Nitro module', + value: 'nitro-module', + description: 'nitro for faster modules', + }, + { + title: 'Turbo module', + value: 'turbo-module', + description: 'integration for native APIs to JS', + }, + { + title: 'Fabric view', + value: 'fabric-view', + description: 'integration for native views to JS', + }, + { + title: 'Legacy Native module', + value: 'legacy-module', + description: 'bridge for native APIs to JS (old architecture)', + }, + { + title: 'Legacy Native view', + value: 'legacy-view', + description: 'bridge for native views to JS (old architecture)', + }, + { + title: 'JavaScript library', + value: 'library', + description: 'supports Expo Go and Web', + }, + ]; export const acceptedArgs: Record = { slug: { diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index 946784e94..a13bcb5bc 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -18,6 +18,7 @@ export type TemplateConfiguration = { package_cpp: string; identifier: string; native: boolean; + nitro: boolean; arch: SupportedArchitecture; cpp: boolean; swift: boolean; @@ -143,6 +144,7 @@ export function generateTemplateConfiguration({ package_cpp: pack.replace(/\./g, '_'), identifier: slug.replace(/[^a-z0-9]+/g, '-').replace(/^-/, ''), native: languages !== 'js', + nitro: type.startsWith('nitro'), arch, cpp: languages === 'cpp', swift: languages === 'kotlin-swift', From 789f79a8f45ce2272b73eb84e8a1e063b87df6ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 15:57:31 +0300 Subject: [PATCH 05/67] fix: don't print using undefined react native version --- packages/create-react-native-library/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index a9cdfa92a..b7cd28925 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -111,9 +111,9 @@ async function create(_argv: yargs.Arguments) { rootPackageJson.devDependencies = rootPackageJson.devDependencies ? { - ...rootPackageJson.devDependencies, - ...devDependencies, - } + ...rootPackageJson.devDependencies, + ...devDependencies, + } : devDependencies; } From cad25f0b0bb73a5e0d9fdd099a2536f9b8d64df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 22:59:56 +0300 Subject: [PATCH 06/67] feat: add new arch to nitro modules --- .../create-react-native-library/src/template.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index a13bcb5bc..296567272 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -134,11 +134,11 @@ export function generateTemplateConfiguration({ name: /^[A-Z]/.test(basename) && /^[a-z0-9]+$/i.test(basename) ? // If the project name is already in PascalCase, use it as-is - basename + basename : // Otherwise, convert it to PascalCase and remove any non-alphanumeric characters - `${project.charAt(0).toUpperCase()}${project - .replace(/[^a-z0-9](\w)/g, (_, $1) => $1.toUpperCase()) - .slice(1)}`, + `${project.charAt(0).toUpperCase()}${project + .replace(/[^a-z0-9](\w)/g, (_, $1) => $1.toUpperCase()) + .slice(1)}`, package: pack, package_dir: pack.replace(/\./g, '/'), package_cpp: pack.replace(/\./g, '_'), @@ -226,9 +226,8 @@ export async function applyTemplates( } } - const templateType = `${config.project.module ? 'module' : 'view'}_${ - config.project.arch - }` as const; + const templateType = `${config.project.module ? 'module' : 'view'}_${config.project.arch + }` as const; await applyTemplate(config, KOTLIN_FILES[templateType], folder); From 06f7984766af3e883af34f561fe7fde43c059fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 23:11:28 +0300 Subject: [PATCH 07/67] feat: apply the nitro template --- .../create-react-native-library/src/template.ts | 6 ++++++ .../templates/nitro-module/$nitro.json | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 packages/create-react-native-library/templates/nitro-module/$nitro.json diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index 296567272..f05d6bfb7 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -73,6 +73,7 @@ const NATIVE_FILES = { module_new: path.resolve(__dirname, '../templates/native-library-new'), view_legacy: path.resolve(__dirname, '../templates/native-view-legacy'), view_new: path.resolve(__dirname, '../templates/native-view-new'), + module_nitro: path.resolve(__dirname, '../templates/nitro-module'), } as const; const OBJC_FILES = { @@ -198,6 +199,11 @@ export async function applyTemplates( await applyTemplate(config, NATIVE_COMMON_EXAMPLE_FILES, folder); } + if (config.project.nitro) { + await applyTemplate(config, NATIVE_FILES['module_nitro'], folder); + return; + } + if (config.project.module) { await applyTemplate( config, diff --git a/packages/create-react-native-library/templates/nitro-module/$nitro.json b/packages/create-react-native-library/templates/nitro-module/$nitro.json new file mode 100644 index 000000000..001a8fd5b --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-module/$nitro.json @@ -0,0 +1,17 @@ +{ + "cxxNamespace": ["<%- project.package_cpp -%>"], + "ios": { + "iosModulename": "<%- project.identifier -%>" + }, + "android": { + "androidNamespace": ["<%- project.package -%>"], + "androidCxxLibName": "<%- project.package_cpp -%>" + }, + "autolinking": { + "<%- project.name -%>": { + "swift": "<%- project.name -%>", + "kotlin": "<%- project.name -%>" + } + }, + "ignorePaths": ["node_modules"] +} From 0efb509e161e2180d0caeb2fc3d1aab30205bc9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 23:25:44 +0300 Subject: [PATCH 08/67] feat: create index and nitro files --- .../templates/nitro-module/src/$index.ts | 28 +++++++++++++++++++ .../src/{%- project.name %}.nitro.ts | 5 ++++ 2 files changed, 33 insertions(+) create mode 100644 packages/create-react-native-library/templates/nitro-module/src/$index.ts create mode 100644 packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts diff --git a/packages/create-react-native-library/templates/nitro-module/src/$index.ts b/packages/create-react-native-library/templates/nitro-module/src/$index.ts new file mode 100644 index 000000000..d8fe05e3a --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-module/src/$index.ts @@ -0,0 +1,28 @@ +import { NitroModules } from 'react-native-nitro-modules'; +import { Platform } from 'react-native'; +import type { <%- project.name -%> } from './<%- project.name -%>.nitro'; + +const LINKING_ERROR = + `The package '<%- project.slug -%>' doesn't seem to be linked. Make sure: \n\n` + + Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + + '- You rebuilt the app after installing the package\n' + + '- You are not using Expo Go\n'; + +export const <%- project.name -%>HybridObject = + NitroModules.createHybridObject<<%- project.name -%>>('<%- project.name -%>'); + +const <%- project.name -%> = <%- project.name -%>HybridObject + ? <%- project.name -%>HybridObject + : new Proxy( + {}, + { + get() { + throw new Error(LINKING_ERROR); + }, + } + ); + +export function multiply(a: number, b: number): number { + return <%- project.name -%>.multiply(a, b); +} + diff --git a/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts b/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts new file mode 100644 index 000000000..577d40654 --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts @@ -0,0 +1,5 @@ +import type { HybridObject } from 'react-native-nitro-modules'; + +export interface <%- project.name -%> extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> { + multiply(a: number, b: number): number; +} From f6484a2720889c613801d898b1f842bc9f0649dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 23:29:52 +0300 Subject: [PATCH 09/67] feat: add required stuff to podspec --- .../native-common/{%- project.identifier %}.podspec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec b/packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec index 5ee275d4f..cdd38471e 100644 --- a/packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec +++ b/packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec @@ -24,6 +24,11 @@ Pod::Spec.new do |s| <% } else { -%> s.source_files = "ios/**/*.{h,m,mm}" <% } -%> +<% if (project.nitro) { -%> + + load 'nitrogen/generated/ios/CrnlNitro+autolinking.rb' + add_nitrogen_files(s) +<% } -%> # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79. From 80a0f338d2ce63612aad46252751a73f06194f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 23:38:50 +0300 Subject: [PATCH 10/67] feat: add cmakelist --- .../nitro-module/android/$CMakeLists.txt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 packages/create-react-native-library/templates/nitro-module/android/$CMakeLists.txt diff --git a/packages/create-react-native-library/templates/nitro-module/android/$CMakeLists.txt b/packages/create-react-native-library/templates/nitro-module/android/$CMakeLists.txt new file mode 100644 index 000000000..1fa9ed39d --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-module/android/$CMakeLists.txt @@ -0,0 +1,24 @@ +project(<%- project.package_cpp -%>) +cmake_minimum_required(VERSION 3.9.0) + +set(PACKAGE_NAME <%- project.package_cpp -%>) +set(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_CXX_STANDARD 20) + +# Define C++ library and add all sources +add_library(${PACKAGE_NAME} SHARED src/main/cpp/cpp-adapter.cpp) + +# Add Nitrogen specs :) +include(${CMAKE_SOURCE_DIR}/../nitrogen/generated/android/<%- project.package_cpp -%>+autolinking.cmake) + +# Set up local includes +include_directories("src/main/cpp" "../cpp") + +find_library(LOG_LIB log) + +# Link all libraries together +target_link_libraries( + ${PACKAGE_NAME} + ${LOG_LIB} + android # <-- Android core +) From 9fb5b5e5d274ee7b8c9253b1d2804be893a8d8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 23:43:13 +0300 Subject: [PATCH 11/67] feat: add cpp adapter --- .../nitro-module/android/src/main/cpp/$cpp-adapter.cpp | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/$cpp-adapter.cpp diff --git a/packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/$cpp-adapter.cpp b/packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/$cpp-adapter.cpp new file mode 100644 index 000000000..7c727ef95 --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/$cpp-adapter.cpp @@ -0,0 +1,6 @@ +#include +#include "<%- project.package_cpp -%>OnLoad.hpp" + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { + return margelo::nitro::<%- project.package -%>::initialize(vm); +} From ac53b275a4cb57e7b5a385ff6aab88c43d597f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 23:51:32 +0300 Subject: [PATCH 12/67] feat: don't add codegen with nitro --- .../templates/common/$package.json | 4 ++-- .../create-react-native-library/templates/common/package.json | 0 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 packages/create-react-native-library/templates/common/package.json diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index 5ae1e4432..158836994 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -172,7 +172,7 @@ "source": "src", "output": "lib", "targets": [ -<% if (project.arch === 'new') { -%> +<% if (project.arch === 'new' && !project.nitro) { -%> "codegen", <% } -%> [ @@ -194,7 +194,7 @@ } ] ] -<% if (project.arch === 'new') { -%> +<% if (project.arch === 'new' && !project.nitro) { -%> }, "codegenConfig": { "name": "RN<%- project.name -%><%- project.view ? 'View': '' -%>Spec", diff --git a/packages/create-react-native-library/templates/common/package.json b/packages/create-react-native-library/templates/common/package.json new file mode 100644 index 000000000..e69de29bb From 9b8d769ecd6180fdc6f018984e48b8c37a53afee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 29 Nov 2024 23:59:11 +0300 Subject: [PATCH 13/67] feat: don't add rnccli for nitro --- .../src/exampleApp/dependencies.ts | 6 +++--- packages/create-react-native-library/src/index.ts | 8 ++++---- .../templates/common/$package.json | 8 +++++++- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/create-react-native-library/src/exampleApp/dependencies.ts b/packages/create-react-native-library/src/exampleApp/dependencies.ts index dccb19a98..c6eab92fa 100644 --- a/packages/create-react-native-library/src/exampleApp/dependencies.ts +++ b/packages/create-react-native-library/src/exampleApp/dependencies.ts @@ -1,11 +1,11 @@ import assert from 'node:assert'; import path from 'path'; import fs from 'fs-extra'; -import type { ExampleApp } from '../input'; +import type { TemplateConfiguration } from '../template'; export async function getDependencyVersionsFromExampleApp( folder: string, - exampleAppType: ExampleApp + config: TemplateConfiguration ) { const examplePackageJson = await fs.readJSON( path.join(folder, 'example', 'package.json') @@ -27,7 +27,7 @@ export async function getDependencyVersionsFromExampleApp( 'react-native': reactNative, }; - if (exampleAppType === 'vanilla') { + if (config.example === 'vanilla' && !config.project.nitro) { // React Native doesn't provide the community CLI as a dependency. // We have to get read the version from the example app and put to the root package json const exampleCommunityCLIVersion = diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index b7cd28925..ca3ceda51 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -106,14 +106,14 @@ async function create(_argv: yargs.Arguments) { if (config.example !== 'none') { const { devDependencies } = await getDependencyVersionsFromExampleApp( folder, - config.example + config ); rootPackageJson.devDependencies = rootPackageJson.devDependencies ? { - ...rootPackageJson.devDependencies, - ...devDependencies, - } + ...rootPackageJson.devDependencies, + ...devDependencies, + } : devDependencies; } diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index 158836994..6d097eb87 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -23,6 +23,9 @@ "android", "ios", "cpp", +<% if (project.nitro) { -%> + "nitro", +<% } -%> "*.podspec", "react-native.config.js", "!ios/build", @@ -72,7 +75,7 @@ "devDependencies": { "@commitlint/config-conventional": "^17.0.2", "@evilmartians/lefthook": "^1.5.0", -<% if (example === 'vanilla') { -%> +<% if (example === 'vanilla' && !project.nitro) { -%> "@react-native-community/cli": "15.0.0-alpha.2", <% } -%> "@react-native/eslint-config": "^0.73.1", @@ -99,6 +102,9 @@ "@types/react": "^18.2.44" }, "peerDependencies": { +<% if (project.nitro) { -%> + "react-native-nitro-modules": "*", +<% } -%> "react": "*", "react-native": "*" }, From a6d0f52ab71307be489506c11fa3b6f7159ced80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 00:07:49 +0300 Subject: [PATCH 14/67] feat: add kotlin files --- .../{%- project.name %}.kt | 10 +++++++++ .../{%- project.name %}Package.kt | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt create mode 100644 packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}Package.kt diff --git a/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt new file mode 100644 index 000000000..67f48eb3b --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt @@ -0,0 +1,10 @@ +package com.margelo.nitro.<%- project.package %> + +class CrnlNitro : Hybrid<%- project.name %>Spec() { + override val memorySize: Long + get() = 0L + + override fun multiply(a: Double, b: Double): Double { + return a * b + } +} diff --git a/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}Package.kt b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}Package.kt new file mode 100644 index 000000000..cbc34152e --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}Package.kt @@ -0,0 +1,22 @@ +package com.margelo.nitro.<%- project.package %> + +import com.facebook.react.TurboReactPackage +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.module.model.ReactModuleInfoProvider + +class CrnlNitroPackage : TurboReactPackage() { + override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { + return null + } + + override fun getReactModuleInfoProvider(): ReactModuleInfoProvider { + return ReactModuleInfoProvider { HashMap() } + } + + companion object { + init { + System.loadLibrary("<%- project.name -%>") + } + } +} From 19297129cfd7da8beedd0b154a499c84ec26bf0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 00:16:27 +0300 Subject: [PATCH 15/67] feat: add swift code --- .../nitro-module/ios/{%- project.name %}.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift diff --git a/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift new file mode 100644 index 000000000..3c09b14a0 --- /dev/null +++ b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift @@ -0,0 +1,11 @@ +class <%- project.name -%>: Hybrid<%- project.name -%>Spec { + var hybridContext = margelo.nitro.HybridContext() + var memorySize: Int { + getSizeOf(self) + } + + func multiply(a: Double, b: Double) throws -> Double { + return a * b + } +} + From 87238917ebc03e2ba1ffa3c8e89344980a3c5061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 00:27:58 +0300 Subject: [PATCH 16/67] feat: make the necessary changes on build.gradle --- .../native-common/android/build.gradle | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/packages/create-react-native-library/templates/native-common/android/build.gradle b/packages/create-react-native-library/templates/native-common/android/build.gradle index ac8e1841c..d03b08155 100644 --- a/packages/create-react-native-library/templates/native-common/android/build.gradle +++ b/packages/create-react-native-library/templates/native-common/android/build.gradle @@ -28,6 +28,9 @@ def isNewArchitectureEnabled() { apply plugin: "com.android.library" apply plugin: "kotlin-android" +<% if (project.nitro) { -%> +apply from: '../nitrogen/generated/android/<%- project.name -%>+autolinking.gradle' +<% } -%> if (isNewArchitectureEnabled()) { apply plugin: "com.facebook.react" @@ -48,7 +51,11 @@ def supportsNamespace() { android { if (supportsNamespace()) { +<% if (project.nitro) { -%> + namespace "com.margelo.nitro.<%- project.package -%>" +<% } else { -%> namespace "com.<%- project.package -%>" +<% } -%> sourceSets { main { @@ -68,28 +75,61 @@ android { <% if (project.arch === "new") { -%> buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() <% } -%> +<% if (project.cpp || project.nitro) { -%> -<% if (project.cpp) { -%> externalNativeBuild { cmake { - cppFlags "-O2 -frtti -fexceptions -Wall -fstack-protector-all" + cppFlags "-frtti -fexceptions -Wall -fstack-protector-all" abiFilters (*reactNativeArchitectures()) + + buildTypes { + debug { + cppFlags "-O1 -g" + } + release { + cppFlags "-O2" + } + } } } <% } -%> } -<% if (project.cpp) { -%> +<% if (project.cpp || project.nitro) { -%> externalNativeBuild { cmake { path "CMakeLists.txt" } } + + packagingOptions { + excludes = [ + "META-INF", + "META-INF/**", + "**/libc++_shared.so", + "**/libfbjni.so", + "**/libjsi.so", + "**/libfolly_json.so", + "**/libfolly_runtime.so", + "**/libglog.so", + "**/libhermes.so", + "**/libhermes-executor-debug.so", + "**/libhermes_executor.so", + "**/libreactnative.so", + "**/libreactnativejni.so", + "**/libturbomodulejsijni.so", + "**/libreact_nativemodule_core.so", + "**/libjscexecutor.so" + ] + } <% } -%> <% if (project.arch === "new") { -%> buildFeatures { buildConfig true +<% if (project.nitro) { -%> + prefab true +<% } -%> } <% } -%> @@ -132,9 +172,13 @@ def kotlin_version = getExtOrDefault("kotlinVersion") dependencies { implementation "com.facebook.react:react-android" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" +<% if (project.nitro) { -%> + // Add a dependency on NitroModules + implementation project(":react-native-nitro-modules") +<% } -%> } -<% if (project.arch === "new") { -%> +<% if (project.arch === "new" && !project.nitro) { -%> if (isNewArchitectureEnabled()) { react { jsRootDir = file("../src/") From 4459982a9dfb89a80496df84d4e99f5c93cb2cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 00:31:28 +0300 Subject: [PATCH 17/67] feat: don't add codegen prebuild when we ship nitro --- packages/create-react-native-library/src/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index ca3ceda51..b8808963a 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -111,13 +111,13 @@ async function create(_argv: yargs.Arguments) { rootPackageJson.devDependencies = rootPackageJson.devDependencies ? { - ...rootPackageJson.devDependencies, - ...devDependencies, - } + ...rootPackageJson.devDependencies, + ...devDependencies, + } : devDependencies; } - if (config.example === 'vanilla' && config.project.arch === 'new') { + if (config.example === 'vanilla' && config.project.arch === 'new' && !config.project.nitro) { addCodegenBuildScript(folder); } From 7b87e0930ddd2537047fcf6ccd2e4cf9837c1daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:06:04 +0300 Subject: [PATCH 18/67] feat: add dependencies for nitro --- .../src/exampleApp/generateExampleApp.ts | 62 +++++++++---------- .../create-react-native-library/src/index.ts | 25 ++++++-- .../src/template.ts | 18 +++--- .../templates/common/$package.json | 8 ++- 4 files changed, 66 insertions(+), 47 deletions(-) diff --git a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts index 1fb4d76a1..1c00eb11b 100644 --- a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts +++ b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts @@ -3,7 +3,7 @@ import path from 'path'; import https from 'https'; import { spawn } from '../utils/spawn'; import sortObjectKeys from '../utils/sortObjectKeys'; -import type { ExampleApp } from '../input'; +import type { TemplateConfiguration } from '../template'; const FILES_TO_DELETE = [ '__tests__', @@ -42,25 +42,15 @@ const PACKAGES_TO_ADD_WEB = { }; export default async function generateExampleApp({ - type, - dest, - arch, - project, - bobVersion, + config, + destination, reactNativeVersion = 'latest', }: { - type: ExampleApp; - dest: string; - arch: 'new' | 'legacy'; - project: { - slug: string; - name: string; - package: string; - }; - bobVersion: string; + config: TemplateConfiguration; + destination: string; reactNativeVersion?: string; }) { - const directory = path.join(dest, 'example'); + const directory = path.join(destination, 'example'); // `npx --package react-native-test-app@latest init --name ${projectName}Example --destination example --version ${reactNativeVersion}` const testAppArgs = [ @@ -68,7 +58,7 @@ export default async function generateExampleApp({ `react-native-test-app@latest`, 'init', '--name', - `${project.name}Example`, + `${config.project.name}Example`, `--destination`, directory, ...(reactNativeVersion !== 'latest' @@ -84,9 +74,9 @@ export default async function generateExampleApp({ const vanillaArgs = [ `@react-native-community/cli`, 'init', - `${project.name}Example`, + `${config.project.name}Example`, '--package-name', - `${project.package}.example`, + `${config.project.package}.example`, '--directory', directory, '--version', @@ -107,7 +97,7 @@ export default async function generateExampleApp({ let args: string[] = []; - switch (type) { + switch (config.example) { case 'vanilla': args = vanillaArgs; break; @@ -131,7 +121,7 @@ export default async function generateExampleApp({ // Patch the example app's package.json const pkg = await fs.readJSON(path.join(directory, 'package.json')); - pkg.name = `${project.slug}-example`; + pkg.name = `${config.project.slug}-example`; // Remove Jest config for now delete pkg.jest; @@ -144,12 +134,12 @@ export default async function generateExampleApp({ const SCRIPTS_TO_ADD = { 'build:android': 'react-native build-android --extra-params "--no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a"', - 'build:ios': `react-native build-ios --scheme ${project.name}Example --mode Debug --extra-params "-sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO"`, + 'build:ios': `react-native build-ios --scheme ${config.project.name}Example --mode Debug --extra-params "-sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO"`, }; - if (type === 'vanilla') { + if (config.example === 'vanilla') { Object.assign(scripts, SCRIPTS_TO_ADD); - } else if (type === 'test-app') { + } else if (config.example === 'test-app') { // `react-native-test-app` doesn't bundle application by default in 'Release' mode and also `bundle` command doesn't create a directory. // `mkdist` script should be removed after stable React Native major contains this fix: https://github.com/facebook/react-native/pull/45182. @@ -173,9 +163,9 @@ export default async function generateExampleApp({ const app = await fs.readJSON(path.join(directory, 'app.json')); app.android = app.android || {}; - app.android.package = `${project.package}.example`; + app.android.package = `${config.project.package}.example`; app.ios = app.ios || {}; - app.ios.bundleIdentifier = `${project.package}.example`; + app.ios.bundleIdentifier = `${config.project.package}.example`; await fs.writeJSON(path.join(directory, 'app.json'), app, { spaces: 2, @@ -188,12 +178,19 @@ export default async function generateExampleApp({ }); const PACKAGES_TO_ADD_DEV = { - 'react-native-builder-bob': `^${bobVersion}`, + 'react-native-builder-bob': `^${config.versions.bob}`, }; + if (config.project.nitro) { + const packagesToAddNitro = { + 'react-native-nitro-modules': `^${config.versions.nitroModules}`, + }; + Object.assign(dependencies, packagesToAddNitro); + } + Object.assign(devDependencies, PACKAGES_TO_ADD_DEV); - if (type === 'expo') { + if (config.example === 'expo') { const sdkVersion = dependencies.expo.split('.')[0].replace(/[^\d]/, ''); let bundledNativeModules: Record; @@ -231,15 +228,16 @@ export default async function generateExampleApp({ const app = await fs.readJSON(path.join(directory, 'app.json')); app.expo.android = app.expo.android || {}; - app.expo.android.package = `${project.package}.example`; + app.expo.android.package = `${config.project.package}.example`; app.expo.ios = app.expo.ios || {}; - app.expo.ios.bundleIdentifier = `${project.package}.example`; + app.expo.ios.bundleIdentifier = `${config.project.package}.example`; await fs.writeJSON(path.join(directory, 'app.json'), app, { spaces: 2, }); } + // Sort the deps by name for (const field of ['dependencies', 'devDependencies']) { if (pkg[field]) { pkg[field] = sortObjectKeys(pkg[field]); @@ -250,7 +248,7 @@ export default async function generateExampleApp({ spaces: 2, }); - if (type !== 'expo') { + if (config.example !== 'expo') { let gradleProperties = await fs.readFile( path.join(directory, 'android', 'gradle.properties'), 'utf8' @@ -264,7 +262,7 @@ export default async function generateExampleApp({ ); // If the library is on new architecture, enable new arch for iOS and Android - if (arch === 'new') { + if (config.project.arch === 'new') { // iOS // Add ENV['RCT_NEW_ARCH_ENABLED'] = 1 on top of example/ios/Podfile const podfile = await fs.readFile( diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index b8808963a..cf200ae29 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -21,6 +21,8 @@ import { getDependencyVersionsFromExampleApp } from './exampleApp/dependencies'; import { printErrorHelp, printNextSteps, printUsedRNVersion } from './inform'; const FALLBACK_BOB_VERSION = '0.36.0'; +const FALLBACK_NITRO_MODULES_VERSION = '0.18.0'; +const FALLBACK_NITRO_CODEGEN_VERSION = '0.18.0'; yargs .command( @@ -47,6 +49,14 @@ async function create(_argv: yargs.Arguments) { const bobVersionPromise = resolveNpmPackageVersion( 'react-native-builder-bob', FALLBACK_BOB_VERSION + ) + const nitroModulesVersionPromise = resolveNpmPackageVersion( + "react-native-nitro-modules", + FALLBACK_NITRO_MODULES_VERSION + ); + const nitroCodegenVersionPromise = resolveNpmPackageVersion( + "nitro-codegen", + FALLBACK_NITRO_CODEGEN_VERSION ); const local = await promptLocalLibrary(argv); @@ -69,9 +79,15 @@ async function create(_argv: yargs.Arguments) { assertUserInput(questions, answers); const bobVersion = await bobVersionPromise; + const nitroModulesVersion = await nitroModulesVersionPromise; + const nitroCodegenVersion = await nitroCodegenVersionPromise; const config = generateTemplateConfiguration({ - bobVersion, + versions: { + bob: bobVersion, + nitroModules: nitroModulesVersion, + nitroCodegen: nitroCodegenVersion, + }, basename, answers, }); @@ -88,12 +104,9 @@ async function create(_argv: yargs.Arguments) { spinner.text = 'Generating example app'; await generateExampleApp({ - type: config.example, - dest: folder, - arch: config.project.arch, - project: config.project, - bobVersion, + destination: folder, reactNativeVersion: answers.reactNativeVersion, + config, }); } diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index f05d6bfb7..ae410b4ce 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -3,12 +3,16 @@ import fs from 'fs-extra'; import ejs from 'ejs'; import type { Answers, ExampleApp, SupportedArchitecture } from './input'; +export type TemplateVersions = { + bob: string; + nitroModules: string; + nitroCodegen: string; +}; + // Please think at least 5 times before introducing a new config key // You can just reuse the existing ones most of the time export type TemplateConfiguration = { - bob: { - version: string; - }; + versions: TemplateVersions; project: { slug: string; description: string; @@ -95,11 +99,11 @@ const SWIFT_FILES = { } as const; export function generateTemplateConfiguration({ - bobVersion, + versions, basename, answers, }: { - bobVersion: string; + versions: TemplateVersions; basename: string; answers: Answers; }): TemplateConfiguration { @@ -126,9 +130,7 @@ export function generateTemplateConfiguration({ .toLowerCase()}`; return { - bob: { - version: bobVersion, - }, + versions, project: { slug, description: answers.description, diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index 6d097eb87..0601e9fc5 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -88,10 +88,16 @@ "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.1", "jest": "^29.7.0", +<% if (project.nitro) { -%> + "nitro-codegen": "^<%- versions.nitroCodegen %>", +<% } -%> "prettier": "^3.0.3", "react": "17.0.2", "react-native": "0.73.0", - "react-native-builder-bob": "^<%- bob.version %>", + "react-native-builder-bob": "^<%- versions.bob %>", +<% if (project.nitro) { -%> + "react-native-nitro-modules": "^<%- versions.nitroModules %>", +<% } -%> "release-it": "^17.10.0", <% if (example !== 'expo') { -%> "turbo": "^1.10.7", From 3229eb2d73dff8a90d18bd8fc220f9555ec32328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:16:11 +0300 Subject: [PATCH 19/67] feat: add nitro to contributing --- .../templates/common/CONTRIBUTING.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/create-react-native-library/templates/common/CONTRIBUTING.md b/packages/create-react-native-library/templates/common/CONTRIBUTING.md index 656304dba..03e1819e6 100644 --- a/packages/create-react-native-library/templates/common/CONTRIBUTING.md +++ b/packages/create-react-native-library/templates/common/CONTRIBUTING.md @@ -22,6 +22,9 @@ yarn The [example app](/example/) demonstrates usage of the library. You need to run it to test any changes you make. It is configured to use the local version of the library, so any changes you make to the library's source code will be reflected in the example app. Changes to the library's JavaScript code will be reflected in the example app without a rebuild, but native code changes will require a rebuild of the example app. +<% if (project.nitro) { -%> +This project uses [Nitro Modules](https://nitro.margelo.com/). If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/docs). +<% } -%> <% if (project.native) { -%> If you want to use Android Studio or XCode to edit the native code, you can open the `example/android` or `example/ios` directories respectively in those editors. To edit the Objective-C or Swift files, open `example/ios/<%- project.name -%>Example.xcworkspace` in XCode and find the source files at `Pods > Development Pods > <%- project.slug -%>`. From 79ba42fc07fb045b923766ffe3d191cd15c26b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:25:53 +0300 Subject: [PATCH 20/67] feat: make swift vars public --- .../templates/nitro-module/ios/{%- project.name %}.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift index 3c09b14a0..7bb155d5e 100644 --- a/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift +++ b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift @@ -1,10 +1,10 @@ class <%- project.name -%>: Hybrid<%- project.name -%>Spec { - var hybridContext = margelo.nitro.HybridContext() - var memorySize: Int { + public var hybridContext = margelo.nitro.HybridContext() + public var memorySize: Int { getSizeOf(self) } - func multiply(a: Double, b: Double) throws -> Double { + public func multiply(a: Double, b: Double) throws -> Double { return a * b } } From 4c966b2cd17e96c7d4a59b3c58628884ecd81d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:26:06 +0300 Subject: [PATCH 21/67] feat: print nitro docs prompt --- packages/create-react-native-library/src/inform.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/create-react-native-library/src/inform.ts b/packages/create-react-native-library/src/inform.ts index e6c18318f..07e43f4bb 100644 --- a/packages/create-react-native-library/src/inform.ts +++ b/packages/create-react-native-library/src/inform.ts @@ -96,6 +96,16 @@ export async function printNextSteps( ) .join('\n')} + ${ + config.project.nitro + ? kleur.blue( + `Read the ${kleur.bold( + 'Nitro Modules' + )} docs at ${kleur.underline('https://nitro.margelo.com/docs')}` + ) + : '' + } + ${kleur.yellow( `See ${kleur.bold('CONTRIBUTING.md')} for more details. Good luck!` )} From f2f081e47354fd9770d93969263bc6a432b81533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:29:35 +0300 Subject: [PATCH 22/67] feat: json is the worst format ever --- .../templates/common/$package.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index 0601e9fc5..9f329c154 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -108,11 +108,13 @@ "@types/react": "^18.2.44" }, "peerDependencies": { -<% if (project.nitro) { -%> - "react-native-nitro-modules": "*", -<% } -%> "react": "*", +<% if (project.nitro) { -%> + "react-native": "*", + "react-native-nitro-modules": "*" +<% } else { -%> "react-native": "*" +<% } -%> }, <% if (example !== 'none') { -%> "workspaces": [ From dba62580b47a2f13d125775e5480b99a590bf9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:37:46 +0300 Subject: [PATCH 23/67] fix: nitro json expects an array --- packages/create-react-native-library/src/template.ts | 2 ++ .../templates/nitro-module/$nitro.json | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index ae410b4ce..fff409800 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -18,6 +18,7 @@ export type TemplateConfiguration = { description: string; name: string; package: string; + package_array: string; package_dir: string; package_cpp: string; identifier: string; @@ -143,6 +144,7 @@ export function generateTemplateConfiguration({ .replace(/[^a-z0-9](\w)/g, (_, $1) => $1.toUpperCase()) .slice(1)}`, package: pack, + package_array: JSON.stringify(pack.split('.')), package_dir: pack.replace(/\./g, '/'), package_cpp: pack.replace(/\./g, '_'), identifier: slug.replace(/[^a-z0-9]+/g, '-').replace(/^-/, ''), diff --git a/packages/create-react-native-library/templates/nitro-module/$nitro.json b/packages/create-react-native-library/templates/nitro-module/$nitro.json index 001a8fd5b..eba764e6b 100644 --- a/packages/create-react-native-library/templates/nitro-module/$nitro.json +++ b/packages/create-react-native-library/templates/nitro-module/$nitro.json @@ -1,10 +1,10 @@ { "cxxNamespace": ["<%- project.package_cpp -%>"], "ios": { - "iosModulename": "<%- project.identifier -%>" + "iosModuleName": "<%- project.name -%>" }, "android": { - "androidNamespace": ["<%- project.package -%>"], + "androidNamespace": <%- project.package_array -%>, "androidCxxLibName": "<%- project.package_cpp -%>" }, "autolinking": { From a353f39961b0cfb82f154296f04a35d08e569d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:41:53 +0300 Subject: [PATCH 24/67] fix: use correct podspec --- .../templates/native-common/{%- project.identifier %}.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec b/packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec index cdd38471e..330d32eb1 100644 --- a/packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec +++ b/packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec @@ -26,7 +26,7 @@ Pod::Spec.new do |s| <% } -%> <% if (project.nitro) { -%> - load 'nitrogen/generated/ios/CrnlNitro+autolinking.rb' + load 'nitrogen/generated/ios/<%- project.name -%>+autolinking.rb' add_nitrogen_files(s) <% } -%> From 6ab7ad8855a839343c245b8b5584fc862c99d928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:44:28 +0300 Subject: [PATCH 25/67] feat: add nitrogen script --- .../templates/common/$package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index 9f329c154..bc4b8e17c 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -51,7 +51,12 @@ <% } else { -%> "clean": "del-cli lib", <% } -%> +<% if (example !== 'expo') { -%> + "nitrogen": "nitro-codegen", + "prepare": "bob build && yarn nitrogen", +<% } else { -%> "prepare": "bob build", +<% } -%> "release": "release-it" }, "keywords": [ From 51367428f9f1e155846f213495f1f89cdbef1bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:48:05 +0300 Subject: [PATCH 26/67] fix: type problems --- .../templates/nitro-module/src/$index.ts | 5 ++--- .../templates/nitro-module/src/{%- project.name %}.nitro.ts | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/create-react-native-library/templates/nitro-module/src/$index.ts b/packages/create-react-native-library/templates/nitro-module/src/$index.ts index d8fe05e3a..b433fde58 100644 --- a/packages/create-react-native-library/templates/nitro-module/src/$index.ts +++ b/packages/create-react-native-library/templates/nitro-module/src/$index.ts @@ -13,16 +13,15 @@ export const <%- project.name -%>HybridObject = const <%- project.name -%> = <%- project.name -%>HybridObject ? <%- project.name -%>HybridObject - : new Proxy( + : (new Proxy( {}, { get() { throw new Error(LINKING_ERROR); }, } - ); + ) as <%- project.name -%>); export function multiply(a: number, b: number): number { return <%- project.name -%>.multiply(a, b); } - diff --git a/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts b/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts index 577d40654..46e2f7b31 100644 --- a/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts +++ b/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts @@ -1,5 +1,6 @@ import type { HybridObject } from 'react-native-nitro-modules'; -export interface <%- project.name -%> extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> { +export interface <%- project.name -%> + extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> { multiply(a: number, b: number): number; } From 824c61959eb38cc3929bd8f4a39c74868de1b24a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 01:57:38 +0300 Subject: [PATCH 27/67] fix: remove newline on swift file --- .../templates/nitro-module/ios/{%- project.name %}.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift index 7bb155d5e..4854d8142 100644 --- a/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift +++ b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift @@ -8,4 +8,3 @@ class <%- project.name -%>: Hybrid<%- project.name -%>Spec { return a * b } } - From 43a074dbce14beb677b0e8f2eb25cb3ac4d2fd1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 02:02:23 +0300 Subject: [PATCH 28/67] fix: use project name for pod name --- ...%}.podspec => {%- project.name %}.podspec} | 0 .../native-common/{- project.name }.podspec | 57 +++++++++++++++++++ 2 files changed, 57 insertions(+) rename packages/create-react-native-library/templates/native-common/{{%- project.identifier %}.podspec => {%- project.name %}.podspec} (100%) create mode 100644 packages/create-react-native-library/templates/native-common/{- project.name }.podspec diff --git a/packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec b/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec similarity index 100% rename from packages/create-react-native-library/templates/native-common/{%- project.identifier %}.podspec rename to packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec diff --git a/packages/create-react-native-library/templates/native-common/{- project.name }.podspec b/packages/create-react-native-library/templates/native-common/{- project.name }.podspec new file mode 100644 index 000000000..6001f8e6c --- /dev/null +++ b/packages/create-react-native-library/templates/native-common/{- project.name }.podspec @@ -0,0 +1,57 @@ +require "json" + +package = JSON.parse(File.read(File.join(__dir__, "package.json"))) +folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' + +Pod::Spec.new do |s| + s.name = "<%- project.name -%>" + s.version = package["version"] + s.summary = package["description"] + s.homepage = package["homepage"] + s.license = package["license"] + s.authors = package["author"] + + s.platforms = { :ios => min_ios_version_supported } + s.source = { :git => "<%- repo -%>.git", :tag => "#{s.version}" } + +<% if (project.cpp) { -%> + s.source_files = "ios/**/*.{h,m,mm}", "cpp/**/*.{hpp,cpp,c,h}" +<% } else if (project.swift) { -%> + s.source_files = "ios/**/*.{h,m,mm,swift}" +<% } else if (project.arch !== "legacy") { -%> + s.source_files = "ios/**/*.{h,m,mm,cpp}" +<% } else { -%> + s.source_files = "ios/**/*.{h,m,mm}" +<% } -%> +<% if (project.nitro) { -%> + + load 'nitrogen/generated/ios/<%- project.name -%>+autolinking.rb' + add_nitrogen_files(s) +<% } -%> + + # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. + # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79. + if respond_to?(:install_modules_dependencies, true) + install_modules_dependencies(s) + else + s.dependency "React-Core" + + # Don't install the dependencies when we run `pod install` in the old architecture. + if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then + s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" + s.pod_target_xcconfig = { + "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", + "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", + "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" + } +<% if (project.view) { -%> + s.dependency "React-RCTFabric" +<% } -%> + s.dependency "React-Codegen" + s.dependency "RCT-Folly" + s.dependency "RCTRequired" + s.dependency "RCTTypeSafety" + s.dependency "ReactCommon/turbomodule/core" + end + end +end From 0d64a741746118bd805a81de01d6152c99f2513e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 02:09:05 +0300 Subject: [PATCH 29/67] fix: make index a tsx file --- .../templates/nitro-module/src/{$index.ts => $index.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/create-react-native-library/templates/nitro-module/src/{$index.ts => $index.tsx} (100%) diff --git a/packages/create-react-native-library/templates/nitro-module/src/$index.ts b/packages/create-react-native-library/templates/nitro-module/src/$index.tsx similarity index 100% rename from packages/create-react-native-library/templates/nitro-module/src/$index.ts rename to packages/create-react-native-library/templates/nitro-module/src/$index.tsx From b89a74e083deede17cb142329a1ee0791e40e24e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 02:12:36 +0300 Subject: [PATCH 30/67] fix: redundant podspec file --- .../native-common/{%- project.name %}.podspec | 2 +- .../native-common/{- project.name }.podspec | 57 ------------------- 2 files changed, 1 insertion(+), 58 deletions(-) delete mode 100644 packages/create-react-native-library/templates/native-common/{- project.name }.podspec diff --git a/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec b/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec index 330d32eb1..35e4feb8f 100644 --- a/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec +++ b/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec @@ -4,7 +4,7 @@ package = JSON.parse(File.read(File.join(__dir__, "package.json"))) folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' Pod::Spec.new do |s| - s.name = "<%- project.identifier -%>" + s.name = "<%- project.name -%>" s.version = package["version"] s.summary = package["description"] s.homepage = package["homepage"] diff --git a/packages/create-react-native-library/templates/native-common/{- project.name }.podspec b/packages/create-react-native-library/templates/native-common/{- project.name }.podspec deleted file mode 100644 index 6001f8e6c..000000000 --- a/packages/create-react-native-library/templates/native-common/{- project.name }.podspec +++ /dev/null @@ -1,57 +0,0 @@ -require "json" - -package = JSON.parse(File.read(File.join(__dir__, "package.json"))) -folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' - -Pod::Spec.new do |s| - s.name = "<%- project.name -%>" - s.version = package["version"] - s.summary = package["description"] - s.homepage = package["homepage"] - s.license = package["license"] - s.authors = package["author"] - - s.platforms = { :ios => min_ios_version_supported } - s.source = { :git => "<%- repo -%>.git", :tag => "#{s.version}" } - -<% if (project.cpp) { -%> - s.source_files = "ios/**/*.{h,m,mm}", "cpp/**/*.{hpp,cpp,c,h}" -<% } else if (project.swift) { -%> - s.source_files = "ios/**/*.{h,m,mm,swift}" -<% } else if (project.arch !== "legacy") { -%> - s.source_files = "ios/**/*.{h,m,mm,cpp}" -<% } else { -%> - s.source_files = "ios/**/*.{h,m,mm}" -<% } -%> -<% if (project.nitro) { -%> - - load 'nitrogen/generated/ios/<%- project.name -%>+autolinking.rb' - add_nitrogen_files(s) -<% } -%> - - # Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0. - # See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79. - if respond_to?(:install_modules_dependencies, true) - install_modules_dependencies(s) - else - s.dependency "React-Core" - - # Don't install the dependencies when we run `pod install` in the old architecture. - if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then - s.compiler_flags = folly_compiler_flags + " -DRCT_NEW_ARCH_ENABLED=1" - s.pod_target_xcconfig = { - "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/boost\"", - "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", - "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" - } -<% if (project.view) { -%> - s.dependency "React-RCTFabric" -<% } -%> - s.dependency "React-Codegen" - s.dependency "RCT-Folly" - s.dependency "RCTRequired" - s.dependency "RCTTypeSafety" - s.dependency "ReactCommon/turbomodule/core" - end - end -end From 0cc42787712fcab33c627b1d28cb73637ae41eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 02:26:18 +0300 Subject: [PATCH 31/67] fix: use project package cpp for autolinking --- .../templates/native-common/android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-react-native-library/templates/native-common/android/build.gradle b/packages/create-react-native-library/templates/native-common/android/build.gradle index d03b08155..8afbeaa4d 100644 --- a/packages/create-react-native-library/templates/native-common/android/build.gradle +++ b/packages/create-react-native-library/templates/native-common/android/build.gradle @@ -29,7 +29,7 @@ def isNewArchitectureEnabled() { apply plugin: "com.android.library" apply plugin: "kotlin-android" <% if (project.nitro) { -%> -apply from: '../nitrogen/generated/android/<%- project.name -%>+autolinking.gradle' +apply from: '../nitrogen/generated/android/<%- project.package_cpp -%>+autolinking.gradle' <% } -%> if (isNewArchitectureEnabled()) { From 8f6b3a148e7c18f92dc1f8f7af5ba8a1312d0606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 02:31:56 +0300 Subject: [PATCH 32/67] fix: pass args to cmake --- .../templates/native-common/android/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/create-react-native-library/templates/native-common/android/build.gradle b/packages/create-react-native-library/templates/native-common/android/build.gradle index 8afbeaa4d..625082ed4 100644 --- a/packages/create-react-native-library/templates/native-common/android/build.gradle +++ b/packages/create-react-native-library/templates/native-common/android/build.gradle @@ -80,6 +80,7 @@ android { externalNativeBuild { cmake { cppFlags "-frtti -fexceptions -Wall -fstack-protector-all" + arguments "-DANDROID_STL=c++_shared" abiFilters (*reactNativeArchitectures()) buildTypes { From 8619de792290e725dc902850c613716ccc25eaef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sat, 30 Nov 2024 02:59:58 +0300 Subject: [PATCH 33/67] docs: add installation steps --- .../create-react-native-library/templates/common/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/create-react-native-library/templates/common/README.md b/packages/create-react-native-library/templates/common/README.md index 4fe83e1b3..bbcdaa831 100644 --- a/packages/create-react-native-library/templates/common/README.md +++ b/packages/create-react-native-library/templates/common/README.md @@ -4,9 +4,15 @@ ## Installation +<% if (project.nitro) { -%> +```sh +npm install <%- project.slug %> react-native-nitro-modules +``` +<% } else { -%> ```sh npm install <%- project.slug %> ``` +<% } -%> ## Usage From 7d7f5bc5174faf68a6b9fefa59d333c708116c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 6 Dec 2024 18:46:16 +0300 Subject: [PATCH 34/67] fix: move the autolinked package file to correct package --- .../{%- project.name %}Package.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/{margelo/nitro => }/{%- project.package_dir %}/{%- project.name %}Package.kt (77%) diff --git a/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}Package.kt b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt similarity index 77% rename from packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}Package.kt rename to packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt index cbc34152e..f832910bc 100644 --- a/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}Package.kt +++ b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/{%- project.package_dir %}/{%- project.name %}Package.kt @@ -1,11 +1,11 @@ -package com.margelo.nitro.<%- project.package %> +package com.<%- project.package %> import com.facebook.react.TurboReactPackage import com.facebook.react.bridge.NativeModule import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.module.model.ReactModuleInfoProvider -class CrnlNitroPackage : TurboReactPackage() { +class <%- project.name -%>Package : TurboReactPackage() { override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? { return null } @@ -16,7 +16,7 @@ class CrnlNitroPackage : TurboReactPackage() { companion object { init { - System.loadLibrary("<%- project.name -%>") + System.loadLibrary("<%- project.package_cpp -%>") } } } From 983a0ed9ea5cf39832c6f7825b87384f147a50e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 6 Dec 2024 19:16:40 +0300 Subject: [PATCH 35/67] chore: formatting --- .../create-react-native-library/src/index.ts | 12 +- .../create-react-native-library/src/input.ts | 104 +++++++++--------- .../src/template.ts | 13 ++- 3 files changed, 67 insertions(+), 62 deletions(-) diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index cf200ae29..0406dbd5c 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -124,13 +124,17 @@ async function create(_argv: yargs.Arguments) { rootPackageJson.devDependencies = rootPackageJson.devDependencies ? { - ...rootPackageJson.devDependencies, - ...devDependencies, - } + ...rootPackageJson.devDependencies, + ...devDependencies, + } : devDependencies; } - if (config.example === 'vanilla' && config.project.arch === 'new' && !config.project.nitro) { + if ( + config.example === 'vanilla' && + config.project.arch === 'new' && + !config.project.nitro + ) { addCodegenBuildScript(folder); } diff --git a/packages/create-react-native-library/src/input.ts b/packages/create-react-native-library/src/input.ts index 00d303069..2b3a64e37 100644 --- a/packages/create-react-native-library/src/input.ts +++ b/packages/create-react-native-library/src/input.ts @@ -33,27 +33,27 @@ const LANGUAGE_CHOICES: { value: ProjectLanguages; types: ProjectType[]; }[] = [ - { - title: 'Kotlin & Swift', - value: 'kotlin-swift', - types: ['nitro-module', 'legacy-module', 'legacy-view'], - }, - { - title: 'Kotlin & Objective-C', - value: 'kotlin-objc', - types: ['turbo-module', 'fabric-view', 'legacy-module', 'legacy-view'], - }, - { - title: 'C++ for Android & iOS', - value: 'cpp', - types: ['turbo-module', 'legacy-module'], - }, - { - title: 'JavaScript for Android, iOS & Web', - value: 'js', - types: ['library'], - }, - ]; + { + title: 'Kotlin & Swift', + value: 'kotlin-swift', + types: ['nitro-module', 'legacy-module', 'legacy-view'], + }, + { + title: 'Kotlin & Objective-C', + value: 'kotlin-objc', + types: ['turbo-module', 'fabric-view', 'legacy-module', 'legacy-view'], + }, + { + title: 'C++ for Android & iOS', + value: 'cpp', + types: ['turbo-module', 'legacy-module'], + }, + { + title: 'JavaScript for Android, iOS & Web', + value: 'js', + types: ['library'], + }, +]; const EXAMPLE_CHOICES = ( [ @@ -85,37 +85,37 @@ const TYPE_CHOICES: { value: ProjectType; description: string; }[] = [ - { - title: 'Nitro module', - value: 'nitro-module', - description: 'nitro for faster modules', - }, - { - title: 'Turbo module', - value: 'turbo-module', - description: 'integration for native APIs to JS', - }, - { - title: 'Fabric view', - value: 'fabric-view', - description: 'integration for native views to JS', - }, - { - title: 'Legacy Native module', - value: 'legacy-module', - description: 'bridge for native APIs to JS (old architecture)', - }, - { - title: 'Legacy Native view', - value: 'legacy-view', - description: 'bridge for native views to JS (old architecture)', - }, - { - title: 'JavaScript library', - value: 'library', - description: 'supports Expo Go and Web', - }, - ]; + { + title: 'Nitro module', + value: 'nitro-module', + description: 'nitro for faster modules', + }, + { + title: 'Turbo module', + value: 'turbo-module', + description: 'integration for native APIs to JS', + }, + { + title: 'Fabric view', + value: 'fabric-view', + description: 'integration for native views to JS', + }, + { + title: 'Legacy Native module', + value: 'legacy-module', + description: 'bridge for native APIs to JS (old architecture)', + }, + { + title: 'Legacy Native view', + value: 'legacy-view', + description: 'bridge for native views to JS (old architecture)', + }, + { + title: 'JavaScript library', + value: 'library', + description: 'supports Expo Go and Web', + }, +]; export const acceptedArgs: Record = { slug: { diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index fff409800..0b54069c7 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -138,11 +138,11 @@ export function generateTemplateConfiguration({ name: /^[A-Z]/.test(basename) && /^[a-z0-9]+$/i.test(basename) ? // If the project name is already in PascalCase, use it as-is - basename + basename : // Otherwise, convert it to PascalCase and remove any non-alphanumeric characters - `${project.charAt(0).toUpperCase()}${project - .replace(/[^a-z0-9](\w)/g, (_, $1) => $1.toUpperCase()) - .slice(1)}`, + `${project.charAt(0).toUpperCase()}${project + .replace(/[^a-z0-9](\w)/g, (_, $1) => $1.toUpperCase()) + .slice(1)}`, package: pack, package_array: JSON.stringify(pack.split('.')), package_dir: pack.replace(/\./g, '/'), @@ -236,8 +236,9 @@ export async function applyTemplates( } } - const templateType = `${config.project.module ? 'module' : 'view'}_${config.project.arch - }` as const; + const templateType = `${config.project.module ? 'module' : 'view'}_${ + config.project.arch + }` as const; await applyTemplate(config, KOTLIN_FILES[templateType], folder); From 47d8fcdfc829afbd28451730fa2e41241da4d196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 6 Dec 2024 19:19:04 +0300 Subject: [PATCH 36/67] fix: remove unnecessary package json --- .../create-react-native-library/templates/common/package.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 packages/create-react-native-library/templates/common/package.json diff --git a/packages/create-react-native-library/templates/common/package.json b/packages/create-react-native-library/templates/common/package.json deleted file mode 100644 index e69de29bb..000000000 From fe6a3973ec171c656c4d4f2388200c00d4f7272e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 6 Dec 2024 19:26:36 +0300 Subject: [PATCH 37/67] fix: better spacing --- packages/create-react-native-library/src/inform.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/create-react-native-library/src/inform.ts b/packages/create-react-native-library/src/inform.ts index 07e43f4bb..c146efc39 100644 --- a/packages/create-react-native-library/src/inform.ts +++ b/packages/create-react-native-library/src/inform.ts @@ -101,11 +101,11 @@ export async function printNextSteps( ? kleur.blue( `Read the ${kleur.bold( 'Nitro Modules' - )} docs at ${kleur.underline('https://nitro.margelo.com/docs')}` + )} docs at ${kleur.underline('https://nitro.margelo.com/docs')} + ` ) : '' } - ${kleur.yellow( `See ${kleur.bold('CONTRIBUTING.md')} for more details. Good luck!` )} From bcae200c10c8a90583d47fa36314245886e85de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 6 Dec 2024 19:38:35 +0300 Subject: [PATCH 38/67] fix: correct the nitro paths --- .../templates/common/$package.json | 8 +++---- .../templates/nitro-module/src/$index.tsx | 22 ++----------------- 2 files changed, 5 insertions(+), 25 deletions(-) diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index bc4b8e17c..4309afed7 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -24,7 +24,7 @@ "ios", "cpp", <% if (project.nitro) { -%> - "nitro", + "nitrogen", <% } -%> "*.podspec", "react-native.config.js", @@ -51,11 +51,9 @@ <% } else { -%> "clean": "del-cli lib", <% } -%> -<% if (example !== 'expo') { -%> - "nitrogen": "nitro-codegen", - "prepare": "bob build && yarn nitrogen", -<% } else { -%> "prepare": "bob build", +<% if (project.nitro) { -%> + "nitrogen": "nitro-codegen", <% } -%> "release": "release-it" }, diff --git a/packages/create-react-native-library/templates/nitro-module/src/$index.tsx b/packages/create-react-native-library/templates/nitro-module/src/$index.tsx index b433fde58..fb7633d49 100644 --- a/packages/create-react-native-library/templates/nitro-module/src/$index.tsx +++ b/packages/create-react-native-library/templates/nitro-module/src/$index.tsx @@ -1,27 +1,9 @@ import { NitroModules } from 'react-native-nitro-modules'; -import { Platform } from 'react-native'; import type { <%- project.name -%> } from './<%- project.name -%>.nitro'; -const LINKING_ERROR = - `The package '<%- project.slug -%>' doesn't seem to be linked. Make sure: \n\n` + - Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + - '- You rebuilt the app after installing the package\n' + - '- You are not using Expo Go\n'; - -export const <%- project.name -%>HybridObject = +const <%- project.name -%>HybridObject = NitroModules.createHybridObject<<%- project.name -%>>('<%- project.name -%>'); -const <%- project.name -%> = <%- project.name -%>HybridObject - ? <%- project.name -%>HybridObject - : (new Proxy( - {}, - { - get() { - throw new Error(LINKING_ERROR); - }, - } - ) as <%- project.name -%>); - export function multiply(a: number, b: number): number { - return <%- project.name -%>.multiply(a, b); + return <%- project.name -%>HybridObject.multiply(a, b); } From 5f319f635d8021dfa0d924feabb461ebcee6142d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 6 Dec 2024 20:04:03 +0300 Subject: [PATCH 39/67] chore: add nitro to CI --- .github/workflows/build-templates.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/build-templates.yml b/.github/workflows/build-templates.yml index 4c5de8686..9bc2bb22e 100644 --- a/.github/workflows/build-templates.yml +++ b/.github/workflows/build-templates.yml @@ -34,6 +34,7 @@ jobs: - fabric-view - legacy-module - legacy-view + - nitro-module language: - kotlin-objc - kotlin-swift @@ -47,6 +48,10 @@ jobs: language: cpp - type: legacy-view language: cpp + - type: nitro-module + language: kotlin-objc + - type: nitro-module + language: cpp include: - os: ubuntu type: library @@ -216,6 +221,11 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- + - name: Run nitro codegen + if: matrix.type == 'nitro-module' + run: | + yarn nitrogen + - name: Build example (Android) env: JAVA_OPTS: "-XX:MaxHeapSize=6g" From 15e4ec0dada474c1bf3ca23dd28d6f14a7e30129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20G=C3=BCner?= Date: Fri, 6 Dec 2024 20:20:55 +0300 Subject: [PATCH 40/67] Update packages/create-react-native-library/templates/common/CONTRIBUTING.md Co-authored-by: Marc Rousavy --- .../templates/common/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-react-native-library/templates/common/CONTRIBUTING.md b/packages/create-react-native-library/templates/common/CONTRIBUTING.md index 03e1819e6..f4b80bd9e 100644 --- a/packages/create-react-native-library/templates/common/CONTRIBUTING.md +++ b/packages/create-react-native-library/templates/common/CONTRIBUTING.md @@ -23,7 +23,7 @@ The [example app](/example/) demonstrates usage of the library. You need to run It is configured to use the local version of the library, so any changes you make to the library's source code will be reflected in the example app. Changes to the library's JavaScript code will be reflected in the example app without a rebuild, but native code changes will require a rebuild of the example app. <% if (project.nitro) { -%> -This project uses [Nitro Modules](https://nitro.margelo.com/). If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/docs). +This project uses [Nitro Modules](https://nitro.margelo.com/). If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/). <% } -%> <% if (project.native) { -%> From b89fd91d9c93cc60c5dfe3de3fca7f6d7a61b8cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20G=C3=BCner?= Date: Fri, 6 Dec 2024 20:22:26 +0300 Subject: [PATCH 41/67] Update packages/create-react-native-library/src/inform.ts Co-authored-by: Marc Rousavy --- packages/create-react-native-library/src/inform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-react-native-library/src/inform.ts b/packages/create-react-native-library/src/inform.ts index c146efc39..38eb9386a 100644 --- a/packages/create-react-native-library/src/inform.ts +++ b/packages/create-react-native-library/src/inform.ts @@ -101,7 +101,7 @@ export async function printNextSteps( ? kleur.blue( `Read the ${kleur.bold( 'Nitro Modules' - )} docs at ${kleur.underline('https://nitro.margelo.com/docs')} + )} docs at ${kleur.underline('https://nitro.margelo.com')} ` ) : '' From e0590882e4aa5952d412b7ef23debd2b856021c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Mon, 16 Dec 2024 15:30:33 +0300 Subject: [PATCH 42/67] docs: update comment --- .../src/exampleApp/generateExampleApp.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts index 1c00eb11b..076051f7d 100644 --- a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts +++ b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts @@ -237,7 +237,8 @@ export default async function generateExampleApp({ }); } - // Sort the deps by name + // Sort the deps by name to match behavior of package managers + // This way the package.json doesn't get updated when installing deps for (const field of ['dependencies', 'devDependencies']) { if (pkg[field]) { pkg[field] = sortObjectKeys(pkg[field]); From 0067944ad2b59631206877f24b0e31cc45fa8ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Mon, 16 Dec 2024 15:32:04 +0300 Subject: [PATCH 43/67] feat: add newline with nitro --- .../create-react-native-library/templates/common/CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/create-react-native-library/templates/common/CONTRIBUTING.md b/packages/create-react-native-library/templates/common/CONTRIBUTING.md index f4b80bd9e..726ec490a 100644 --- a/packages/create-react-native-library/templates/common/CONTRIBUTING.md +++ b/packages/create-react-native-library/templates/common/CONTRIBUTING.md @@ -23,6 +23,7 @@ The [example app](/example/) demonstrates usage of the library. You need to run It is configured to use the local version of the library, so any changes you make to the library's source code will be reflected in the example app. Changes to the library's JavaScript code will be reflected in the example app without a rebuild, but native code changes will require a rebuild of the example app. <% if (project.nitro) { -%> + This project uses [Nitro Modules](https://nitro.margelo.com/). If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/). <% } -%> From 36fffd7e2baed14eef0d20c3fd0c95fa7613bf6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Mon, 16 Dec 2024 15:33:58 +0300 Subject: [PATCH 44/67] feat: don't mention the nitro docs when user creates a lib --- packages/create-react-native-library/src/inform.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/create-react-native-library/src/inform.ts b/packages/create-react-native-library/src/inform.ts index 38eb9386a..e6c18318f 100644 --- a/packages/create-react-native-library/src/inform.ts +++ b/packages/create-react-native-library/src/inform.ts @@ -96,16 +96,6 @@ export async function printNextSteps( ) .join('\n')} - ${ - config.project.nitro - ? kleur.blue( - `Read the ${kleur.bold( - 'Nitro Modules' - )} docs at ${kleur.underline('https://nitro.margelo.com')} - ` - ) - : '' - } ${kleur.yellow( `See ${kleur.bold('CONTRIBUTING.md')} for more details. Good luck!` )} From 7cc2ee385465505d16de21f32611c106d1f405c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Mon, 16 Dec 2024 15:34:48 +0300 Subject: [PATCH 45/67] chore: remove unnecessary $ from file names --- .../nitro-module/android/{$CMakeLists.txt => CMakeLists.txt} | 0 .../android/src/main/cpp/{$cpp-adapter.cpp => cpp-adapter.cpp} | 0 .../templates/nitro-module/{$nitro.json => nitro.json} | 0 .../templates/nitro-module/src/{$index.tsx => index.tsx} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename packages/create-react-native-library/templates/nitro-module/android/{$CMakeLists.txt => CMakeLists.txt} (100%) rename packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/{$cpp-adapter.cpp => cpp-adapter.cpp} (100%) rename packages/create-react-native-library/templates/nitro-module/{$nitro.json => nitro.json} (100%) rename packages/create-react-native-library/templates/nitro-module/src/{$index.tsx => index.tsx} (100%) diff --git a/packages/create-react-native-library/templates/nitro-module/android/$CMakeLists.txt b/packages/create-react-native-library/templates/nitro-module/android/CMakeLists.txt similarity index 100% rename from packages/create-react-native-library/templates/nitro-module/android/$CMakeLists.txt rename to packages/create-react-native-library/templates/nitro-module/android/CMakeLists.txt diff --git a/packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/$cpp-adapter.cpp b/packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/cpp-adapter.cpp similarity index 100% rename from packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/$cpp-adapter.cpp rename to packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/cpp-adapter.cpp diff --git a/packages/create-react-native-library/templates/nitro-module/$nitro.json b/packages/create-react-native-library/templates/nitro-module/nitro.json similarity index 100% rename from packages/create-react-native-library/templates/nitro-module/$nitro.json rename to packages/create-react-native-library/templates/nitro-module/nitro.json diff --git a/packages/create-react-native-library/templates/nitro-module/src/$index.tsx b/packages/create-react-native-library/templates/nitro-module/src/index.tsx similarity index 100% rename from packages/create-react-native-library/templates/nitro-module/src/$index.tsx rename to packages/create-react-native-library/templates/nitro-module/src/index.tsx From c199ec3e47ad82a0c47cb2913e3510a0f9d576ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Mon, 16 Dec 2024 15:47:48 +0300 Subject: [PATCH 46/67] feat: explain why nitro modules are needed as a dependency --- packages/create-react-native-library/templates/common/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/create-react-native-library/templates/common/README.md b/packages/create-react-native-library/templates/common/README.md index bbcdaa831..0b7a4329b 100644 --- a/packages/create-react-native-library/templates/common/README.md +++ b/packages/create-react-native-library/templates/common/README.md @@ -7,6 +7,8 @@ <% if (project.nitro) { -%> ```sh npm install <%- project.slug %> react-native-nitro-modules + +> `react-native-nitro-modules` is required as this library relies on [Nitro Modules](https://nitro.margelo.com/). ``` <% } else { -%> ```sh From 8075719dc1aa72b1c28f432ddaf954418de4c3d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Mon, 16 Dec 2024 17:04:59 +0300 Subject: [PATCH 47/67] feat: change nitro description --- .../create-react-native-library/src/input.ts | 104 +++++++++--------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/packages/create-react-native-library/src/input.ts b/packages/create-react-native-library/src/input.ts index 2b3a64e37..e4a484daa 100644 --- a/packages/create-react-native-library/src/input.ts +++ b/packages/create-react-native-library/src/input.ts @@ -33,27 +33,27 @@ const LANGUAGE_CHOICES: { value: ProjectLanguages; types: ProjectType[]; }[] = [ - { - title: 'Kotlin & Swift', - value: 'kotlin-swift', - types: ['nitro-module', 'legacy-module', 'legacy-view'], - }, - { - title: 'Kotlin & Objective-C', - value: 'kotlin-objc', - types: ['turbo-module', 'fabric-view', 'legacy-module', 'legacy-view'], - }, - { - title: 'C++ for Android & iOS', - value: 'cpp', - types: ['turbo-module', 'legacy-module'], - }, - { - title: 'JavaScript for Android, iOS & Web', - value: 'js', - types: ['library'], - }, -]; + { + title: 'Kotlin & Swift', + value: 'kotlin-swift', + types: ['nitro-module', 'legacy-module', 'legacy-view'], + }, + { + title: 'Kotlin & Objective-C', + value: 'kotlin-objc', + types: ['turbo-module', 'fabric-view', 'legacy-module', 'legacy-view'], + }, + { + title: 'C++ for Android & iOS', + value: 'cpp', + types: ['turbo-module', 'legacy-module'], + }, + { + title: 'JavaScript for Android, iOS & Web', + value: 'js', + types: ['library'], + }, + ]; const EXAMPLE_CHOICES = ( [ @@ -85,37 +85,37 @@ const TYPE_CHOICES: { value: ProjectType; description: string; }[] = [ - { - title: 'Nitro module', - value: 'nitro-module', - description: 'nitro for faster modules', - }, - { - title: 'Turbo module', - value: 'turbo-module', - description: 'integration for native APIs to JS', - }, - { - title: 'Fabric view', - value: 'fabric-view', - description: 'integration for native views to JS', - }, - { - title: 'Legacy Native module', - value: 'legacy-module', - description: 'bridge for native APIs to JS (old architecture)', - }, - { - title: 'Legacy Native view', - value: 'legacy-view', - description: 'bridge for native views to JS (old architecture)', - }, - { - title: 'JavaScript library', - value: 'library', - description: 'supports Expo Go and Web', - }, -]; + { + title: 'Nitro module', + value: 'nitro-module', + description: 'type-safe and fast integration for native APIs to JS', + }, + { + title: 'Turbo module', + value: 'turbo-module', + description: 'integration for native APIs to JS', + }, + { + title: 'Fabric view', + value: 'fabric-view', + description: 'integration for native views to JS', + }, + { + title: 'Legacy Native module', + value: 'legacy-module', + description: 'bridge for native APIs to JS (old architecture)', + }, + { + title: 'Legacy Native view', + value: 'legacy-view', + description: 'bridge for native views to JS (old architecture)', + }, + { + title: 'JavaScript library', + value: 'library', + description: 'supports Expo Go and Web', + }, + ]; export const acceptedArgs: Record = { slug: { From 0ce079e0859b862e884de6446d8f7af3500e1fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Mon, 16 Dec 2024 18:29:14 +0300 Subject: [PATCH 48/67] refactor: remove package_array --- packages/create-react-native-library/src/template.ts | 2 -- .../templates/nitro-module/nitro.json | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index 0b54069c7..afc20b907 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -18,7 +18,6 @@ export type TemplateConfiguration = { description: string; name: string; package: string; - package_array: string; package_dir: string; package_cpp: string; identifier: string; @@ -144,7 +143,6 @@ export function generateTemplateConfiguration({ .replace(/[^a-z0-9](\w)/g, (_, $1) => $1.toUpperCase()) .slice(1)}`, package: pack, - package_array: JSON.stringify(pack.split('.')), package_dir: pack.replace(/\./g, '/'), package_cpp: pack.replace(/\./g, '_'), identifier: slug.replace(/[^a-z0-9]+/g, '-').replace(/^-/, ''), diff --git a/packages/create-react-native-library/templates/nitro-module/nitro.json b/packages/create-react-native-library/templates/nitro-module/nitro.json index eba764e6b..8a1674a36 100644 --- a/packages/create-react-native-library/templates/nitro-module/nitro.json +++ b/packages/create-react-native-library/templates/nitro-module/nitro.json @@ -4,7 +4,7 @@ "iosModuleName": "<%- project.name -%>" }, "android": { - "androidNamespace": <%- project.package_array -%>, + "androidNamespace": <%- JSON.stringify(project.package.split('.')) -%>, "androidCxxLibName": "<%- project.package_cpp -%>" }, "autolinking": { From 0caf3e13a0a4415874c5aba0e10b427de486408c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Mon, 16 Dec 2024 18:42:47 +0300 Subject: [PATCH 49/67] feat: remove unnecessary comment --- .../templates/native-common/android/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/create-react-native-library/templates/native-common/android/build.gradle b/packages/create-react-native-library/templates/native-common/android/build.gradle index 625082ed4..12ba36fdc 100644 --- a/packages/create-react-native-library/templates/native-common/android/build.gradle +++ b/packages/create-react-native-library/templates/native-common/android/build.gradle @@ -174,7 +174,6 @@ dependencies { implementation "com.facebook.react:react-android" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" <% if (project.nitro) { -%> - // Add a dependency on NitroModules implementation project(":react-native-nitro-modules") <% } -%> } From 40b86080f09c5844f1cfac24a65bd872d9020326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Tue, 17 Dec 2024 00:55:49 +0300 Subject: [PATCH 50/67] refactor: introduce viewConfig and moduleConfig --- .../src/exampleApp/dependencies.ts | 6 +- .../src/exampleApp/generateExampleApp.ts | 2 +- .../create-react-native-library/src/index.ts | 10 +- .../create-react-native-library/src/input.ts | 104 +++++++++--------- .../src/template.ts | 63 ++++++++--- .../templates/common-local/$package.json | 4 +- .../templates/common/$package.json | 20 ++-- .../templates/common/CONTRIBUTING.md | 2 +- .../templates/common/README.md | 6 +- .../native-common/android/build.gradle | 16 +-- .../native-common/{%- project.name %}.podspec | 4 +- 11 files changed, 138 insertions(+), 99 deletions(-) diff --git a/packages/create-react-native-library/src/exampleApp/dependencies.ts b/packages/create-react-native-library/src/exampleApp/dependencies.ts index c6eab92fa..64552e278 100644 --- a/packages/create-react-native-library/src/exampleApp/dependencies.ts +++ b/packages/create-react-native-library/src/exampleApp/dependencies.ts @@ -27,7 +27,11 @@ export async function getDependencyVersionsFromExampleApp( 'react-native': reactNative, }; - if (config.example === 'vanilla' && !config.project.nitro) { + if ( + config.example === 'vanilla' && + (config.project.moduleConfig === 'turbo-modules' || + config.project.viewConfig === 'fabric-view') + ) { // React Native doesn't provide the community CLI as a dependency. // We have to get read the version from the example app and put to the root package json const exampleCommunityCLIVersion = diff --git a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts index 076051f7d..e998f2dfc 100644 --- a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts +++ b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts @@ -181,7 +181,7 @@ export default async function generateExampleApp({ 'react-native-builder-bob': `^${config.versions.bob}`, }; - if (config.project.nitro) { + if (config.project.moduleConfig === 'nitro-modules') { const packagesToAddNitro = { 'react-native-nitro-modules': `^${config.versions.nitroModules}`, }; diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index 0406dbd5c..58c3741fa 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -49,13 +49,13 @@ async function create(_argv: yargs.Arguments) { const bobVersionPromise = resolveNpmPackageVersion( 'react-native-builder-bob', FALLBACK_BOB_VERSION - ) + ); const nitroModulesVersionPromise = resolveNpmPackageVersion( - "react-native-nitro-modules", + 'react-native-nitro-modules', FALLBACK_NITRO_MODULES_VERSION ); const nitroCodegenVersionPromise = resolveNpmPackageVersion( - "nitro-codegen", + 'nitro-codegen', FALLBACK_NITRO_CODEGEN_VERSION ); @@ -132,8 +132,8 @@ async function create(_argv: yargs.Arguments) { if ( config.example === 'vanilla' && - config.project.arch === 'new' && - !config.project.nitro + (config.project.moduleConfig === 'turbo-modules' || + config.project.viewConfig === 'fabric-view') ) { addCodegenBuildScript(folder); } diff --git a/packages/create-react-native-library/src/input.ts b/packages/create-react-native-library/src/input.ts index e4a484daa..ce1417126 100644 --- a/packages/create-react-native-library/src/input.ts +++ b/packages/create-react-native-library/src/input.ts @@ -33,27 +33,27 @@ const LANGUAGE_CHOICES: { value: ProjectLanguages; types: ProjectType[]; }[] = [ - { - title: 'Kotlin & Swift', - value: 'kotlin-swift', - types: ['nitro-module', 'legacy-module', 'legacy-view'], - }, - { - title: 'Kotlin & Objective-C', - value: 'kotlin-objc', - types: ['turbo-module', 'fabric-view', 'legacy-module', 'legacy-view'], - }, - { - title: 'C++ for Android & iOS', - value: 'cpp', - types: ['turbo-module', 'legacy-module'], - }, - { - title: 'JavaScript for Android, iOS & Web', - value: 'js', - types: ['library'], - }, - ]; + { + title: 'Kotlin & Swift', + value: 'kotlin-swift', + types: ['nitro-module', 'legacy-module', 'legacy-view'], + }, + { + title: 'Kotlin & Objective-C', + value: 'kotlin-objc', + types: ['turbo-module', 'fabric-view', 'legacy-module', 'legacy-view'], + }, + { + title: 'C++ for Android & iOS', + value: 'cpp', + types: ['turbo-module', 'legacy-module'], + }, + { + title: 'JavaScript for Android, iOS & Web', + value: 'js', + types: ['library'], + }, +]; const EXAMPLE_CHOICES = ( [ @@ -85,37 +85,37 @@ const TYPE_CHOICES: { value: ProjectType; description: string; }[] = [ - { - title: 'Nitro module', - value: 'nitro-module', - description: 'type-safe and fast integration for native APIs to JS', - }, - { - title: 'Turbo module', - value: 'turbo-module', - description: 'integration for native APIs to JS', - }, - { - title: 'Fabric view', - value: 'fabric-view', - description: 'integration for native views to JS', - }, - { - title: 'Legacy Native module', - value: 'legacy-module', - description: 'bridge for native APIs to JS (old architecture)', - }, - { - title: 'Legacy Native view', - value: 'legacy-view', - description: 'bridge for native views to JS (old architecture)', - }, - { - title: 'JavaScript library', - value: 'library', - description: 'supports Expo Go and Web', - }, - ]; + { + title: 'Nitro module', + value: 'nitro-module', + description: 'type-safe and fast integration for native APIs to JS', + }, + { + title: 'Turbo module', + value: 'turbo-module', + description: 'integration for native APIs to JS', + }, + { + title: 'Fabric view', + value: 'fabric-view', + description: 'integration for native views to JS', + }, + { + title: 'Legacy Native module', + value: 'legacy-module', + description: 'bridge for native APIs to JS (old architecture)', + }, + { + title: 'Legacy Native view', + value: 'legacy-view', + description: 'bridge for native views to JS (old architecture)', + }, + { + title: 'JavaScript library', + value: 'library', + description: 'supports Expo Go and Web', + }, +]; export const acceptedArgs: Record = { slug: { diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index afc20b907..a0bed8c42 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -1,7 +1,12 @@ import path from 'path'; import fs from 'fs-extra'; import ejs from 'ejs'; -import type { Answers, ExampleApp, SupportedArchitecture } from './input'; +import type { + Answers, + ExampleApp, + ProjectType, + SupportedArchitecture, +} from './input'; export type TemplateVersions = { bob: string; @@ -9,6 +14,14 @@ export type TemplateVersions = { nitroCodegen: string; }; +export type ModuleConfig = + | 'native-modules' + | 'turbo-modules' + | 'nitro-modules' + | null; + +export type ViewConfig = 'paper-view' | 'fabric-view' | null; + // Please think at least 5 times before introducing a new config key // You can just reuse the existing ones most of the time export type TemplateConfiguration = { @@ -22,12 +35,11 @@ export type TemplateConfiguration = { package_cpp: string; identifier: string; native: boolean; - nitro: boolean; arch: SupportedArchitecture; cpp: boolean; swift: boolean; - view: boolean; - module: boolean; + viewConfig: ViewConfig; + moduleConfig: ModuleConfig; }; author: { name: string; @@ -147,12 +159,11 @@ export function generateTemplateConfiguration({ package_cpp: pack.replace(/\./g, '_'), identifier: slug.replace(/[^a-z0-9]+/g, '-').replace(/^-/, ''), native: languages !== 'js', - nitro: type.startsWith('nitro'), arch, cpp: languages === 'cpp', swift: languages === 'kotlin-swift', - view: answers.type.endsWith('-view'), - module: answers.type.endsWith('-module'), + viewConfig: getViewConfig(type), + moduleConfig: getModuleConfig(type), }, author: { name: answers.authorName, @@ -165,6 +176,30 @@ export function generateTemplateConfiguration({ }; } +function getModuleConfig(projectType: ProjectType): ModuleConfig { + switch (projectType) { + case 'nitro-module': + return 'nitro-modules'; + case 'turbo-module': + return 'turbo-modules'; + case 'legacy-module': + return 'native-modules'; + default: + return null; + } +} + +function getViewConfig(projectType: ProjectType): ViewConfig { + switch (projectType) { + case 'legacy-view': + return 'paper-view'; + case 'fabric-view': + return 'fabric-view'; + default: + return null; + } +} + export async function applyTemplates( answers: Answers, config: TemplateConfiguration, @@ -179,7 +214,7 @@ export async function applyTemplates( if (config.example !== 'none') { await applyTemplate(config, EXAMPLE_COMMON_FILES, folder); - if (config.project.view) { + if (config.project.viewConfig !== null) { await applyTemplate(config, EXAMPLE_VIEW_FILES, folder); } else { if (config.project.arch === 'legacy') { @@ -201,12 +236,12 @@ export async function applyTemplates( await applyTemplate(config, NATIVE_COMMON_EXAMPLE_FILES, folder); } - if (config.project.nitro) { + if (config.project.moduleConfig === 'nitro-modules') { await applyTemplate(config, NATIVE_FILES['module_nitro'], folder); return; } - if (config.project.module) { + if (config.project.moduleConfig !== null) { await applyTemplate( config, NATIVE_FILES[`module_${config.project.arch}`], @@ -223,7 +258,7 @@ export async function applyTemplates( if (config.project.swift) { await applyTemplate(config, SWIFT_FILES[`module_legacy`], folder); } else { - if (config.project.module) { + if (config.project.moduleConfig !== null) { await applyTemplate(config, OBJC_FILES[`module_common`], folder); } else { await applyTemplate( @@ -234,9 +269,9 @@ export async function applyTemplates( } } - const templateType = `${config.project.module ? 'module' : 'view'}_${ - config.project.arch - }` as const; + const templateType = `${ + config.project.moduleConfig !== null ? 'module' : 'view' + }_${config.project.arch}` as const; await applyTemplate(config, KOTLIN_FILES[templateType], folder); diff --git a/packages/create-react-native-library/templates/common-local/$package.json b/packages/create-react-native-library/templates/common-local/$package.json index 5faf3f41c..71b873e99 100644 --- a/packages/create-react-native-library/templates/common-local/$package.json +++ b/packages/create-react-native-library/templates/common-local/$package.json @@ -5,8 +5,8 @@ "main": "src/index", <% if (project.arch === 'new') { -%> "codegenConfig": { - "name": "RN<%- project.name -%><%- project.view ? 'View': '' -%>Spec", - "type": <%- project.view ? '"all"': '"modules"' %>, + "name": "RN<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec", + "type": <%- project.viewConfig !== null ? '"components"': '"modules"' %>, "jsSrcsDir": "src" }, <% } -%> diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index 4309afed7..bc1b8686d 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -23,7 +23,7 @@ "android", "ios", "cpp", -<% if (project.nitro) { -%> +<% if (project.moduleConfig === "nitro-modules") { -%> "nitrogen", <% } -%> "*.podspec", @@ -52,7 +52,7 @@ "clean": "del-cli lib", <% } -%> "prepare": "bob build", -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> "nitrogen": "nitro-codegen", <% } -%> "release": "release-it" @@ -78,7 +78,7 @@ "devDependencies": { "@commitlint/config-conventional": "^17.0.2", "@evilmartians/lefthook": "^1.5.0", -<% if (example === 'vanilla' && !project.nitro) { -%> +<% if (example === 'vanilla' && (project.moduleConfig === 'turbo-modules' || project.viewConfig === 'fabric-view')) { -%> "@react-native-community/cli": "15.0.0-alpha.2", <% } -%> "@react-native/eslint-config": "^0.73.1", @@ -91,14 +91,14 @@ "eslint-config-prettier": "^9.0.0", "eslint-plugin-prettier": "^5.0.1", "jest": "^29.7.0", -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> "nitro-codegen": "^<%- versions.nitroCodegen %>", <% } -%> "prettier": "^3.0.3", "react": "17.0.2", "react-native": "0.73.0", "react-native-builder-bob": "^<%- versions.bob %>", -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> "react-native-nitro-modules": "^<%- versions.nitroModules %>", <% } -%> "release-it": "^17.10.0", @@ -112,7 +112,7 @@ }, "peerDependencies": { "react": "*", -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> "react-native": "*", "react-native-nitro-modules": "*" <% } else { -%> @@ -189,7 +189,7 @@ "source": "src", "output": "lib", "targets": [ -<% if (project.arch === 'new' && !project.nitro) { -%> +<% if (project.moduleConfig === 'turbo-modules' || project.viewConfig === 'fabric-view') { -%> "codegen", <% } -%> [ @@ -211,11 +211,11 @@ } ] ] -<% if (project.arch === 'new' && !project.nitro) { -%> +<% if (project.moduleConfig === 'turbo-modules' || project.viewConfig === 'fabric-view') { -%> }, "codegenConfig": { - "name": "RN<%- project.name -%><%- project.view ? 'View': '' -%>Spec", - "type": "<%- project.view ? 'all': 'modules' -%>", + "name": "RN<%- project.name -%><%- project.viewConfig !== null ? 'View': '' -%>Spec", + "type": "<%- project.viewConfig !== null ? 'components': 'modules' -%>", "jsSrcsDir": "src", "outputDir": { "ios": "ios/generated", diff --git a/packages/create-react-native-library/templates/common/CONTRIBUTING.md b/packages/create-react-native-library/templates/common/CONTRIBUTING.md index 726ec490a..5b1d46309 100644 --- a/packages/create-react-native-library/templates/common/CONTRIBUTING.md +++ b/packages/create-react-native-library/templates/common/CONTRIBUTING.md @@ -22,7 +22,7 @@ yarn The [example app](/example/) demonstrates usage of the library. You need to run it to test any changes you make. It is configured to use the local version of the library, so any changes you make to the library's source code will be reflected in the example app. Changes to the library's JavaScript code will be reflected in the example app without a rebuild, but native code changes will require a rebuild of the example app. -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> This project uses [Nitro Modules](https://nitro.margelo.com/). If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/). <% } -%> diff --git a/packages/create-react-native-library/templates/common/README.md b/packages/create-react-native-library/templates/common/README.md index 0b7a4329b..5b34c58f1 100644 --- a/packages/create-react-native-library/templates/common/README.md +++ b/packages/create-react-native-library/templates/common/README.md @@ -4,7 +4,7 @@ ## Installation -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> ```sh npm install <%- project.slug %> react-native-nitro-modules @@ -18,7 +18,7 @@ npm install <%- project.slug %> ## Usage -<% if (project.view) { -%> +<% if (project.viewConfig !== null) { -%> ```js import { <%- project.name -%>View } from "<%- project.slug -%>"; @@ -28,7 +28,7 @@ import { <%- project.name -%>View } from "<%- project.slug -%>"; <<%- project.name -%>View color="tomato" /> ``` -<% } else if (project.arch === 'new' && project.module) { -%> +<% } else if (project.moduleConfig === 'nitro-modules' || project.moduleConfig === 'turbo-modules') { -%> ```js import { multiply } from '<%- project.slug -%>'; diff --git a/packages/create-react-native-library/templates/native-common/android/build.gradle b/packages/create-react-native-library/templates/native-common/android/build.gradle index 12ba36fdc..eb067349d 100644 --- a/packages/create-react-native-library/templates/native-common/android/build.gradle +++ b/packages/create-react-native-library/templates/native-common/android/build.gradle @@ -28,7 +28,7 @@ def isNewArchitectureEnabled() { apply plugin: "com.android.library" apply plugin: "kotlin-android" -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> apply from: '../nitrogen/generated/android/<%- project.package_cpp -%>+autolinking.gradle' <% } -%> @@ -51,7 +51,7 @@ def supportsNamespace() { android { if (supportsNamespace()) { -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> namespace "com.margelo.nitro.<%- project.package -%>" <% } else { -%> namespace "com.<%- project.package -%>" @@ -75,7 +75,7 @@ android { <% if (project.arch === "new") { -%> buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() <% } -%> -<% if (project.cpp || project.nitro) { -%> +<% if (project.cpp || project.moduleConfig === 'nitro-modules') { -%> externalNativeBuild { cmake { @@ -95,7 +95,7 @@ android { } <% } -%> } -<% if (project.cpp || project.nitro) { -%> +<% if (project.cpp || project.moduleConfig === 'nitro-modules') { -%> externalNativeBuild { cmake { @@ -128,7 +128,7 @@ android { buildFeatures { buildConfig true -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> prefab true <% } -%> } @@ -173,16 +173,16 @@ def kotlin_version = getExtOrDefault("kotlinVersion") dependencies { implementation "com.facebook.react:react-android" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" -<% if (project.nitro) { -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> implementation project(":react-native-nitro-modules") <% } -%> } -<% if (project.arch === "new" && !project.nitro) { -%> +<% if (project.moduleConfig === "turbo-modules" || project.viewConfig === "fabric-view") { -%> if (isNewArchitectureEnabled()) { react { jsRootDir = file("../src/") - libraryName = "<%- project.view ? project.name + 'View' : project.name -%>" + libraryName = "<%- project.viewConfig !== null ? project.name + 'View' : project.name -%>" codegenJavaPackageName = "com.<%- project.package -%>" } } diff --git a/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec b/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec index 35e4feb8f..9d8cf0c07 100644 --- a/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec +++ b/packages/create-react-native-library/templates/native-common/{%- project.name %}.podspec @@ -24,7 +24,7 @@ Pod::Spec.new do |s| <% } else { -%> s.source_files = "ios/**/*.{h,m,mm}" <% } -%> -<% if (project.nitro) { -%> +<% if (project.moduleConfig === "nitro-modules") { -%> load 'nitrogen/generated/ios/<%- project.name -%>+autolinking.rb' add_nitrogen_files(s) @@ -45,7 +45,7 @@ Pod::Spec.new do |s| "OTHER_CPLUSPLUSFLAGS" => "-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1", "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" } -<% if (project.view) { -%> +<% if (project.viewConfig !== null) { -%> s.dependency "React-RCTFabric" <% } -%> s.dependency "React-Codegen" From 1c89f260e95fcb883a6e5e9f0ec64f4e500b0a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Tue, 17 Dec 2024 15:50:40 +0300 Subject: [PATCH 51/67] add newline in nitro ts --- .../templates/nitro-module/src/{%- project.name %}.nitro.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts b/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts index 46e2f7b31..439d9a4e9 100644 --- a/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts +++ b/packages/create-react-native-library/templates/nitro-module/src/{%- project.name %}.nitro.ts @@ -1,6 +1,6 @@ import type { HybridObject } from 'react-native-nitro-modules'; -export interface <%- project.name -%> +export interface <%- project.name %> extends HybridObject<{ ios: 'swift'; android: 'kotlin' }> { multiply(a: number, b: number): number; } From 6084bf59dfa086bfd588d995b25fb3f3ad96e016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Tue, 17 Dec 2024 17:42:59 +0300 Subject: [PATCH 52/67] fix: use the correct cpp path --- .../templates/nitro-module/android/src/main/cpp/cpp-adapter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/cpp-adapter.cpp b/packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/cpp-adapter.cpp index 7c727ef95..8e1f6123b 100644 --- a/packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/cpp-adapter.cpp +++ b/packages/create-react-native-library/templates/nitro-module/android/src/main/cpp/cpp-adapter.cpp @@ -2,5 +2,5 @@ #include "<%- project.package_cpp -%>OnLoad.hpp" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) { - return margelo::nitro::<%- project.package -%>::initialize(vm); + return margelo::nitro::<%- project.package_cpp -%>::initialize(vm); } From 46019fc76f8d638d67dc2c1599cbf4528a70b45e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Tue, 17 Dec 2024 17:49:39 +0300 Subject: [PATCH 53/67] feat: only ignore jsi libs on nitro modules --- .../templates/native-common/android/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/create-react-native-library/templates/native-common/android/build.gradle b/packages/create-react-native-library/templates/native-common/android/build.gradle index eb067349d..6e7b4d135 100644 --- a/packages/create-react-native-library/templates/native-common/android/build.gradle +++ b/packages/create-react-native-library/templates/native-common/android/build.gradle @@ -102,6 +102,8 @@ android { path "CMakeLists.txt" } } +<% } -%> +<% if (project.moduleConfig === 'nitro-modules') { -%> packagingOptions { excludes = [ From 0a8c374e51139f7ce5ca3f9929ab11077143451f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Tue, 17 Dec 2024 17:52:18 +0300 Subject: [PATCH 54/67] feat: ignore nitrogen --- .../create-react-native-library/templates/common/$.gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/create-react-native-library/templates/common/$.gitignore b/packages/create-react-native-library/templates/common/$.gitignore index 46c939a7d..67f32126d 100644 --- a/packages/create-react-native-library/templates/common/$.gitignore +++ b/packages/create-react-native-library/templates/common/$.gitignore @@ -81,3 +81,6 @@ lib/ # React Native Codegen ios/generated android/generated + +# React Native Nitro Modules +nitrogen/ From 95ee4d1f493bf1076a1fe2383f4adfaaeb9fa889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Thu, 19 Dec 2024 15:45:51 +0300 Subject: [PATCH 55/67] feat: add nitrogen custom target --- .../templates/common/$package.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index bc1b8686d..4dc8ffc4a 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -189,6 +189,15 @@ "source": "src", "output": "lib", "targets": [ +<% if (project.moduleConfig === "nitro-modules") { -%> + [ + "custom", + { + "script": "nitrogen", + "clean": "nitrogen/" + } + ], +<% } -%> <% if (project.moduleConfig === 'turbo-modules' || project.viewConfig === 'fabric-view') { -%> "codegen", <% } -%> From adb1fc57f67a4805dcc3e911bc68e2c7f168cbe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Thu, 19 Dec 2024 15:50:12 +0300 Subject: [PATCH 56/67] feat: generate codegen code on lib ci --- .../templates/common/$.github/workflows/ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml b/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml index ab1606734..3cba52f1d 100644 --- a/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml +++ b/packages/create-react-native-library/templates/common/$.github/workflows/ci.yml @@ -61,6 +61,11 @@ jobs: - name: Setup uses: ./.github/actions/setup +<% if (project.moduleConfig === 'nitro-modules') { -%> + + - name: Generate nitrogen code + run: yarn nitrogen +<% } -%> - name: Cache turborepo for Android uses: actions/cache@v4 @@ -117,6 +122,11 @@ jobs: - name: Setup uses: ./.github/actions/setup +<% if (project.moduleConfig === 'nitro-modules') { -%> + + - name: Generate nitrogen code + run: yarn nitrogen +<% } -%> - name: Cache turborepo for iOS uses: actions/cache@v4 From d3ce21f57681101856ad26e83e5ac7bd341cd5e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Thu, 19 Dec 2024 18:46:46 +0300 Subject: [PATCH 57/67] fix: remove nitrogen step --- .github/workflows/build-templates.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/build-templates.yml b/.github/workflows/build-templates.yml index 9bc2bb22e..73d5df0b9 100644 --- a/.github/workflows/build-templates.yml +++ b/.github/workflows/build-templates.yml @@ -221,11 +221,6 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - - name: Run nitro codegen - if: matrix.type == 'nitro-module' - run: | - yarn nitrogen - - name: Build example (Android) env: JAVA_OPTS: "-XX:MaxHeapSize=6g" From 55116bff61477e26aeaffd2ec1c47da2adb6fcd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Thu, 19 Dec 2024 18:55:19 +0300 Subject: [PATCH 58/67] feat: only fetch the nitro version when the module type is nitro --- packages/create-react-native-library/src/index.ts | 15 +++++++-------- .../create-react-native-library/src/template.ts | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index 58c3741fa..d1c79916f 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -22,7 +22,6 @@ import { printErrorHelp, printNextSteps, printUsedRNVersion } from './inform'; const FALLBACK_BOB_VERSION = '0.36.0'; const FALLBACK_NITRO_MODULES_VERSION = '0.18.0'; -const FALLBACK_NITRO_CODEGEN_VERSION = '0.18.0'; yargs .command( @@ -54,10 +53,6 @@ async function create(_argv: yargs.Arguments) { 'react-native-nitro-modules', FALLBACK_NITRO_MODULES_VERSION ); - const nitroCodegenVersionPromise = resolveNpmPackageVersion( - 'nitro-codegen', - FALLBACK_NITRO_CODEGEN_VERSION - ); const local = await promptLocalLibrary(argv); const folder = await promptPath(argv, local); @@ -79,14 +74,18 @@ async function create(_argv: yargs.Arguments) { assertUserInput(questions, answers); const bobVersion = await bobVersionPromise; - const nitroModulesVersion = await nitroModulesVersionPromise; - const nitroCodegenVersion = await nitroCodegenVersionPromise; + + const nitroModulesVersion = + answers.type === 'nitro-module' + ? await nitroModulesVersionPromise + : undefined; const config = generateTemplateConfiguration({ versions: { bob: bobVersion, nitroModules: nitroModulesVersion, - nitroCodegen: nitroCodegenVersion, + // Nitro codegen's version is always the same as nitro modules version. + nitroCodegen: nitroModulesVersion, }, basename, answers, diff --git a/packages/create-react-native-library/src/template.ts b/packages/create-react-native-library/src/template.ts index a0bed8c42..c003891c1 100644 --- a/packages/create-react-native-library/src/template.ts +++ b/packages/create-react-native-library/src/template.ts @@ -10,8 +10,8 @@ import type { export type TemplateVersions = { bob: string; - nitroModules: string; - nitroCodegen: string; + nitroModules?: string; + nitroCodegen?: string; }; export type ModuleConfig = From 66d25f133d6ecd99eaf9591455b47d5b36890366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 20 Dec 2024 11:39:24 +0300 Subject: [PATCH 59/67] feat: make nitro the second option and add an experimental label --- packages/create-react-native-library/src/input.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/create-react-native-library/src/input.ts b/packages/create-react-native-library/src/input.ts index ce1417126..3d9c8f885 100644 --- a/packages/create-react-native-library/src/input.ts +++ b/packages/create-react-native-library/src/input.ts @@ -85,16 +85,17 @@ const TYPE_CHOICES: { value: ProjectType; description: string; }[] = [ - { - title: 'Nitro module', - value: 'nitro-module', - description: 'type-safe and fast integration for native APIs to JS', - }, { title: 'Turbo module', value: 'turbo-module', description: 'integration for native APIs to JS', }, + { + title: 'Nitro module', + value: 'nitro-module', + description: + 'type-safe, fast integration for native APIs to JS (experimental)', + }, { title: 'Fabric view', value: 'fabric-view', From 1313c42d4d2bc5320646a7a5f55938473cee627e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 20 Dec 2024 11:41:00 +0300 Subject: [PATCH 60/67] feat: remove one doc link from contributing --- .../templates/common/CONTRIBUTING.md | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/create-react-native-library/templates/common/CONTRIBUTING.md b/packages/create-react-native-library/templates/common/CONTRIBUTING.md index 5b1d46309..1bf70511e 100644 --- a/packages/create-react-native-library/templates/common/CONTRIBUTING.md +++ b/packages/create-react-native-library/templates/common/CONTRIBUTING.md @@ -18,15 +18,27 @@ yarn ``` > Since the project relies on Yarn workspaces, you cannot use [`npm`](https://github.com/npm/cli) for development. +<% if (project.moduleConfig === 'nitro-modules') { -%> -The [example app](/example/) demonstrates usage of the library. You need to run it to test any changes you make. +This project uses Nitro Modules. If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/). -It is configured to use the local version of the library, so any changes you make to the library's source code will be reflected in the example app. Changes to the library's JavaScript code will be reflected in the example app without a rebuild, but native code changes will require a rebuild of the example app. -<% if (project.moduleConfig === 'nitro-modules') { -%> +You need to run the code generation process using [Nitrogen](https://nitro.margelo.com/docs/nitrogen) to generate the boilerplate-heavy code required for this project. Without this step, the example apps will not build. + +Run **Nitrogen** in the following cases: +- When you make changes to any `*.nitro.ts` files. +- When running the project for the first time (since the generated files are not committed to the repository). + +To invoke **Nitrogen**, use the following command: -This project uses [Nitro Modules](https://nitro.margelo.com/). If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/). +```sh +yarn nitrogen +``` <% } -%> +The [example app](/example/) demonstrates usage of the library. You need to run it to test any changes you make. + +It is configured to use the local version of the library, so any changes you make to the library's source code will be reflected in the example app. Changes to the library's JavaScript code will be reflected in the example app without a rebuild, but native code changes will require a rebuild of the example app. + <% if (project.native) { -%> If you want to use Android Studio or XCode to edit the native code, you can open the `example/android` or `example/ios` directories respectively in those editors. To edit the Objective-C or Swift files, open `example/ios/<%- project.name -%>Example.xcworkspace` in XCode and find the source files at `Pods > Development Pods > <%- project.slug -%>`. From 704ad9163cac2d110feb89cc8e80a6d4364721e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Sun, 22 Dec 2024 12:46:27 +0300 Subject: [PATCH 61/67] feat: pin the nitro modules peer dep --- .../create-react-native-library/templates/common/$package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/create-react-native-library/templates/common/$package.json b/packages/create-react-native-library/templates/common/$package.json index 4dc8ffc4a..aa8d4c342 100644 --- a/packages/create-react-native-library/templates/common/$package.json +++ b/packages/create-react-native-library/templates/common/$package.json @@ -114,7 +114,7 @@ "react": "*", <% if (project.moduleConfig === 'nitro-modules') { -%> "react-native": "*", - "react-native-nitro-modules": "*" + "react-native-nitro-modules": "^<%- versions.nitroModules %>" <% } else { -%> "react-native": "*" <% } -%> From 810d5d4f701f80b1d6ba6e669b3e506269106c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Mon, 23 Dec 2024 13:39:12 +0300 Subject: [PATCH 62/67] feat: update ios template with the latest version --- .../templates/nitro-module/ios/{%- project.name %}.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift index 4854d8142..1f09ee1a4 100644 --- a/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift +++ b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift @@ -1,6 +1,5 @@ class <%- project.name -%>: Hybrid<%- project.name -%>Spec { - public var hybridContext = margelo.nitro.HybridContext() - public var memorySize: Int { + public override var memorySize: Int { getSizeOf(self) } From 74f31823df7f02aff2eacd6829ded86d85cbf081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 7 Feb 2025 11:22:12 +0300 Subject: [PATCH 63/67] update the fallback nitro version --- packages/create-react-native-library/src/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index d1c79916f..9074f871e 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -21,7 +21,7 @@ import { getDependencyVersionsFromExampleApp } from './exampleApp/dependencies'; import { printErrorHelp, printNextSteps, printUsedRNVersion } from './inform'; const FALLBACK_BOB_VERSION = '0.36.0'; -const FALLBACK_NITRO_MODULES_VERSION = '0.18.0'; +const FALLBACK_NITRO_MODULES_VERSION = '0.22.1'; yargs .command( @@ -123,9 +123,9 @@ async function create(_argv: yargs.Arguments) { rootPackageJson.devDependencies = rootPackageJson.devDependencies ? { - ...rootPackageJson.devDependencies, - ...devDependencies, - } + ...rootPackageJson.devDependencies, + ...devDependencies, + } : devDependencies; } From dd0ba4506196795e6c95ba5d6f9c14022fde93d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 7 Feb 2025 11:28:02 +0300 Subject: [PATCH 64/67] change a few words in contributing guide --- .../templates/common/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/create-react-native-library/templates/common/CONTRIBUTING.md b/packages/create-react-native-library/templates/common/CONTRIBUTING.md index 1bf70511e..fa78e872c 100644 --- a/packages/create-react-native-library/templates/common/CONTRIBUTING.md +++ b/packages/create-react-native-library/templates/common/CONTRIBUTING.md @@ -22,9 +22,9 @@ yarn This project uses Nitro Modules. If you're not familiar with how Nitro works, make sure to check the [Nitro Modules Docs](https://nitro.margelo.com/). -You need to run the code generation process using [Nitrogen](https://nitro.margelo.com/docs/nitrogen) to generate the boilerplate-heavy code required for this project. Without this step, the example apps will not build. +You need to run [Nitrogen](https://nitro.margelo.com/docs/nitrogen) to generate the boilerplate code required for this project. The example app will not build without this step. -Run **Nitrogen** in the following cases: +Run **Nitrogen** in following cases: - When you make changes to any `*.nitro.ts` files. - When running the project for the first time (since the generated files are not committed to the repository). From fc35623e2826c566427fd984e1bed16a4f2316e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 7 Feb 2025 11:43:17 +0300 Subject: [PATCH 65/67] remove the memory size from hybrid objects --- .../nitro/{%- project.package_dir %}/{%- project.name %}.kt | 3 --- .../templates/nitro-module/ios/{%- project.name %}.swift | 4 ---- 2 files changed, 7 deletions(-) diff --git a/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt index 67f48eb3b..0cd4fad3a 100644 --- a/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt +++ b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt @@ -1,9 +1,6 @@ package com.margelo.nitro.<%- project.package %> class CrnlNitro : Hybrid<%- project.name %>Spec() { - override val memorySize: Long - get() = 0L - override fun multiply(a: Double, b: Double): Double { return a * b } diff --git a/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift index 1f09ee1a4..4515e2ed5 100644 --- a/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift +++ b/packages/create-react-native-library/templates/nitro-module/ios/{%- project.name %}.swift @@ -1,8 +1,4 @@ class <%- project.name -%>: Hybrid<%- project.name -%>Spec { - public override var memorySize: Int { - getSizeOf(self) - } - public func multiply(a: Double, b: Double) throws -> Double { return a * b } From 3411f2cce582a3bc621d1c7a82f854fcb51e1406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 7 Feb 2025 11:46:04 +0300 Subject: [PATCH 66/67] don't strip the nitro module code when proguard is enabled --- .../nitro/{%- project.package_dir %}/{%- project.name %}.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt index 0cd4fad3a..f1ecf3743 100644 --- a/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt +++ b/packages/create-react-native-library/templates/nitro-module/android/src/main/java/com/margelo/nitro/{%- project.package_dir %}/{%- project.name %}.kt @@ -1,5 +1,6 @@ package com.margelo.nitro.<%- project.package %> +@DoNotStrip class CrnlNitro : Hybrid<%- project.name %>Spec() { override fun multiply(a: Double, b: Double): Double { return a * b From ba17214bf6ca8d6a3c487b770b514eca1cf9aead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Gu=CC=88ner?= Date: Fri, 7 Feb 2025 11:47:17 +0300 Subject: [PATCH 67/67] fix linting issues --- packages/create-react-native-library/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/create-react-native-library/src/index.ts b/packages/create-react-native-library/src/index.ts index 9074f871e..f109da151 100644 --- a/packages/create-react-native-library/src/index.ts +++ b/packages/create-react-native-library/src/index.ts @@ -123,9 +123,9 @@ async function create(_argv: yargs.Arguments) { rootPackageJson.devDependencies = rootPackageJson.devDependencies ? { - ...rootPackageJson.devDependencies, - ...devDependencies, - } + ...rootPackageJson.devDependencies, + ...devDependencies, + } : devDependencies; }