我应该如何配置 create-react-app 以从子目录提供应用程序? [英] How should I configure create-react-app to serve app from subdirectory?

查看:17
本文介绍了我应该如何配置 create-react-app 以从子目录提供应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在服务器上呈现了经典的 Web 应用程序.我想在 React 中创建管理面板作为单页应用程序.我想从 https://smyapp.example.com/admin/ 服务器管理面板.我尝试使用 create-react-app 但它假设我从根 URL 提供 SPA.我应该如何配置 create-react-app 以从 "admin" 子目录提供应用程序?在文档中,我找到了 "homepage" 属性,但如果我正确理解它需要完整的 url.我无法提供完整的 url,因为我的应用部署在少数环境中.

I have classic web application rendered on server. I want to create admin panel as single page application in React. I want to server admin panel from https://smyapp.example.com/admin/. I try to use create-react-app but it assumes that i serve SPA from root URL. How should I configure create-react-app to serve app from "admin" subdirectory? In documentation I found "homepage" property but if I properly understand it requires complete url. I can't give complete url because my app is deployed in few environments.

推荐答案

除了你的要求,我还要加上我的:

In addition to your requirements, I am adding mine:

  • 这应该由 CD 通过环境变量完成.
  • 如果我需要重命名子目录,我只需要更改 env 变量即可.
  • 它应该与 react-router 一起使用.
  • 它应该适用于 scss (sass) 和 html.
  • 在开发模式(npm start)下一切都应该正常工作.

不久前我还不得不在 Angular2+ 项目中实现它,我发现在 React 中实现它比在 Angular2+ 中实现更难,在那里你可以使用 ng build --base-href//.来源

I also had to implement it in Angular2+ project not long ago, I found it harder to implement in React then in Angular2+ where you are good to go with ng build --base-href /<project_name>/. source

  1. 在构建之前,将 PUBLIC_URL 环境变量设置为子目录的值,例如使用 /subdir.您也可以将此变量放入您的 .env.production (如果您没有该文件,您可以查看文档)
  2. public/index.html 中添加下面的基本元素,这是用于图像等静态文件.
  1. Before building, set PUBLIC_URL env variable to the value of your subdirectory, let use /subdir for example. You can also put this variable into your .env.production (in case you do not have that file you can check the doc)
  2. In public/index.html add the base element bellow, this is for static files like images.

<base href="%PUBLIC_URL%/">

  1. 同样在 public/index.html 中,如果您有自定义 link 元素,请确保它们以 %PUBLIC_URL% 为前缀(例如manifest.jsonfavicon.ico href).
  2. 如果你使用BrowserRouter,你可以添加basename prop:
  1. Also in public/index.html, if you have custom link element, make sure theyre are prefixed with %PUBLIC_URL% (like manifest.json and favicon.ico href).
  2. If you use BrowserRouter, you can add basename prop:

<BrowserRouter basename={process.env.PUBLIC_URL} />

  1. 如果您使用 Router 代替,因为您需要访问 history.push 方法,以编程方式更改页面,请执行以下操作:
  1. If you use Router instead, because you need access to history.push method, to programmatically change page, do the following:

// history.tsx
import {createBrowserHistory} from 'history';

export default createBrowserHistory({ basename: process.env.PUBLIC_URL });

<!-- Where your router is, for me, App.tsx -->
<Router history={history}>
  ...
</Router>

  1. 在元素中使用相对链接

<!-- "./assets/quotes.png" is also ok, but "/assets/quotes.png" is not -->
<img src="assets/quotes.png" alt="" />

  1. 将您的 background-image 链接从 scss 移动到 jsx/tsx 文件(请注意,如果您使用 css 文件,则可能不需要这样做):
  1. Move your background-image links from scss to jsx/tsx files (note that you may not need to do that if you use css files):

/*remove that*/
background-image: url('/assets/background-form.jpg');

<section style={{backgroundImage: `url('assets/background-form.jpg')`}}>
...

你应该完成了.

我更喜欢在 package.json 中使用 PUBLIC_URL 而不是 homepage 因为我想使用在 gitlab 上设置的 env 变量来设置子目录.关于该主题的相关资源:

I preferred to use PUBLIC_URL instead of homepage in package.json because I want to use env variable set on gitlab to set the subdir. Relevant resources about the subject:

PUBLIC_URL 覆盖 homepage,如果您提供域名,PUBLIC_URL 也会带上域名.如果只设置了homepagePUBLIC_URL 会被设置为homepage 的值.

PUBLIC_URL override homepage, and PUBLIC_URL also take the domain name, if you provide one. If you set only homepage, PUBLIC_URL will be set to the value of homepage.

如果您不想在 index.html 中使用基本元素(我不知道为什么),您需要自己将 process.env.PUBLIC_URL 附加到每个链接.请注意,如果您有带有基本元素的 react-router,但尚未设置 basename 属性,您将收到警告.

If you do not want to use a base element in your index.html (I would not know why), you will need to append process.env.PUBLIC_URL to every link yourself. Note that if you have react-router with a base element, but have not set basename prop, you will get a warning.

Sass 不会使用不正确的相对路径进行编译.它也不会使用 ../public/assets 文件夹的正确相对路径进行编译,因为 ModuleScopePlugin 限制,您可以通过将图像移动到src 文件夹,我没试过.

Sass won't compile with an incorrect relative path. It also won't compile with correct relative path to your ../public/assets folder, because of ModuleScopePlugin restrictions, you can avoid the restriction by moving your image inside the src folder, I haven't tried that.

在开发模式下似乎没有办法测试相对路径(npm start).见评论

There seem to be no way of testing relative path in development mode (npm start). see comment

最后,这些stackoverflow链接有相关问题:

Finnaly, theses stackoverflow link have related issues:

这篇关于我应该如何配置 create-react-app 以从子目录提供应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆