将Expo React Native Web应用部署到子文件夹

huangapple go评论59阅读模式
英文:

Deploy Expo React Native Web app to a subfolder

问题

我尝试在移动应用程序部署到子文件夹的 Web 服务器上时也使其正常工作。

我正在尝试使用 Expo 及其 create-expo-app 样板来创建一个通用应用程序(原生设备和 Web),该样板使用 React Native 和 React Native for Web。

当我部署到我的 Web 服务器时,它不会在根目录中,而是在一个子文件夹中。当我构建(npx expo build:web),上传到服务器并浏览到 https://<myserver>/subfolder 时,我收到一条消息 This screen doesn't exist。有一个链接 Go to home screen!,它会更改浏览器的 URL,删除 subfolder。应用程序功能正常,但 URL 不包括 subfolder。因此,这是一个路由/链接问题。

我已经在我的 package.json 中添加了一个属性:

  "homepage": "/subfolder",

我已经在其他地方看到,<Router><BrowserRouter> 可以添加一个属性,比如 basename={'subfolder'},但是在 Expo 和 React Native 中,没有 Router/BrowserRouter 组件。这个样板似乎使用了完全不同的范例,使用了 @react-navigation/native 中的 NavigationContainer

编辑: 一个重现这个问题的简单方法是运行 create-expo-app,然后在 package.json 中将 homepage 设置为 /web-build/。运行 npx expo export:web 来填充 web-build 文件夹,然后运行 npx servepy -m http.server 或其他一些轻量级的 Web 服务器在当前文件夹中。浏览到 http://localhost:port/web-build/ 会产生我描述的行为。

英文:

How can I have my mobile app also work when deployed to a web server in a subfolder?

I'm trying to create a universal app (native devices and web) using Expo and its create-expo-app boilerplate, which uses React Native and React Native for Web.

When I deploy to my web server, it will not be in the root, rather in a subfolder. When I build (npx expo build:web), upload to my server, and browse to https://&lt;myserver&gt;/subfolder I get a message This screen doesn't exist. There is a link to Go to home screen! which changes the browser URL, removing subfolder. The app functions correctly, but the URL does not include subfolder. Thus, this is a routing/linking issue.

I've added a property to my package.json:

  &quot;homepage&quot;: &quot;/subfolder&quot;,

I have seen elsewhere that &lt;Router&gt; or &lt;BrowserRouter&gt; can be given an attribute like basename={&#39;subfolder&#39;}, but with Expo and React Native there is no Router/BrowserRouter component. The boilerplate seems to use a completely different paradigm with NavigationContainer from @react-navigation/native.

Edit: An easy way to reproduce this is to run create-expo-app, then set homepage to /web-build/ in package.json. Run npx expo export:web which populates the web-build folder, then run npx serve or py -m http.server or some other lightweight web server in the current folder. Browsing to http://localhost:port/web-build/ yields the behavior I described.

答案1

得分: 0

Sure, here's the translation of the code-related content:

首先,在 package.json 中将 homepage 属性更改为一个点(即 &quot;homepage&quot;: &quot;.&quot;)。这使文件引用相对于当前目录。有人争论不应该这样做,但似乎有效。

其次,在定义屏幕的地方,使用一个变量来表示根路径。例如:

import { Platform } from 'react-native';

var baseURL = '';
if (Platform.OS === 'web') baseURL = '/subfolder';

const linking: LinkingOptions<RootStackParamList> = {
  prefixes: [Linking.createURL('/')],
  config: {
    screens: {
      Root: {
        path: baseURL, // <- 此行已添加
        screens: {
          TabOne: {
            screens: {
              TabOneScreen: 'one',
            },
          },
          TabTwo: {
            screens: {
              TabTwoScreen: 'two',
            },
          },
        },
      },
      Modal: 'modal',
      NotFound: '*',
    },
  }
};

Please note that I've translated the code, and you should still use the original code for your development needs.

英文:

I have a two-part solution, but I still don't know if this is the canonical way it should be done.

First, in package.json change the homepage property to just a dot (i.e. &quot;homepage&quot;: &quot;.&quot;). This makes file references relative to the current directory. I've seen some people argue against doing this, but it seems to work.

Second, where your screens are defined use a variable for the root path. For example:

import { Platform } from &#39;react-native&#39;;

var baseURL = &#39;&#39;;
if (Platform.OS == &#39;web&#39;) baseURL = &#39;/subfolder&#39;;

const linking: LinkingOptions&lt;RootStackParamList&gt; = {
  prefixes: [Linking.createURL(&#39;/&#39;)],
  config: {
    screens: {
      Root: {
        path: baseURL, // &lt;- This line was added
        screens: {
          TabOne: {
            screens: {
              TabOneScreen: &#39;one&#39;,
            },
          },
          TabTwo: {
            screens: {
              TabTwoScreen: &#39;two&#39;,
            },
          },
        },
      },
      Modal: &#39;modal&#39;,
      NotFound: &#39;*&#39;,
    },
  }
};

huangapple
  • 本文由 发表于 2023年3月21日 01:43:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75793589-2.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定