Rohan Prabhu
Rohan Prabhu

Reputation: 7302

How to manage common code with node.js - For a react-native perspective

Earlier I believed that one of the aims of react-native was to be able to re-use a lot of the code across multiple platforms. The more I read, it seems to not be the case (or one of the primary cases). What I want to achieve is a project structure like:

project
    +- app
      +- components
    +- android
    +- ios
    +- web

Where app/components contain most of the common code that we write, which can be re-used by android/ios (from react-native) and web is a Spring boot project which can use stuff from app/components as well with react-native-web to package a JS that can be hosted on the web.

Let's say I want to create a layout that I would like to use everywhere:

import {View, Text} from 'react-native'

class MyView extends Component {
    render() {
        return (
            <View><Text>Welcome!</Text></View>
        );
    }
}

I am assuming that react-native will be loaded as required from the node_modules in the specific projects (react-native-web for web and react-native for ios/android).

Now, how do I import this created view in all three of the projects? I am not sure if this is the best project structure there is. What would be the right way to do this? Should app have it's own package.json? Even if it does, I don't believe npm supports sub-projects as well as gradle does (I know, apples to oranges comparison, but I don't think a build-system like gulp/webpack also does, please correct me if I'm wrong).

EDIT

So I experimented with this a bit. The problem is that I cannot have the following structure:

project
    app
    android
    ios
    web
       package.json
    package.json

If there are any packages common in web/package.json and package.json I am getting a Duplicate module name: AutoFocusUtils, from probably node-haste (which appears to be some dep management system built at facebook).

Also, for some reason, when building web from webpack somehow requires me to have the babel-preset-* and react-native dependencies in the context of app, which is still fine, I guess I can work that out later.

So I moved it around a bit:

project
    app
        package.json
    native
        android
        ios
        index.android.js
        index.ios.js
        package.json
    web
        package.json

Everything was fine, but from index.android.js, I can no longer do this:

import MyView from './../app/myview'

I get an error on the phone saying Requiring unknown module ./../app/myview. However, it works just fine from web (while building with webpack). My webpack.config in case it helps: http://pastebin.com/RzmWDgFe

EDIT

I finally reached a code structure that we are happy with. In case anyone comes here looking for a working solution: http://git.nomadly.in/rohan/react-native-tri-platform-starter

Upvotes: 0

Views: 303

Answers (1)

Daniel Schmidt
Daniel Schmidt

Reputation: 11921

You are right; code reuse is a major selling point. As you probably know the react native packager uses the .ios.js or .android.js File ending to determine which version to load. So IMHO the best way to structure your code is to have a structure like you suggested with web, android, ios only including the specific files for the platforms (HTML, Xcode project, etc.) and all react components in the app/components directory. For best reuse you should write your top level components (and all other that are possible) to be independent from the system and include minimal components (e.g. Headline, FullscreenImage, etc.) which then are platform dependent.

Upvotes: 1

Related Questions