Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] feat(crnl): support nitro modules #721

Open
wants to merge 65 commits into
base: main
Choose a base branch
from
Open

[WIP] feat(crnl): support nitro modules #721

wants to merge 65 commits into from

Conversation

atlj
Copy link
Collaborator

@atlj atlj commented Dec 6, 2024

WIP until #732 is merged

Summary

Adds Nitro Modules support to create-react-native-library.
Screenshot 2024-12-06 at 20 05 42

What's next?

Test plan

Prior to all cases:

  1. Clone this branch
  2. Call yarn and yarn prepare
  3. Call bin/create-react-native-library

Example app

  1. Create a new nitro module
  2. Go to the module and install node dependencies
  3. Call yarn nitrogen to create nitro bindings
  4. Build the Android app and make sure it works properly
  5. Install the pods and build the iOS app and make sure it works properly

Published lib

  1. Publish the library from the previous case using https://github.com/wclr/yalc (yalc publish)
  2. Create a new React Native app
  3. Call yalc add your-lib
  4. Make sure the React Native app builds and works fine with your lib.

@mrousavy
Copy link
Contributor

mrousavy commented Dec 6, 2024

letsgoooooo!!!

Copy link
Contributor

@mrousavy mrousavy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really excited for this!

.github/workflows/build-templates.yml Show resolved Hide resolved
packages/create-react-native-library/src/inform.ts Outdated Show resolved Hide resolved
@@ -85,10 +91,16 @@
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.1",
"jest": "^29.7.0",
<% if (project.nitro) { -%>
"nitro-codegen": "^<%- versions.nitroCodegen %>",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah here we have it - ok good!

Comment on lines 2 to 5
public var hybridContext = margelo.nitro.HybridContext()
public var memorySize: Int {
getSizeOf(self)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should really work on getting this lifted into the spec instead of having it at user class level. Maybe Nitro 19

Comment on lines +106 to +128

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"
]
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this still need those days?, I created a rn turbo modules recently then migrated to nitro later, and i didn't got any symbol conflict as we used to have in the past

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got these from @mrousavy's nitro template, @mrousavy is it safe to remove these? Also maybe we can make this to default for everyone?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know, lol.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI I tried to build nitro without these, but I got an error mentioning some of these libs were duplicated so these are needed for nitro modules right now.

Comment on lines 215 to 227
- name: Run nitro codegen
if: matrix.type == 'nitro-module'
run: |
yarn nitrogen
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to run this manually?

Also contributing guide needs to include the workflow in case there are any new steps - like running this (and when is it needed)

packages/create-react-native-library/src/index.ts Outdated Show resolved Hide resolved
packages/create-react-native-library/src/inform.ts Outdated Show resolved Hide resolved
@@ -49,7 +52,11 @@ def supportsNamespace() {

android {
if (supportsNamespace()) {
<% if (project.nitro) { -%>
namespace "com.margelo.nitro.<%- project.package -%>"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this the library's namespace? then it shouldn't have margelo.com since that's not the library's organization.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2024-12-17 at 17 41 09 nitro codegen expects the kotlin files under the margelo namespace. We have to use margelo namespace until this is changed in nitrogen.

cc: @mrousavy

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm this doesn't seem good. i wouldn't feel comfortable having my own library under margelo's domain.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea Nitro expects margelo.com namespaces for all Hybrid Objects.
This was to simplify the ProGuard annotations (if something is missing from com.margelo it was stripped out, which we explicitly deal with) - and also it makes cross-referencing Hybrid Objects from other Nitro Modules easier since we don't have to worry about different namespaces here.
Also, it's at least a little bit of branding 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wouldn't feel comfortable having my own library under margelo's domain.

All the generated code from Turbo Modules are under facebook's domain. This is the same here, the generated code is under margelo domain.

Nitro expects registered hybrid objects to be under the same domain as well, not any custom configurable domain - which is the same as how it works in C++ Turbo Modules.
This was just to simplify the whole thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the generated code from Turbo Modules are under facebook's domain. This is the same here, the generated code is under margelo domain.

Having the generated code or a specific part of the code vs the entire package like it's done here are quite different things. I'm sure bigger companies would have restrictions on using their namespace and publishing to their internal registries.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea I understand, but this is not gonna change anytime soon as it might require larger changes in the Nitrogen codebase.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a bigger company reaches out to me because they want to use Nitro but can't because of namespace restrictions, then I'll work on that with them. For now, I don't see a problem in it tbh.

packages/create-react-native-library/src/index.ts Outdated Show resolved Hide resolved
@@ -72,7 +78,7 @@
"devDependencies": {
"@commitlint/config-conventional": "^17.0.2",
"@evilmartians/lefthook": "^1.5.0",
<% if (example === 'vanilla') { -%>
<% if (example === 'vanilla' && !project.nitro) { -%>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll be more future-proof to add configs based on what type of project it is rather than what type of project it is not. That way adding a new type won't require adding new condition to each call site.

I think we should just add a key for the official module type and use it for these checks (here and other places) instead of !project.nitro.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've introduced project.moduleConfig (which replaces project.module) as an union type of native-modules, turbo-modules, nitro-modules. This is the native modules api that we use.

@atlj atlj force-pushed the @atlj/nitro branch 6 times, most recently from 5df5303 to 54d0fa5 Compare December 17, 2024 14:43
@atlj atlj marked this pull request as ready for review December 19, 2024 12:50
@atlj atlj changed the title feat(crnl): support nitro modules [WIP] feat(crnl): support nitro modules Dec 20, 2024
@atlj atlj requested a review from satya164 December 20, 2024 08:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants