Skip to content

[Dependencies] Module system (fantastic project for interested contributors!) #235

@ide

Description

@ide

Currently React Native ships with a set of modules, some of which are ubiquitous (basic View support) and some that are used only in a handful of apps (e.g. Vibration support). As the set of modules grows, the size of the 'react-native' JS will also increase and slow down the boot time for apps. There's already overhead on the order of a couple hundred milliseconds spinning up a JSContext and loading every single Obj-C class (#69) so reducing the startup cost is valuable. Also there needs to be a module system in place to support third-party components, especially those with a native implementation.

Features:

My current thinking is a good module system would let you:

  • Pay for only what you use. Ex: if you don't use a database module then your app shouldn't include the JS for it (string loading + parsing + evaluation cost) nor the native binary code (app size cost).
  • Dedupe native dependencies. This is a requirement since you cannot have two Obj-C classes with the same name. Ex: two modules may both use CocoaLumberjack, a very popular logging library. The module system should determine which version of CocoaLumberjack is compatible with both modules and download and link just one copy. Good news is that the CocoaPods system already does this with a constraint solver!
  • Dedupe JS depedendencies. Many JS components will use the same npm modules. Unlike Node on the server (boot time is hidden from the user + powerful hardware available), extra JS on the client (esp. mobile clients) adds a user-facing cost. So . This is not a hard requirement unlike with the native dependencies, but still important.

Design:

The gist is that the modules should be hosted in npm and will include both a package.json and a podspec (similar in spirit to package.json but for Obj-C and Swift). The package manager client (that is, what this project is about) looks inside node_modules for React Native components and updates a Podfile to reference these modules. The rest of the work is delegated to CocoaPods:

File hierarchy:

Podfile
Autogenerated-npm-Podfile  # created by the tool
node_modules/
  react-native-page-view-controller/
    package.json
    index.js
    ios/
      RCTPageViewController.h
      RCTPageViewController.m
      react-native-page-view-controller.podspec

Podfile

# all your normal dependencies, here are some examples
pod 'AWSiOSSDKv2', '~> 2.1'
pod 'CocoaLumberjack', '~> 2.0'
pod 'FMDB', '~> 2.5'
pod 'GoogleAnalytics-iOS-SDK', '~> 3.0'
pod 'Reachability', '~> 3.2'

require 'Autogenerated-npm-Podfile'

Autogenerated-npm-Podfile

# @generated by hypothetical tool
# Reference the local pods that live in node_modules
pod 'react-native-page-view-controller', 'node_modules/react-native-page-view-controller/ios'

What the tool does:

  1. Scans node_modules for the podspecs
  2. Adds references to them in an autogenerated file that is loaded from the Podfile (Podfiles and Podspecs are just Ruby)
  3. Runs pod install or pod update, whatever is appropriate

The workflow

npm install react-native-page-view-controller
cool_tool
# open App.xcworkspace

There are details to be worked through but I believe this is directionally correct.

Skill set:

Strong familiarity with npm and iOS development is helpful, as well as some familarity with CocoaPods. You could learn some of these as you go though you'll be more comfortable with an advance understanding of how the pieces fit together and what npm and CocoaPods can and can't do.

I'm happy to provide feedback, direction, or mentorship if someone or a pair of people want to take up this endeavor - it should be a worthwhile project that lots of people will use.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions