Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to deploy a React Native app to Heroku?

Is was wondering if its possible to deploy a React Native app to Heroku? The reason I ask is because then I can retrieve the url and place it in an iframe to mimic an iPhone where the user can then tryout the app without actually having to install it on to the iPhone via iTunes.

like image 623
GY22 Avatar asked Feb 25 '16 03:02

GY22


People also ask

Can you use React with Heroku?

Your React app should now be deployed to Heroku! You can open it directly from the terminal by running heroku open .

What apps can I deploy on Heroku?

Heroku lets you deploy, run and manage applications written in Ruby, Node. js, Java, Python, Clojure, Scala, Go and PHP.

Can I deploy react native app on Web?

Can React Native be used for web and mobile? Yes! With React Native for Web, developers can write a single React Native application that can run natively on Android and iOS, as well as on a web browser using standard web technologies.


1 Answers

This is possible using react-native-web (sources). There are few things that you have to do to set this up on heroku:

  • in the settings tab of your your heroku app dashboard set the buildpack as heroku/nodejs,
  • in package.json set the build script to build your web version from RN sources, for example, if you are using expo: expo build:web,
  • create a Procfile in the root directory to serve the web version: for example, if you used expo, the build directory is web-build and therfore the command should be npx serve web-build,

Additionally, if you use expo, make sure to add the expo-cli as a dev dependency: npm install -D expo-cli.

You will then simply need to push to heroku the usual way. By default, heroku will run yarn build (or npm run build depending on wether you used one or the other to generate your lock file).

In the end, here is what the package.json file might look like (using expo again):

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject",
    "test": "jest --watchAll",
    "build": "expo build:web"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@expo/vector-icons": "^12.0.0",
    "@react-native-community/masked-view": "0.1.10",
    "@react-navigation/bottom-tabs": "^5.11.1",
    "@react-navigation/native": "^5.8.9",
    "@react-navigation/stack": "^5.12.6",
    "expo": "~40.0.0",
    "expo-asset": "~8.2.1",
    "expo-constants": "~9.3.0",
    "expo-font": "~8.4.0",
    "expo-linking": "~2.0.0",
    "expo-splash-screen": "~0.8.0",
    "expo-status-bar": "~1.0.3",
    "expo-web-browser": "~8.6.0",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
    "react-native-gesture-handler": "~1.8.0",
    "react-native-safe-area-context": "3.1.9",
    "react-native-screens": "~2.15.0",
    "react-native-web": "~0.13.12"
  },
  "devDependencies": {
    "expo-cli": "^4.0.16",
    "@babel/core": "~7.9.0",
    "@types/react": "~16.9.35",
    "@types/react-native": "~0.63.2",
    "jest-expo": "~40.0.0",
    "typescript": "~4.0.0"
  },
  "private": true
}

And the Procfile simply consists of a single line:

web: npx serve web-build

You could probably achieve similar results using reactxp instead of reac-native-web, but I never tried it myself.

Client side routing

Configuring Heroku for client side routing

If you use client side routing (react navigation for example), you will have to setup a few more things to make sure linking works. With the previous build alone, client side routing will fail (404 errors) because heroku will try to route requests on its own, but your app needs everything to end up at index.html so it can perform routing tasks on its own (client side routing).

We will thus prevent any Heroku routing by adding a second buildpack heroku-community/static next to heroku/nodejs. This second buildpack is configured via a /static.json file (default values):

{
  "root": "web-build/",
  "clean_urls": false,
  "routes": {
    "/**": "index.html"
  }
}

Configuring webpack for client side routing

You probably already have this part setup because otherwise you would have 404 errors even locally. To allow client side routing it seems like we also need to configure webpack (output.publicPath and devServer.historyApiFallback), with expo this can be done by running expo customize:web and then editing /webpack.config.js with:

const createExpoWebpackConfigAsync = require('@expo/webpack-config');

module.exports = async function (env, argv) {
    const config = await createExpoWebpackConfigAsync(env, argv);
    config.output.publicPath = '/';
    config.devServer = {
        ...config.devServer,
        historyApiFallback: true,
    };
    return config;
};

There is a nice article about these routing issues you might have here: Fixing the 'cannot GET /URL'

like image 162
cglacet Avatar answered Oct 04 '22 17:10

cglacet