除了您的要求,我还添加了我的:
- 应该由 CD 通过一个环境变量来完成。
- 如果我需要重命名子目录,我应该只需要更改 env 变量。
- 它应该与 react-router 一起使用。
- 它应该适用于 scss (sass) 和 html。
- 一切都应该在开发模式下正常工作(npm start)。
不久前我还必须在 Angular2+ 项目中实现它,我发现在 React 中实现它比在 Angular2+ 中实现它更难,你可以使用 ng build --base-href /<project_name>/。 source
短版
- 在构建之前,将
PUBLIC_URL 环境变量设置为您的子目录的值,例如使用/subdir。您也可以将此变量放入您的.env.production (in case you do not have that file you can check the doc)
- 在
public/index.html 中添加下面的基本元素,这是用于图像等静态文件的。
<base href="%PUBLIC_URL%/">
- 同样在
public/index.html 中,如果您有自定义link 元素,请确保它们以%PUBLIC_URL% 为前缀(如manifest.json 和favicon.ico href)。
- 如果你使用
BrowserRouter,可以添加basename prop:
<BrowserRouter basename={process.env.PUBLIC_URL} />
- 如果您改用
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>
- 在元素中使用相对链接
<!-- "./assets/quotes.png" is also ok, but "/assets/quotes.png" is not -->
<img src="assets/quotes.png" alt="" />
- 将您的
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 上设置的环境变量来设置子目录。关于该主题的相关资源:
PUBLIC_URL 覆盖homepage,PUBLIC_URL 也取域名,如果你提供的话。如果只设置homepage,PUBLIC_URL 将设置为homepage 的值。
如果您不想在 index.html 中使用基本元素(我不知道为什么),您需要自己将 process.env.PUBLIC_URL 附加到每个链接。请注意,如果您有带有基本元素的 react-router,但尚未设置 basename 属性,您将收到警告。
Sass 不会使用不正确的相对路径进行编译。它也不会以正确的相对路径编译到您的../public/assets 文件夹,因为ModuleScopePlugin 的限制,您可以通过将图像移动到 src 文件夹中来避免限制,我没有尝试过。
似乎无法在开发模式下测试相对路径(npm start)。 see comment
最后,这些stackoverflow链接有相关问题: