我在 ReactJS 应用程序中使用 webpack 时遇到问题。
在 URL 上,只有一个端点,例如 http://localhost:8000/login 我的徽标图像可以正确加载,但如果我输入的 URL 超过一层深度,例如: http:// /localhost:8000/reset/forgot 它不会下载 SVG 并且图像不会加载。
加载图像的图像标记对于两个 URL 是相同的(它位于我的标题上,因此应该加载到所有页面)。
如果我检查 SVG 下载请求,则尝试从 http://localhost:8000/reset/assets/Logo_WHT.svg 而不是 http://localhost:8000/assets/Logo_WHT.svg 获取图像。
这是我的 webpack 配置:
const path = require("path");
const webpack = require("webpack");
const os = require("os");
var config = {
entry: {
index: "./src/index.js"
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
publicPath: "/",
},
module: {
rules: [
{
resolve: {
fallback: {
"http": require.resolve("stream-http"), // install 'stream-http'
"https": require.resolve("https-browserify"), // install 'https-browserify'
"vm": require.resolve("vm-browserify"), // install 'os-browserify'
"os": require.resolve("os-browserify/browser"), // install 'vm-browserify'
"buffer": require.resolve("buffer/"), // install 'buffer'
"url": false,
"constants": false,
}
}
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
["@babel/preset-env", {
targets: [
"last 2 versions",
"ie 11",
"not dead",
"> 0.5%"
]
}],
"@babel/preset-react"
]
}
}
},
{
test: /\.(png|jp(e*)g|svg|gif)$/,
type: "asset/resource"
},
{
test: /\.less$|\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
plugins: [
],
};
最初我使用 file-loader 来加载文件,但在 webpack 5.x.x 上不再推荐,所以我更改为 asset/resource (如文档中所述)。
我希望从根文件夹“assets”加载所有文件
您遇到的问题与相对 URL 在 HTML 中的工作方式有关。当您在
http://localhost:8000/reset/forgot
之类的页面上尝试加载具有 assets/Logo_WHT.svg
之类的相对 URL 的图像时,浏览器将尝试从 http://localhost:8000/reset/assets/Logo_WHT.svg
加载图像。
要解决此问题,您可以使用资产的绝对路径。对于您的情况,您可以在资产 URL 前面添加
/
,使它们相对于您网站的根目录。这样,assets/Logo_WHT.svg
就变成了 /assets/Logo_WHT.svg
,浏览器将尝试从 http://localhost:8000/assets/Logo_WHT.svg
加载图像,无论当前页面的 URL 是什么。
但是,这需要您的 webpack 配置设置为正确处理此问题。在您的 webpack 配置中,您已在
publicPath: "/"
对象中设置了 output
。这意味着 webpack 将为您的资产生成相对于站点根目录的 URL,这正是您想要的。
所以,在你的 React 组件中,你应该导入你的 SVG 并像这样使用它:
import Logo from './assets/Logo_WHT.svg';
// In your render method
<img src={Logo} alt="Logo" />
Webpack 将负责捆绑 SVG 文件并用正确的 URL 替换
Logo
。