我应该如何配置create-react-app来从子目录中提供app?

时间:2018-03-22 13:26:06

标签: reactjs webpack single-page-application create-react-app

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

7 个答案:

答案 0 :(得分:6)

您应该为此在package.json中添加条目。

在您的 package.json 中添加关键的“首页”:“您的子文件夹/” 所有静态文件将从“您的子文件夹”中加载

如果没有子文件夹,并且需要从同一文件夹加载,则需要将路径添加为“ ./”

"homepage": "./"

来自here

答案 1 :(得分:2)

除了您的要求之外,我还要添加我的

  • 应该由CD通过env变量来完成。
  • 如果我需要重命名子目录,则只需要更改env变量即可。
  • 它应该与react-router一起使用。
  • 它应该与scss(sass)和html一起使用。
  • 一切都应该在开发人员模式下正常运行(npm start)。

不久前我还不得不在Angular2 +项目中实现它,我发现在React中实现的难度要比在Angular2 +中更适合使用ng build --base-href /<project_name>/的位置。 source


简短版

  1. 在构建之前,将PUBLIC_URL的env变量设置为子目录的值,以/subdir为例。您还可以将此变量放入.env.productionin case you do not have that file you can check the doc
  2. public/index.html中添加以下基本元素,该元素用于图像之类的静态文件。
<base href="%PUBLIC_URL%/">
  1. public/index.html中,如果您有自定义的link元素,请确保它们以%PUBLIC_URL%为前缀(例如manifest.jsonfavicon.ico href)。 / li>
  2. 如果您使用BrowserRouter,则可以添加basename道具:
<BrowserRouter basename={process.env.PUBLIC_URL} />
  1. 如果您改用Router,因为您需要访问history.push方法,以编程方式更改页面,请执行以下操作:
// 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文件,则可能不需要这样做):
/*remove that*/
background-image: url('/assets/background-form.jpg');
<section style={{backgroundImage: `url('assets/background-form.jpg')`}}>
...

您应该完成。


其他信息

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

PUBLIC_URL覆盖homepage,并且PUBLIC_URL也采用域名(如果您提供的话)。如果仅设置homepage,则PUBLIC_URL将设置为homepage的值。


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


Sass不会使用错误的相对路径进行编译。由于../public/assets的限制,它也不会以正确的相对路径编译到您的ModuleScopePlugin文件夹,您可以通过将图像移到src文件夹中来避免这种限制,我没有尝试过。 / p>


似乎没有办法在开发模式(npm start)中测试相对路径。 see comment


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

答案 2 :(得分:2)

要获取相对 URL,您可以像这样构建应用程序:

PUBLIC_URL="." npm run build

答案 3 :(得分:0)

也许您可以使用react-router及其相对 basename参数,该参数允许您从子目录中提供应用。

basename是所有地点的基本网址。如果您的应用程序是从服务器上的子目录提供的,则需要将其设置为子目录。格式正确的基本名称应该有一个前导斜杠,但没有斜杠。

例如:

<BrowserRouter basename="/calendar"/>

因此<Link to="/today"/>将呈现<a href="/calendar/today">

请参阅:https://reacttraining.com/react-router/web/api/BrowserRouter/basename-string

度过美好的一天!

答案 4 :(得分:0)

将package.json放入这样的内容:

<强>&#34;主页&#34; :&#34; http://localhost:3000/subfolder&#34;,

并在任何公共或本地服务器上正常工作。当然,子文件夹必须是您的文件夹。

答案 5 :(得分:0)

对于create-react-app v2和react-router v4,我使用以下组合在“ / app”下为生产(登台,uat等)应用服务:

package.json:

 # returns the elapsed milliseconds since the start of the program
 def millis(year,month,day,hour,minute):
   dt = datetime(year,month,day,hour, minute) - start_time
   ms = (dt.days * 24 * 60 * 60 + dt.seconds) * 1000 + dt.microseconds / 1000.0
   return round(ms)

然后在应用程序入口点:

"homepage": "/app"

一切都可以在本地开发环境和部署环境中“正常工作”。 HTH!

答案 6 :(得分:-1)

您可以在webpack配置中指定公共路径以及使用react route basepath。

指向公共路径的链接:https://webpack.js.org/guides/public-path/

请注意,公共路径将是前导和尾随斜杠/有效。