webpack 我应该如何配置create-react-app以从子目录提供应用程序?

j9per5c4  于 2023-03-12  发布在  Webpack
关注(0)|答案(9)|浏览(168)

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

kq4fsx7k

kq4fsx7k1#

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

  • 它应该由CD通过env变量完成。
  • 如果我需要重命名子目录,我只需要修改env变量。
  • 它应该与React路由器一起工作。
  • 它应该可以与scss(sass)和html一起工作。
  • 在dev模式下一切都应该正常工作(npm start)。

不久前,我还不得不在Angular2+项目中实现它,我发现在React中实现它比在Angular2+中实现要困难,因为在Angular2+中使用ng build --base-href /<project_name>/是很好的选择。源代码

简短版本

1.在构建之前,将PUBLIC_URL env变量设置为您的子目录的值,例如使用/subdir。您也可以将此变量放入您的.env.productionin case you do not have that file you can check the doc
1.在public/index.html中添加下面的基本元素,这是针对静态文件(如图像)的。

<base href="%PUBLIC_URL%/">

1.同样在public/index.html中,如果您有自定义的link元素,请确保它们的前缀为%PUBLIC_URL%(如manifest.jsonfavicon.ico href)。
1.如果使用BrowserRouter,则可以添加basename prop:

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

1.如果使用Router,因为您需要访问history.push方法,要以编程方式更改页,请执行以下操作:
一个二个一个一个
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')`}}>
...

你应该结束了

附加信息

package.json中,我更喜欢使用PUBLIC_URL而不是homepage,因为我想使用gitlab上的env变量set来设置subdir。

PUBLIC_URL覆盖homepage,并且PUBLIC_URL也采用域名(如果您提供)。如果您只设置homepage,则PUBLIC_URL将设置为homepage的值。
如果你不想在index.html中使用一个基本元素(我不知道为什么),你需要自己在每个链接上添加process.env.PUBLIC_URL.注意如果你有一个基本元素的react-router,但是没有设置basename prop,你会得到一个警告.
如果相对路径不正确,Sass将无法编译,如果相对路径正确,也无法编译到../public/assets文件夹,因为ModuleScopePlugin的限制,你可以通过移动src文件夹中的图像来避免限制,我还没有尝试过。
在开发模式下似乎没有办法测试相对路径(npm start)。
最后,这些堆栈溢出链接存在相关问题:

t9eec4r0

t9eec4r02#

对于create-react-app v2和react-router v4,我使用以下组合在“/app”下提供生产(staging、uat等)应用:
package.json:

"homepage": "/app"

然后在应用程序入口点中:

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

所有的东西都可以在本地开发环境和部署环境中“正常工作”。

eqoofvh9

eqoofvh93#

您应该为此在package.json中添加条目。
添加一个关键“主页”:* *package.json中的“your-subfolder/”**所有静态文件都将从“your-subfolder”加载
如果没有子文件夹,并且需要从同一文件夹加载,则需要添加路径“./”或删除包含"homepage": "xxxxxxxxxx"的整行
"homepage": "./"

来自官方文件

默认情况下,“创建React应用”会生成一个构建版本,假设您的应用托管在服务器根目录下。要覆盖此设置,请在package.json中指定主页,例如:
“主页”:“http://mywebsite.com/relativepath“,

**注意:**如果您使用的是react-router@^4,则可以使用任何<Router>上的基本名称属性来路由<Link>

here开始,同时检查官方CRA文件

lbsnaicq

lbsnaicq4#

要获取相对URL,您可以按如下方式构建应用:

PUBLIC_URL="." npm run build
dba5bblo

dba5bblo5#

在package.json中放入如下内容:

“主页”:“http://localhost:3000/subfolder“,

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

yjghlzjz

yjghlzjz6#

也许您可以使用react-router及其 relativebasename参数,该参数允许您从子目录提供应用。
basename是所有位置的基URL。如果你的应用是从服务器上的子目录提供的,你需要将此设置为子目录。格式正确的基名称应具有前导斜杠,但没有尾随斜杠。
例如:

<BrowserRouter basename="/calendar"/>

因此<Link to="/today"/>将渲染<a href="/calendar/today">
参见:https://reacttraining.com/react-router/web/api/BrowserRouter/basename-string

ql3eal8s

ql3eal8s7#

在我们的例子中,我们按照Ambroise's answer中的描述做了所有的事情,但是在生产中得到了一个空白页面,在控制台中没有任何错误或警告。这原来是BrowserRouter的问题-我们通过如下设置BrowserRouter的basename来使它工作:

<BrowserRouter basename="/our_subfolder/" />
llew8vvj

llew8vvj8#

按照以下步骤从子目录提供react应用程序。

  • package.json文件中添加homepage条目。
"homepage": "xyz/",
  • 如果从子目录提供应用程序,请更改基本路由名称。
<BrowserRouter basename={"/xyz"}>
    <Routes/>
</BrowserRouter>
  • 如果你使用Nginx服务器,那么你必须指定如下位置,
location /xyz {
          alias /build-folder-path;
          try_files $uri /$uri /xyz/index.html;
  }

注意:xyz是子目录名。

lkaoscv7

lkaoscv79#

您可以在Webpack配置中指定公共路径沿着使用React Route basepath。
链接到公共路径:https://webpack.js.org/guides/public-path/
请注意,公共路径将同时包含前导和尾随斜杠/才有效。

相关问题