是否可以将React Native应用程序部署到Heroku?

GY2*_*Y22 8 heroku react-native

是否想知道是否有可能将Heract Native应用程序部署到Heroku?我问的原因是因为我可以检索网址并将其放在iframe中以模仿iPhone,然后用户可以试用该应用,而无需通过iTunes将其安装到iPhone上.

cgl*_*cet 5

这可以使用react-native-web (来源)。要在 heroku 上进行设置,您需要做几件事:

  • 在您的 heroku 应用仪表板的设置选项卡中,将 buildpack 设置为heroku/nodejs
  • package.json设置build脚本以从 RN 源构建您的网络版本,例如,如果您使用 expo: expo build:web,
  • 在根目录中创建一个 Procfile 来为 web 版本提供服务:例如,如果您使用 expo,则构建目录是web-build,因此命令应该是npx serve web-build

此外,如果您使用的世博会,一定要添加expo-cli的开发依赖:npm install -D expo-cli

然后,您只需要以通常的方式推送到 heroku。默认情况下,heroku 将运行yarn build(或者npm run build取决于您使用了一个还是另一个来生成您的锁定文件)。

最后,这是package.json文件的样子(再次使用 expo):

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

Run Code Online (Sandbox Code Playgroud)

并且Procfile简单地由一行组成:

web: npx serve web-build
Run Code Online (Sandbox Code Playgroud)

您可能可以使用reactxp而不是reac -native-web 来获得类似的结果,但我自己从未尝试过。

客户端路由

为客户端路由配置 Heroku

如果您使用客户端路由(例如 React 导航),则必须设置更多内容以确保链接有效。单独使用之前的构建,客户端路由将失败(404 错误),因为 heroku 将尝试自行路由请求,但您的应用程序需要一切都结束,index.html以便它可以自己执行路由任务(客户端路由)。

因此,我们将通过在旁边添加第二个 buildpack heroku-community/static防止任何 Heroku 路由。第二个 buildpack 是通过文件(默认值)配置的:heroku/nodejs/static.json

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

Run Code Online (Sandbox Code Playgroud)

为客户端路由配置 webpack

您可能已经设置了这部分,否则即使在本地也会出现 404 错误。为了允许客户端路由,我们似乎还需要配置 webpack(output.publicPathdevServer.historyApiFallback),使用 expo这可以通过运行expo customize:web然后编辑来完成/webpack.config.js

web: npx serve web-build
Run Code Online (Sandbox Code Playgroud)

这里有一篇关于这些路由问题的好文章:修复“无法获取 /URL”