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

How do I run the packager for a new project? #23

Closed
jlongster opened this Issue Feb 1, 2015 · 10 comments

Comments

Projects
None yet
7 participants
@jlongster

jlongster commented Feb 1, 2015

I created a brand new project, added the required files for ReactKit, and got all that working. Now I just need to run the packager. In packager/packager.js I see:

if (!options.projectRoot) {
  options.projectRoot = path.resolve(__dirname, '..');
}

But options is parsed from the command line arguments and I don't see the projectRoot command line arg. How do I run it, setting the path to my new project?

I temporarily fixed it by hardcoding the projectRoot to my project in there. A side issue: I was surprised to find that the bundler didn't seem to load files from that node_modules where I ran the packager (the error was pretty obscure). I needed to copy the node_modules directory into my new project also.

@amasad

This comment has been minimized.

Show comment
Hide comment
@amasad

amasad Feb 1, 2015

Contributor

@frantic do you have steps for new project creation?

The packager currently only looks in the project root because our @providesModule format forces us to build a dependency graph ahead of time by reading files. Otherwise we'll end up reading your entire drive. There are probably ways around that. I'll look into this tomorrow make sure it works as expected

Contributor

amasad commented Feb 1, 2015

@frantic do you have steps for new project creation?

The packager currently only looks in the project root because our @providesModule format forces us to build a dependency graph ahead of time by reading files. Otherwise we'll end up reading your entire drive. There are probably ways around that. I'll look into this tomorrow make sure it works as expected

@frantic

This comment has been minimized.

Show comment
Hide comment
@frantic

frantic Feb 2, 2015

Contributor

But options is parsed from the command line arguments and I don't see the projectRoot command line arg.

Oh, I missed that when syncing changes to github repo :)

We don't have a good story for creating new apps yet, but imho would be great if all you needed was npm install react-native + packages that your app depends on, and run npm exec devserver to start packager

Contributor

frantic commented Feb 2, 2015

But options is parsed from the command line arguments and I don't see the projectRoot command line arg.

Oh, I missed that when syncing changes to github repo :)

We don't have a good story for creating new apps yet, but imho would be great if all you needed was npm install react-native + packages that your app depends on, and run npm exec devserver to start packager

@jlongster

This comment has been minimized.

Show comment
Hide comment
@jlongster

jlongster Feb 2, 2015

We don't have a good story for creating new apps yet, but imho would be great if all you needed was npm install react-native + packages that your app depends on, and run npm exec devserver to start packager

That's definitely the ideal goal. This & showing how to integrate with other bundlers like webpack would be great.

jlongster commented Feb 2, 2015

We don't have a good story for creating new apps yet, but imho would be great if all you needed was npm install react-native + packages that your app depends on, and run npm exec devserver to start packager

That's definitely the ideal goal. This & showing how to integrate with other bundlers like webpack would be great.

@sjmueller

This comment has been minimized.

Show comment
Hide comment
@sjmueller

sjmueller Feb 5, 2015

Contributor

@frantic, even if the story for new project creation is not there yet, could you still share the manual steps needed to setup a fresh new project? It's been harder than expected, and we have fallen back to just copying one of the examples and hacking away within the cloned repo.

Contributor

sjmueller commented Feb 5, 2015

@frantic, even if the story for new project creation is not there yet, could you still share the manual steps needed to setup a fresh new project? It's been harder than expected, and we have fallen back to just copying one of the examples and hacking away within the cloned repo.

@jlongster

This comment has been minimized.

Show comment
Hide comment
@jlongster

jlongster Feb 5, 2015

@sjmueller Personally I didn't find it too hard, except for not being able to set the project root of the packager. If I remember right:

  • Import ReactKit.xcodeproj into your project
  • Link to libReactKit.a in the link phase
  • Make the RCTRootView in your delegate, like:
    RCTRootView *rootView = [[RCTRootView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    rootView.scriptURL = jsCodeLocation;
    rootView.moduleName = @"App";

And just append it as a subview where you need it

  • Make a js folder in your project
  • Change the root project url in packager/packager.js to your js folder
  • Copy the package.json from the root of react-native into js and run npm install
  • Copy the Libraries folder from react-native into your project

The last steps are the annoying ones, but I'm sure that'll be fixed soon. I may have forgotten something. (definitely need to write this down in docs)

jlongster commented Feb 5, 2015

@sjmueller Personally I didn't find it too hard, except for not being able to set the project root of the packager. If I remember right:

  • Import ReactKit.xcodeproj into your project
  • Link to libReactKit.a in the link phase
  • Make the RCTRootView in your delegate, like:
    RCTRootView *rootView = [[RCTRootView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    rootView.scriptURL = jsCodeLocation;
    rootView.moduleName = @"App";

And just append it as a subview where you need it

  • Make a js folder in your project
  • Change the root project url in packager/packager.js to your js folder
  • Copy the package.json from the root of react-native into js and run npm install
  • Copy the Libraries folder from react-native into your project

The last steps are the annoying ones, but I'm sure that'll be fixed soon. I may have forgotten something. (definitely need to write this down in docs)

@frantic

This comment has been minimized.

Show comment
Hide comment
@frantic

frantic Feb 6, 2015

Contributor

Thanks @jlongster! @sjmueller If you don't have iOS experience, it's easier to just copy the example app and change it's name

Contributor

frantic commented Feb 6, 2015

Thanks @jlongster! @sjmueller If you don't have iOS experience, it's easier to just copy the example app and change it's name

@sjmueller

This comment has been minimized.

Show comment
Hide comment
@sjmueller

sjmueller Feb 6, 2015

Contributor

Much appreciated, @jlongster!

Contributor

sjmueller commented Feb 6, 2015

Much appreciated, @jlongster!

@vjeux

This comment has been minimized.

Show comment
Hide comment
@vjeux

vjeux Feb 7, 2015

Contributor

Closing as it's not very actionable. We definitely want to improve this new project creation experience.

Contributor

vjeux commented Feb 7, 2015

Closing as it's not very actionable. We definitely want to improve this new project creation experience.

@vjeux vjeux closed this Feb 7, 2015

@sjmueller

This comment has been minimized.

Show comment
Hide comment
@sjmueller

sjmueller Feb 13, 2015

Contributor

I went through the process of creating a new Swift v1.2 project from scratch with Xcode 6.3 beta, and preparing it for use with react-native. I know the end goal is to improve the experience so that this is trivial, but for the time being, here are the steps if anyone is curious:

  1. Create a new swift project. I generated mine with Xcode 6.3-beta as Single View Application.

  2. Copy packager, libraries, and reactkit folders from react-native. Copy over .gitignore as well, or create one yourself.

  3. Import ReactKit as a subproject. The easiest way is to drag ReactKit/ReactKit.xcodeproj from finder into the Project navigator in your newly created Xcode project.

  4. Link ReactKit library to build with main binary. This is done by selecting the main project in Xcode, choosing the Build Phases tab, and adding a new framework under the Link Binary With Libraries group. Choose libReactKit.a, as Required.

  5. Add bridging header to use ReactKit in swift. You can do this by adding an temporary ObjC file to your project, and Xcode will prompt you asking if you want to create a Bridging Header. You can then delete the temp file, and continue to use the newly created [app]-bridging-header.h file.

  6. Add all the headers you plan to use from ReactKit into your [app]-bridging-header. I added all of them, since there are some interesting errors if you don't get the dependencies right. I bet there's an easier way to do this, but if not just let me know and I can post my bridging-header.

  7. In order for the headers inside ReactKit to be found, you must add the
    project as a search path. Select main project, choose Build Settings
    tab. Under Search Paths, add a new entry Header Search Paths:
    $(PROJECT_DIR)/ReactKit, recursive.

  8. Initialize app with RCTRootView, set js bundle location. I used the following code in AppDelegate.swift:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    
        let jsCodeLocation = NSURL(string: "http:localhost:8081/Cards/CardsApp.includeRequire.runModule.bundle"),
        rootView = RCTRootView(),
        rootViewController = UIViewController()
    
        rootView.scriptURL = jsCodeLocation
        rootView.moduleName = "CardsApp"
    
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        rootViewController.view = rootView
        self.window!.rootViewController = rootViewController
        self.window!.makeKeyAndVisible()
    
        return true
    }
    
  9. Delete unused default storyboard, viewcontroller under your [app] folder, since they aren't being used.

  10. Modify Info.plist to remove storyboard entry:

    -      <key>UIMainStoryboardFile</key>
    -      <string>Main</string>
    
  11. Add -all_load linker flag to pick up ReactKit objc category methods. Otherwise you'll receive errors like unrecognized selector sent to class when trying to use RCTRootView. On your main project, select Build Settings tab, Linking -> Other Linker Flags: Add -all_load. I've read that there are more optimal ways to do this, but good enough for now.

  12. Add main entry point to js application as [AppName]App.js. Just for starters you can use something like the code below (check out the tictactoe app for a full example):

    var App = React.createClass({
        render() {
            return (
                <View style={styles.container}>
                    <Text style={styles.title}>My App</Text>
                </View>
            );
        }
    });
    

Perhaps there are some steps that are extraneous, and a few obviously won't apply to a pure ObjC project. Hope this helps.

Contributor

sjmueller commented Feb 13, 2015

I went through the process of creating a new Swift v1.2 project from scratch with Xcode 6.3 beta, and preparing it for use with react-native. I know the end goal is to improve the experience so that this is trivial, but for the time being, here are the steps if anyone is curious:

  1. Create a new swift project. I generated mine with Xcode 6.3-beta as Single View Application.

  2. Copy packager, libraries, and reactkit folders from react-native. Copy over .gitignore as well, or create one yourself.

  3. Import ReactKit as a subproject. The easiest way is to drag ReactKit/ReactKit.xcodeproj from finder into the Project navigator in your newly created Xcode project.

  4. Link ReactKit library to build with main binary. This is done by selecting the main project in Xcode, choosing the Build Phases tab, and adding a new framework under the Link Binary With Libraries group. Choose libReactKit.a, as Required.

  5. Add bridging header to use ReactKit in swift. You can do this by adding an temporary ObjC file to your project, and Xcode will prompt you asking if you want to create a Bridging Header. You can then delete the temp file, and continue to use the newly created [app]-bridging-header.h file.

  6. Add all the headers you plan to use from ReactKit into your [app]-bridging-header. I added all of them, since there are some interesting errors if you don't get the dependencies right. I bet there's an easier way to do this, but if not just let me know and I can post my bridging-header.

  7. In order for the headers inside ReactKit to be found, you must add the
    project as a search path. Select main project, choose Build Settings
    tab. Under Search Paths, add a new entry Header Search Paths:
    $(PROJECT_DIR)/ReactKit, recursive.

  8. Initialize app with RCTRootView, set js bundle location. I used the following code in AppDelegate.swift:

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    
        let jsCodeLocation = NSURL(string: "http:localhost:8081/Cards/CardsApp.includeRequire.runModule.bundle"),
        rootView = RCTRootView(),
        rootViewController = UIViewController()
    
        rootView.scriptURL = jsCodeLocation
        rootView.moduleName = "CardsApp"
    
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        rootViewController.view = rootView
        self.window!.rootViewController = rootViewController
        self.window!.makeKeyAndVisible()
    
        return true
    }
    
  9. Delete unused default storyboard, viewcontroller under your [app] folder, since they aren't being used.

  10. Modify Info.plist to remove storyboard entry:

    -      <key>UIMainStoryboardFile</key>
    -      <string>Main</string>
    
  11. Add -all_load linker flag to pick up ReactKit objc category methods. Otherwise you'll receive errors like unrecognized selector sent to class when trying to use RCTRootView. On your main project, select Build Settings tab, Linking -> Other Linker Flags: Add -all_load. I've read that there are more optimal ways to do this, but good enough for now.

  12. Add main entry point to js application as [AppName]App.js. Just for starters you can use something like the code below (check out the tictactoe app for a full example):

    var App = React.createClass({
        render() {
            return (
                <View style={styles.container}>
                    <Text style={styles.title}>My App</Text>
                </View>
            );
        }
    });
    

Perhaps there are some steps that are extraneous, and a few obviously won't apply to a pure ObjC project. Hope this helps.

@boopathi

This comment has been minimized.

Show comment
Hide comment
@boopathi

boopathi Feb 13, 2015

Contributor

@sjmueller Thanks a lot. I was stuck because of not adding all headers to bridging-header for quite a while, and I would suggest this to go into the docs as well (or) to Examples/SwiftApp

And instead of copying files around, you can open packager/packager.js and add your project directory to options.projectRoots. #64 would fix it where you could run

./packager/packager.sh --root ~/workspace/Cards

and your jsCodeLocation would be http://localhost:8081/CardsApp.includeRequire.runModule.bundle where CardsApp.js is the entry point.

Contributor

boopathi commented Feb 13, 2015

@sjmueller Thanks a lot. I was stuck because of not adding all headers to bridging-header for quite a while, and I would suggest this to go into the docs as well (or) to Examples/SwiftApp

And instead of copying files around, you can open packager/packager.js and add your project directory to options.projectRoots. #64 would fix it where you could run

./packager/packager.sh --root ~/workspace/Cards

and your jsCodeLocation would be http://localhost:8081/CardsApp.includeRequire.runModule.bundle where CardsApp.js is the entry point.

harrykiselev pushed a commit to harrykiselev/react-native that referenced this issue Aug 5, 2015

dustturtle added a commit to dustturtle/react-native that referenced this issue Jul 6, 2016

JSONKit usage here may cause serious crash hard to debug(I found the …
…crash on simulator, on device I got nothing but app freezed)!

My app has an old version of JSONKit which is still using MRC. I think JSONKit is not needed if system version is available. Kicking out of JSONKit will make react native stronger.
Crash stack:
* thread #11: tid = 0xbd672f, 0x000000010a10edeb imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=22 key/value pairs) + 16971 at JSONKit.m:2807, name = 'com.facebook.React.JavaScript', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x000000010a10edeb imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=22 key/value pairs) + 16971 at JSONKit.m:2807
    frame #1: 0x000000010a10ef67 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=2 key/value pairs) + 17351 at JSONKit.m:2811
    frame #2: 0x000000010a10ef67 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=25 key/value pairs) + 17351 at JSONKit.m:2811
    frame #3: 0x000000010a10e768 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=@"3 elements") + 15304 at JSONKit.m:2778
  * frame #4: 0x000000010a10a26a imobii-waiqin`-[JKSerializer serializeObject:options:encodeOption:block:delegate:selector:error:](self=0x00007f9b831fbc80, _cmd="serializeObject:options:encodeOption:block:delegate:selector:error:", object=@"3 elements", optionFlags=0, encodeOption=10, block=0x0000000000000000, delegate=0x0000000000000000, selector=<no value available>, error=domain: class name = NSInvocation - code: 0) + 2250 at JSONKit.m:2876
    frame #5: 0x000000010a109992 imobii-waiqin`+[JKSerializer serializeObject:options:encodeOption:block:delegate:selector:error:](self=JKSerializer, _cmd="serializeObject:options:encodeOption:block:delegate:selector:error:", object=@"3 elements", optionFlags=0, encodeOption=10, block=0x0000000000000000, delegate=0x0000000000000000, selector=<no value available>, error=domain: class name = NSInvocation - code: 0) + 178 at JSONKit.m:2831
    frame #6: 0x000000010a10f700 imobii-waiqin`-[NSArray(self=@"3 elements", _cmd="JSONStringWithOptions:error:", serializeOptions=0, error=domain: class name = NSInvocation - code: 0) JSONStringWithOptions:error:] + 112 at JSONKit.m:2985
    frame #7: 0x000000010ac13c02 imobii-waiqin`_RCTJSONStringifyNoRetry(jsonObject=@"3 elements", error=domain: class name = NSInvocation - code: 0) + 338 at RCTUtils.m:49
    frame #8: 0x000000010ac13990 imobii-waiqin`RCTJSONStringify(jsonObject=@"3 elements", error=0x0000000000000000) + 128 at RCTUtils.m:77
    frame #9: 0x000000010ab5fdfa imobii-waiqin`__27-[RCTContextExecutor setUp]_block_invoke_2(.block_descriptor=<unavailable>, moduleName=@"UIManager") + 218 at RCTContextExecutor.m:363
    frame #10: 0x00000001134495cc CoreFoundation`__invoking___ + 140
    frame #11: 0x000000011344941e CoreFoundation`-[NSInvocation invoke] + 286
    frame #12: 0x000000010db13db3 JavaScriptCore`JSC::ObjCCallbackFunctionImpl::call(JSContext*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) + 451
    frame #13: 0x000000010db13926 JavaScriptCore`JSC::objCCallbackFunctionCallAsFunction(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) + 262
    frame #14: 0x000000010db14bad JavaScriptCore`long long JSC::APICallbackFunction::call<JSC::ObjCCallbackFunction>(JSC::ExecState*) + 573
    frame #15: 0x000000010dade340 JavaScriptCore`JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) + 528
    frame #16: 0x000000010dae535d JavaScriptCore`llint_entry + 22900
    frame #17: 0x000000010dadf7d9 JavaScriptCore`vmEntryToJavaScript + 326
    frame #18: 0x000000010d9b1959 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 169
    frame #19: 0x000000010d9985ad JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 493
    frame #20: 0x000000010d76cb7e JavaScriptCore`JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 62
    frame #21: 0x000000010d929a55 JavaScriptCore`JSC::callGetter(JSC::ExecState*, JSC::JSValue, JSC::JSValue) + 149
    frame #22: 0x000000010dad49fb JavaScriptCore`llint_slow_path_get_by_id + 2203
    frame #23: 0x000000010dae22f0 JavaScriptCore`llint_entry + 10503
    frame #24: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame #25: 0x000000010dae52fd JavaScriptCore`llint_entry + 22804
    frame #26: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame #27: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame #28: 0x000000010dae52fd JavaScriptCore`llint_entry + 22804
    frame #29: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame #30: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame #31: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame #32: 0x000000010dae552a JavaScriptCore`llint_entry + 23361
    frame #33: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame #34: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911
    frame #35: 0x000000010dadf7d9 JavaScriptCore`vmEntryToJavaScript + 326
    frame #36: 0x000000010d9b1959 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 169
    frame #37: 0x000000010d998264 JavaScriptCore`JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) + 10404
    frame #38: 0x000000010d7a8786 JavaScriptCore`JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) + 470
    frame #39: 0x000000010d9f6fb8 JavaScriptCore`JSEvaluateScript + 424
    frame #40: 0x000000010ab6379e imobii-waiqin`__68-[RCTContextExecutor executeApplicationScript:sourceURL:onComplete:]_block_invoke.264(.block_descriptor=<unavailable>) + 414 at RCTContextExecutor.m:589
    frame #41: 0x000000010ab63262 imobii-waiqin`__68-[RCTContextExecutor executeApplicationScript:sourceURL:onComplete:]_block_invoke(.block_descriptor=<unavailable>) + 498 at RCTContextExecutor.m:589
    frame #42: 0x000000010ab63df8 imobii-waiqin`-[RCTContextExecutor executeBlockOnJavaScriptQueue:](self=0x00007f9b832f6040, _cmd="executeBlockOnJavaScriptQueue:", block=0x00007f9b80c92970) + 248 at RCTContextExecutor.m:627
    frame #43: 0x000000010eb1d7a7 Foundation`__NSThreadPerformPerform + 283
    frame #44: 0x0000000113486301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #45: 0x000000011347c22c CoreFoundation`__CFRunLoopDoSources0 + 556
    frame #46: 0x000000011347b6e3 CoreFoundation`__CFRunLoopRun + 867
    frame #47: 0x000000011347b0f8 CoreFoundation`CFRunLoopRunSpecific + 488
    frame #48: 0x000000010ab5e41b imobii-waiqin`+[RCTContextExecutor runRunLoopThread](self=RCTContextExecutor, _cmd="runRunLoopThread") + 363 at RCTContextExecutor.m:284
    frame #49: 0x000000010ebc012b Foundation`__NSThread__start__ + 1198
    frame #50: 0x00000001140869b1 libsystem_pthread.dylib`_pthread_body + 131
    frame #51: 0x000000011408692e libsystem_pthread.dylib`_pthread_start + 168
    frame #52: 0x0000000114084385 libsystem_pthread.dylib`thread_start + 13

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.