facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
117.1k stars 24.07k forks source link

CocoaPod spec #60

Closed ide closed 9 years ago

ide commented 9 years ago

CocoaPods is like npm for iOS and OS X. It keeps your dependencies up-to-date and sets up the Xcode workspace file so you don't have to manually drag ReactKit into the Movies project, for example. It probably makes sense to publish a CocoaPod for the public release.

There are a couple steps in this process. One thing that needs to be figured out is how to deploy the JS files under Libraries. Usually a CocoaPod will include Obj-C along with resource files inside of a bundle, but ReactKit's packager wants to bundle up both the core library files with the application JS (side note: worth thinking about changing this so apps don't need to load all the JS at boot). The right setup might be to split the project into three parts: ReactKit's native code (fetched via CocoaPods), ReactKit's core JS libraries (via npm), and react-kit-tools (packager, etc, fetched via npm). The workflow would look like:

pod try ReactKit
npm install react-kit react-kit-tools
npm start
# done!

Looking to get feedback on the overall idea or the specifics, especially because it affects both adoption of ReactKit and touches FB's syncing between the public and private repos.

vjeux commented 9 years ago

Thanks for opening up this issue. This was the setup I had in mind as well.

One other thing that's going to be interesting is plugins, since they have both a obj-c and js part.

vjeux commented 9 years ago

cc @a2 @nicklockwood

joewood commented 9 years ago

Would it better to package these together like Cordova does? Check out this simple example: cordova-facebook Otherwise I could imagine keeping the CocoaPod version inline with the npm version a challenge.

vjeux commented 9 years ago

@joewood one of the issue with Cordova is that they invented their own package manager and registry. I really don't want us to be in the business of running a registry for react native plugins. I'd much rather leave this hard work to npm and cocoapods :)

joewood commented 9 years ago

@vjeux totally agree. Why not use npm to pull the files from a single repo and then the build/package process would take the files out of the node_modules directory? If the native package managers were to be used, it could soon become a dependency nightmare between maven, npm, nuget, cocoapods etc...

amasad commented 9 years ago

Three packages in two different package managers sounds like it would be hard to manage. What value does CocoaPod provide here?

JoeStanton commented 9 years ago

I've also been thinking about this, it seems like it would be best to rely heavily on npm to package both the JS and Obj-C code (for plugins) and have it integrate to the build process by scripts/convention. Most developers familiar with React will be used to npm but likely not have seen Cocoapods etc. before. Might reduce some friction and make contributing and versioning easier...

joewood commented 9 years ago

With npm, for the C++ part of any build node-gyp could be used too. Taking some of the pain out of the build environment set-up.

ide commented 9 years ago

CocoaPods handles the Xcode workspace configuration and linking. Things that you can do by hand or with a tool like Carthage (though that's iOS8-only which I think is a no-go for Facebook) but are nicer when handled automatically.

Most developers familiar with React will be used to npm but likely not have seen Cocoapods etc. before.

I think this is true at the moment because the project was advertised to people attending React Conf and are mostly doing web development, but I think ReactKit is going to get substantial traction when iOS developers get on board. Since CocoaPods is by far the most popular way to publish iOS libraries I think it is a good place to start even if something that's designed for polyglot modules supersedes it.

amasad commented 9 years ago

I think this is true at the moment because the project was advertised to people attending React Conf and are mostly doing web development, but I think ReactKit is going to get substantial traction when iOS developers get on board. Since CocoaPods is by far the most popular way to publish iOS libraries I think it is a good place to start even if something that's designed for polyglot modules supersedes it.

It sounds like this could be really useful for more advanced users. However, it seems like the common case would be developers writing JavaScript and not worrying much about Obj-C. Additionally, we're working on the Android version of ReactNative, and possibly a Windows version to follow. If we added their respective package managers as first-class dependencies, we can easily get to a point were getting started would be too hard. Let's try to make the common thing easy and the more advanced thing possible.

Can we have the initial project set up via npm and scripts and then more advanced users that want to write native components and use third party libraries can have the choice to install and use CocoaPods?

vjeux commented 9 years ago

Some more things to put into consideration.

1) What's the story for Android? Do we ask people to also install Maven/Graddle/whatever is being used there?

2) What's the story for custom components? Let say I want to use Shimmer, do I have to do pod install react-native-shimmer; npm install react-native-shimmer? Or do we put everything in the npm module? Or everything in the pod?

nicklockwood commented 9 years ago

I'm inclined to agree with @joewood. I like CocoaPods, and if this were an iOS-specific framework I would say that pods were an obvious solution for managing plugins. But in the long term, our plugins are going to contain JavaScript, Objective-C (or Swift!) and Java code, with whatever dependencies each of those requires, and CocoaPods only really makes sense for managing the Objective-C code.

Given that the target consumers of these plugins are predominantly web developers, and that node is a requirement to run the platform, I'd say that npm makes sense, provided that it can meet all of our requirements.

I totally understand @vjeux's disinclination for us to try to build our own package manager, however the plugin management of Cordova is one of its strongest features, and I would like to make sure that whatever we end up with provides at least that ease of use for plugin developers and consumers.

In the short term however, I see no harm in including a podspec, as it will make it easier for iOS developers to discover and try out React Native.

ide commented 9 years ago

@vjeux

  1. Yeah. I think you want compatibility with Maven and Gradle so that the class path is automatically handled. These tools shouldn't be required, like how you're not forced to use CocoaPods even if a project has a podspec, but they automate the project setup experience a lot more.
  2. Great question. I'm not sure of the answer though I think the solution for distributing ReactKit could apply to UI components as well. Lots of similarities like having both JS and ObjC code, needing to integrate with Xcode, making the packager aware of the JS, etc.

I want to reiterate that integrating with the iOS ecosystem & community and drawing upon the wealth of Cocoa experience could be really valuable for ReactKit. From another angle, CocoaPods is familiar to people already building iOS apps today who might find it easier to drop into Obj-C when building features that ReactKit hasn't yet anticipated.

ide commented 9 years ago

In the short term however, I see no harm in including a podspec, as it will make it easier for iOS developers to discover and try out React Native.

Totally. The podspec is hopefully unobtrusive. There's a fair chance that CocoaPods isn't part of the picture at the end but I think it is worth experimenting with.

Here's another idea for the dependency management & binary build process: what if there were a small tool that looked inside node_modules for React Native components and updated the Xcode project file (or even updated the Podfile to reference these modules, and delegated the rest of the work to CocoaPods)? Something like:

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.0'
pod 'CocoaLumberjack', '~> 2.0.0-rc'
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

Now here's the cool part / litmus test: can ReactKit itself be distributed this way? I think it can.

joewood commented 9 years ago

I think the above provides the best of both worlds. This makes npm the parent package manager, CocoaPod, Maven etc. subordinate. Most JS developers won't have to worry about the native modules, as long as the scripts keep the packages in sync.

sahrens commented 9 years ago

I like James' proposal a lot - basically leveraging cocoapods (or Maven or whatever) as a platform-specific installer, and all the code is pulled in as one versioned unit from one system (npm), and we can even hide the steps inside npm install so it's super smooth for developers.

On Feb 24, 2015, at 6:38 PM, Joe Wood notifications@github.com wrote:

I think the above provides the best of both worlds. This makes npm the parent package manager, CocoaPod, Maven etc. subordinate. Most JS developers won't have to worry about the native modules, as long as the scripts keep the packages in sync.

— Reply to this email directly or view it on GitHub.

jaisanth commented 9 years ago

+1 for @ide 's suggestion.

a2 commented 9 years ago

Can we close this now that we have a CP spec?

ide commented 9 years ago

@a2 Yeah soon I think. The podspec needs a little bit of work (see #285) but with my diff I've gotten things running.

I would like to exclude unused code soon though, which is one thing a package system should provide. Discussion about external packages can continue in #235.

zetachang commented 9 years ago

As an iOS developer, +1 on @ide 's suggestion.

paramaggarwal commented 9 years ago

+1 on @ide 's suggestion to use npm as parent package manager and CocoaPods/Maven as platform-specific installers.

ide commented 9 years ago

The podspecs for RN and its helper libraries are in a reasonable place now. Module system still needs to be worked out and let's have that discussion separately.

paramaggarwal commented 9 years ago

Hop on to the module system discussion over at #235 if you want to hear about progress on the above suggestions.