npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-native-colocate-native

v0.2.0

Published

Colocate your native modules with your React Native JavaScript and JSX files

Downloads

4

Readme

React Native Colocate Native

Hey! You found an experiment that I'm working on. Fun fun.

This library (theoretically) lets you colocate your native files with your React Native JavaScript files.

Installation

Add this library to your development dependencies:

npm install --save-dev react-native-colocate-native
# or
yarn add -D react-native-colocate-native

iOS Installation

For iOS, add this to your Podfile (ios/Podfile):

require_relative '../node_modules/react-native-colocate-native/scripts/ios.rb'
link_colocated_native_files(app_name: 'MyApp', app_path: "../app")

Android Installation

Create a "package" file for your project in ./android/app/src/main/java/com/myapp/MyAppPackage.java (but replace myapp and MyApp with your app's name).

The contents of this file will be this:

// ./android/app/src/main/java/com/myapp/MyAppPackage.java
package com.myapp; // replace myapp with your app’s package name
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

// Replace MyApp with your app's name
public class MyAppPackage implements ReactPackage {
   @Override
   public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
       return Collections.emptyList();
   }

   @Override
   public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
      List<NativeModule> modules = new ArrayList<>();

      // Add all react-native-colocate-native modules from ./colocated/RNColocate.java
      modules.addAll(RNColocate.colocatedModules(reactContext));

      return modules;
   }
}

Open up your MainApplication.java file in the same folder and update the following method:

@Override
protected List<ReactPackage> getPackages() {
  @SuppressWarnings("UnnecessaryLocalVariable")
  List<ReactPackage> packages = new PackageList(this).getPackages();
  // Packages that cannot be autolinked yet can be added manually here, for example:
  // packages.add(new MyReactNativePackage());
  packages.add(new MyAppPackage());
  return packages;
}

Open up your ./android/gradle.settings file and add this near the top (replace myapp with your app name):

rootProject.name = 'MyApp'

apply from: '../node_modules/react-native-colocate-native/scripts/android.groovy'
setupReactNativeColocateNative([
  appName: rootProject.name,
  appPath: "../app",
  appPackageName: "com.myapp",
  androidPath: "./android/app/src/main/java/com/myapp"
])

// rest of file...

Now, when you run yarn android, it'll hardlink your .java files into a colocated folder in your Android project directory and then generate the class RNColocate which will instantiate & register all of them with your project.

Usage

For native Objective-C and Java modules, place your .m, .h, .swift, and .java files anywhere near your JavaScript/JSX files. They'll be linked in automatically when you run npx pod-install or pod install, or in Android's case, when you run yarn android.

ios/
android/
app/
  components/
    MyButton.tsx
    MyButton.h
    MyButton.m
    MyButton.java

Examples

Objective-C Example

Let's build a small native module.

In a fresh React Native project, make a folder called app. Place two files inside of that -- Jamon.h and Jamon.m.

// app/Jamon.h
#import <React/RCTBridgeModule.h>
@interface Jamon : NSObject <RCTBridgeModule>
@end
// Jamon.m
#import "Jamon.h"

@implementation Jamon

RCT_EXPORT_MODULE();

// Export a method -- `Jamon.hello()`
RCT_EXPORT_METHOD(hello)
{
  // Alerts have to go on the main thread
  dispatch_async(dispatch_get_main_queue(), ^{
    UIAlertView *alert = [[UIAlertView alloc]
      initWithTitle: @"Hello from native!"
      message: @"This is from Jamon.m"
      delegate: self
      cancelButtonTitle: @"Cancel"
      otherButtonTitles: @"Say Hello",
      nil
    ];
    [alert show];
  });
}

@end

Modify the App.js to import the native module:

import { NativeModules } from "react-native";
const { Jamon } = NativeModules;

// Now run it:
Jamon.hello();

If you haven't added the module yet, run npm i --save-dev react-native-colocate-native and then modify your Podfile (replace MyApp with your actual app name):

require_relative '../node_modules/react-native-colocate-native/scripts/ios.rb'

link_colocated_native_files(app_name: 'MyApp', app_path: "../app")

Run npx pod-install in your terminal and then run your project with yarn ios (or yarn react-native run-ios).

You should see the native alert pop up in your app!

Hint: You can read a lot more about iOS native modules here: https://reactnative.dev/docs/native-modules-ios

Swift Example

Swift requires a bit more setup, but after that you should be able to drop in .swift files and have them work. Unfortunately, as of now, Swift files still require a .m file to expose them to React Native, so you'll still be making two files.

To set up Swift in your project (only has to be done once):

First, open your xcworkspace file (in the ./ios folder) in Xcode.

Click File -> New -> New File in the menu (or hit Cmd+N).

Choose "Swift File" under the Source section. Name it something like EnableSwift and click Create.

Xcode should prompt you with this prompt: Would you like to configure an Objective-C bridging header?

Click Create bridging header (this is key).

Inside that file, add this line:

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//
#import <React/RCTBridgeModule.h>

Save it, and you now have Swift support. You can close Xcode and let your Mac take a breather.

Now, it's just a matter of adding Swift files to your project. Inside the ./app folder you created in the previous section, add the following Gant.swift file:

// Gant.swift
@objc(Gant)
class Gant : NSObject {
  @objc func hello() {
    // Alerts have to go on the main thread
    DispatchQueue.main.async {
      let alert = UIAlertView(
        title: "Hello from native!",
        message: "This is from Gant.swift",
        delegate: nil,
        cancelButtonTitle: "Cancel",
        otherButtonTitles: "Say Hello"
      )
      alert.show()
    }
  }
}

Also add a Gant.m file next to it to export it to React Native:

// Gant.m
#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(Gant, NSObject)
RCT_EXTERN_METHOD(hello)
@end

In your App.js, just use it like you did the Jamon native module:

import { NativeModules } from "react-native";
const { Gant } = NativeModules;

Gant.hello();

Don't forget to run npx pod-install (or pod install from the ios folder) to link up the new native files.

Then run yarn ios to recompile. You should see the alert pop up! Yay!

Android example

Coming soon!