Skip to content
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 add react-native-macos to an existing React Native project? #164

Open
ndbroadbent opened this issue May 17, 2017 · 21 comments
Open
Labels

Comments

@ndbroadbent
Copy link

ndbroadbent commented May 17, 2017

I have an existing React Native project with iOS, Android, Windows, and web. I would also like to experiment with support for MacOS.

Is there a command I can run that will add a "mac" directory? It would be great if the README could be updated with these instructions.

EDIT: Ok it wasn't too hard, I just ran the init command, then copied macos into my app, and updated my package.json to include react-native-macos.

EDIT 2: Ok damn, now I'm getting a ton of these errors:

This error is caused by a @providesModule declaration with the same name across two different files.
Error: @providesModule naming collision:
  Duplicate module name: ReactNative
  Paths: <myapp>/node_modules/react-native-macos/Libraries/react-native/ReactNative.js collides with <myapp>/node_modules/react-native/Libraries/Renderer/src/renderers/native/ReactNative.js 

Do I need to replace react-native with react-native-macos? Would it be possible for you to fix this in a similar way to react-native-windows?

@ndbroadbent
Copy link
Author

Sorry I just saw #65. A big +1 to that.

@ptmt
Copy link
Owner

ptmt commented May 18, 2017

You can add rn-cli.config.js for handling these issues. Something like this worked for me https://gist.github.com/ptmt/b1473dead098cf53d667e355aedf2a7b (though, it's quite old, worked with the RN 10 months ago. Now I'm working on #163, so it might change a bit.

@ndbroadbent
Copy link
Author

ndbroadbent commented May 18, 2017 via email

@Pagebakers
Copy link
Collaborator

Pagebakers commented Oct 25, 2017

I've added the project successfully to my existing RN project, but I'm running into one last issue when trying to run the app.

The React-Packager is throwing this error:

error: bundling: UnableToResolveError: Unable to resolve module `react-native` from `/Users/**/index.macos.js`: Module does not exist in the module map or in these directories:
  /Users/**/node_modules

The path is correct and react-native exists.

index.macos.js

import { AppRegistry, StyleSheet, Text, View } from 'react-native';

When I change 'react-native' to 'react-native-macos' It's all working just fine. Isn't 'react-native' supposed to resolve to macos automatiscally by the mac cli?

How to fix this? obviously I want to import from 'react-native' so I can share components between platforms.

@ptmt
Copy link
Owner

ptmt commented Oct 25, 2017

You're right. There is a specific babel resolver for making that alias. Could you please check that you have installed babel plugins and this config in your package.json or .babelrc? https://github.com/ptmt/react-native-macos/blob/master/local-cli/templates/HelloWorld/_babelrc

@antondomratchev
Copy link

@ptmt Tried adding the above mentioned babelRC config and it doesn't seem to have solved the issue.
.babelrc

{
  "presets": [
    "react-native-stage-0"
  ],
  "plugins": [
    ["module-resolver", {
      "alias": {
        "react-native": "react-native-macos",
      }
    }]
  ]
}

rn-cli.config.js

const path = require('path');

// Don't forget to everything listed here to `package.json`
// modulePathIgnorePatterns.
const sharedBlacklist = [
  /node_modules[/\\]react[/\\]dist[/\\].*/,

  'downstream/core/invariant.js',

  /website\/node_modules\/.*/,

  // TODO(jkassens, #9876132): Remove this rule when it's no longer needed.
  'Libraries/Relay/relay/tools/relayUnstableBatchedUpdates.js',
];

const platformBlacklists = {
  web: [
    '.ios.js',
    '.android.js',
  ],
  ios: [
    '.web.js',
//    '.android.js',
    /node_modules\/react-native-macos\/.*/,
  ],
  android: [
    '.web.js',
    '.ios.js',
    /node_modules\/react-native-macos\/.*/,
  ],
  macos: [
    '.ios.js',
    '.android.js',
    /node_modules\/react-native\/.*/,
  ],
};

function escapeRegExp(pattern) {
  if (Object.prototype.toString.call(pattern) === '[object RegExp]') {
    return pattern.source.replace(/\//g, path.sep);
  } else if (typeof pattern === 'string') {
    const escaped = pattern.replace(/[\-\[\]\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
    // convert the '/' into an escaped local file separator
    return escaped.replace(/\//g, `\\${path.sep}`);
  }
  throw new Error(`Unexpected packager blacklist pattern: ${pattern}`);
}

function blacklist(platform, additionalBlacklist) {
  // eslint-disable-next-line
  return new RegExp('(' +
    (additionalBlacklist || []).concat(sharedBlacklist)
      .concat(platformBlacklists[platform] || [])
      .map(escapeRegExp)
      .join('|') +
    ')$'
  );
}

module.exports = {
  getBlacklistRE(platform) {
    if (process && process.argv.filter(a => a.indexOf('react-native-macos') > -1).length > 0) {
      return blacklist('macos')
    }
    return blacklist(platform);
  },
};

Please let me know if there is anything I am missing.

@ptmt
Copy link
Owner

ptmt commented Oct 26, 2017

Could you please post your package.json also? And add something like `"react-native-test": "react-native-macos", to babel config resolver section?

@antondomratchev
Copy link

{
  "name": "PROJECT_NAME",
  "version": "0.1.0",
  "private": true,
  "engines": {
    "node": ">=8.1.0",
    "npm": ">=5.1.0"
  },
  "devDependencies": {
    "babel-eslint": "^8.0.0",
    "babel-plugin-module-resolver": "^2.7.1",
    "eslint": "^4.6.1",
    "eslint-config-airbnb": "^15.1.0",
    "eslint-plugin-babel": "^4.1.2",
    "eslint-plugin-import": "^2.7.0",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "eslint-plugin-react": "^7.3.0",
    "react-test-renderer": "16.0.0-alpha.6",
    "reactotron-react-native": "^1.11.1",
    "reactotron-redux": "^1.11.2",
    "rn-nodeify": "mvayngrib/rn-nodeify",
    "rnpm-plugin-windows": "^0.2.7"
  },
  "scripts": {
    "start": "react-native start",
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "macos": "react-native-macos run-macos",
    "test": "node node_modules/jest/bin/jest.js --watch",
    "postinstall": "./node_modules/.bin/rn-nodeify --install crypto,stream,vm --hack",
    "lint": "node_modules/eslint/bin/eslint.js src/",
    "lint-fix": "node_modules/eslint/bin/eslint.js src/ --fix"
  },
  "jest": {
    "preset": "react-native",
    "setupFiles": [
      "./setupJest.js"
    ],
    "transformIgnorePatterns": [
      "node_modules/(?!react-native)/"
    ]
  },
  "dependencies": {
    "assert": "^1.4.1",
    "babel-jest": "^20.0.3",
    "babel-preset-env": "^1.6.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react-native-stage-0": "^1.0.1",
    "base-64": "^0.1.0",
    "browserify-sign": "^4.0.4",
    "csv-string": "^2.3.2",
    "events": "^1.1.1",
    "fuzzy": "^0.1.3",
    "immutability-helper": "^2.3.0",
    "immutable": "3.7.6",
    "jest": "^20.0.4",
    "path-browserify": "0.0.0",
    "process": "^0.11.10",
    "pwgenjs": "^0.0.1",
    "react": "16.0.0-alpha.6",
    "react-immutable-proptypes": "^2.1.0",
    "react-native": "^0.44.0",
    "react-native-crypto": "^2.0.2",
    "react-native-document-picker": "^2.1.0",
    "react-native-fabric": "^0.5.0",
    "react-native-file-provider": "^1.0.2",
    "react-native-fs": "^2.8.0",
    "react-native-keyboard-aware-scroll-view": "^0.2.9",
    "react-native-keychain": "^1.2.0",
    "react-native-macos": "^0.16.0",
    "react-native-randombytes": "GrokInteractive/react-native-randombytes",
    "react-native-router-flux": "^3.38.0",
    "react-native-sensitive-info": "^5.2.0",
    "react-native-timer": "^1.3.1",
    "react-native-vector-icons": "^4.2.0",
    "react-native-windows": "0.44.0-rc.3",
    "react-redux": "^5.0.5",
    "readable-stream": "^1.0.33",
    "redux": "^3.6.0",
    "redux-persist": "^4.8.2",
    "redux-persist-transform-immutable": "^4.3.0",
    "stream-browserify": "^1.0.0",
    "timers-browserify": "^1.4.2",
    "tty-browserify": "0.0.0",
    "url": "^0.10.3",
    "util": "^0.10.3",
    "uuid-js": "^0.7.5",
    "vm-browserify": "0.0.4"
  },
  "react-native": {
    "crypto": "react-native-crypto",
    "path": "path-browserify",
    "_stream_transform": "readable-stream/transform",
    "_stream_readable": "readable-stream/readable",
    "_stream_writable": "readable-stream/writable",
    "_stream_duplex": "readable-stream/duplex",
    "_stream_passthrough": "readable-stream/passthrough",
    "stream": "stream-browserify",
    "timers": "timers-browserify",
    "tty": "tty-browserify",
    "vm": "vm-browserify"
  },
  "browser": {
    "crypto": "react-native-crypto",
    "path": "path-browserify",
    "_stream_transform": "readable-stream/transform",
    "_stream_readable": "readable-stream/readable",
    "_stream_writable": "readable-stream/writable",
    "_stream_duplex": "readable-stream/duplex",
    "_stream_passthrough": "readable-stream/passthrough",
    "stream": "stream-browserify",
    "timers": "timers-browserify",
    "tty": "tty-browserify",
    "vm": "vm-browserify"
  }
}

I'v redacted a few things from the list, but most of the relevant things are in there.

@ptmt
Copy link
Owner

ptmt commented Oct 26, 2017

See this project I just forked to demonstrate cross-platform capability https://github.com/ptmt/react-native-nw-react-calculator I just tried and packager correctly resolves react-native as react-native-macos. If you could add something to this project to stop it working that would be helpful to understand the reason behind this. Try to use other babel plugins or aliases just to ensure that babel respect this config section.

@JosephAustin
Copy link

Even changing it to directly use react-native-macos now gives me this error:

error: bundling: UnableToResolveError: Unable to resolve module PickerAndroid from ....../node_modules/react-native/Libraries/Components/Picker/Picker.js

@JosephAustin
Copy link

The above error also occurs using react-native-macos run-macos on the nw calculator, though I see it is made to be served through nw and electron. But maybe that's a clue as to what's causing it?

@ptmt
Copy link
Owner

ptmt commented Nov 20, 2017

it seems that eighter babel resolver or rn-cli.config.js that I added there doesn't work. So you pulled https://github.com/ptmt/react-native-nw-react-calculator this, made yarn install and have this error? Try to do react-native-macos start --reset-cache also to make sure it's not related to cache.

@JosephAustin
Copy link

I don't think it's Babel because that is just for aliasing (right?), I went into the app file and changed it to explicitly look in react-native-macos so that should be where it looks.

I didn't try it with yarn, i just did npm install and then attempted to run it. Doing it exactly as you just specified worked.

@JosephAustin
Copy link

Now trying with a fresh project...

@JosephAustin
Copy link

It... it worked.

yarn install to get your packages works, npm install doesn't. That's an interesting tidbit.

@JosephAustin
Copy link

JosephAustin commented Nov 21, 2017

Okay, so to answer this thread!

  1. Have a regular react project, we call it Roadmap 0.1.0 #1
  2. react-native-macos init to get your macos project, we call it License #2
  3. Copy macos folder from License #2 to Roadmap 0.1.0 #1
  4. Also place rn-cli.config.js inside Roadmap 0.1.0 #1
  5. Copy hidden files from License #2 to Roadmap 0.1.0 #1 and overwrite. Probably only need babelrc
  6. Edit Roadmap 0.1.0 #1's package.json to include the dependencies and devdependencies of License #2 that are not present there
  7. yarn install --- NOT npm install
  8. You need to make sure to register the app in your startup file, as index.macos.js does in License #2
  9. react-native-macos run-macos

@JosephAustin
Copy link

I want to point out by the way that create-react-native-app uses App.js and you need to go modify the xcode project to look for 'App' where it looks for index.macos

@JosephAustin
Copy link

This approach led to some problems when i then tried to run ios. I'll try again tomorrow I suppose.

@ptmt
Copy link
Owner

ptmt commented Nov 21, 2017

I don't think it's Babel because that is just for aliasing (right?), I went into the app file and changed it to explicitly look in react-native-macos so that should be where it looks.

Actually, react-native-macos imports itself modules as react-native inside, so it's relying on this babel aliasing.

Thanks for detailing description. Any chance that I can have a look at the project itself?

@manodupont
Copy link

Where are we with that! I would Loooooveeee to see my react-native have three target. macos, ios, and android. And have three separate npm script so i can start all three target and hot reload all three at the same time. Never been able to do so yet.
I am capable of starting one or another, depending of (not quite sure yet) .babelrc and, the presence or "not" of rn-cli-.config.js.

If both are there, i can run macos, but not ios. If i dont have rn-cli.config.js, AND, remove babelrc module resolver plugins, then i can run ios, but not macos.

There is definitely something feasible here, but i can't put my hand on it.

@AkshayP8140
Copy link

AkshayP8140 commented Sep 24, 2019

Any one can give me a full procedure for make react-native-macos in react-native running iOS/android project and make three target(macOS,ios,android)

https://github.com/ptmt/react-native-macos
https://gist.github.com/ptmt/b1473dead098cf53d667e355aedf2a7b#file-rn-cli-config-js-L65
#164 (comment)
#164 (comment)

I try all above solution but it not work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants