react-native-macos icon indicating copy to clipboard operation
react-native-macos copied to clipboard

How do I add react-native-macos to an existing React Native project?

Open ndbroadbent opened this issue 7 years ago • 21 comments

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 avatar May 17 '17 14:05 ndbroadbent

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

ndbroadbent avatar May 17 '17 15:05 ndbroadbent

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.

ptmt avatar May 18 '17 07:05 ptmt

Oh wow, thanks! I didn't know that existed. I'll try it out.

On 18 May 2017, 2:13 PM +0700, Dima Loktev [email protected], wrote:

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 (https://github.com/ptmt/react-native-macos/pull/163), so it might change a bit.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub (https://github.com/ptmt/react-native-macos/issues/164#issuecomment-302320951), or mute the thread (https://github.com/notifications/unsubscribe-auth/AAIhELyPQHwTMIb07Ag_0_s2xoTsGh_0ks5r6--PgaJpZM4Nd62J).

ndbroadbent avatar May 18 '17 07:05 ndbroadbent

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.

Pagebakers avatar Oct 25 '17 14:10 Pagebakers

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

ptmt avatar Oct 25 '17 16:10 ptmt

@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.

antondomratchev avatar Oct 26 '17 04:10 antondomratchev

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

ptmt avatar Oct 26 '17 08:10 ptmt

{
  "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.

antondomratchev avatar Oct 26 '17 14:10 antondomratchev

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.

ptmt avatar Oct 26 '17 16:10 ptmt

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 avatar Nov 20 '17 06:11 JosephAustin

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?

JosephAustin avatar Nov 20 '17 06:11 JosephAustin

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.

ptmt avatar Nov 20 '17 08:11 ptmt

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 avatar Nov 20 '17 23:11 JosephAustin

Now trying with a fresh project...

JosephAustin avatar Nov 20 '17 23:11 JosephAustin

It... it worked.

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

JosephAustin avatar Nov 21 '17 00:11 JosephAustin

Okay, so to answer this thread!

  1. Have a regular react project, we call it #1
  2. react-native-macos init to get your macos project, we call it #2
  3. Copy macos folder from #2 to #1
  4. Also place rn-cli.config.js inside #1
  5. Copy hidden files from #2 to #1 and overwrite. Probably only need babelrc
  6. Edit #1's package.json to include the dependencies and devdependencies of #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 #2
  9. react-native-macos run-macos

JosephAustin avatar Nov 21 '17 00:11 JosephAustin

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 avatar Nov 21 '17 00:11 JosephAustin

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

JosephAustin avatar Nov 21 '17 07:11 JosephAustin

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?

ptmt avatar Nov 21 '17 07:11 ptmt

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.

manodupont avatar Feb 17 '18 21:02 manodupont

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 https://github.com/ptmt/react-native-macos/issues/164#issuecomment-339545000 https://github.com/ptmt/react-native-macos/issues/164#issuecomment-345874097

I try all above solution but it not work

AkshayP8140 avatar Sep 24 '19 06:09 AkshayP8140