Webpack url-loader 或 file-loader 不起作用反应应用程序
Posted
技术标签:
【中文标题】Webpack url-loader 或 file-loader 不起作用反应应用程序【英文标题】:Webpack url-loader or file-loader not working react app 【发布时间】:2020-02-01 07:54:45 【问题描述】:使用带有 url-loader 或 file-loader 的 Webpack 4 无法在浏览器中加载图像。小图像不在数据 url 中(或者如果它们是浏览器没有显示它们)并且文件网络请求不是通过文件加载器发出的。
nginx 在https://server/images/image_name.png
上正确地提供图像,但在https://server
上没有提供图像,并且在网络检查器网络面板中没有对图像进行网络调用。
目前最好的猜测是 Webpack url-loader 或 file-loader 一定不能生成正确的 URL。为 url 搜索 app.bundle.js 时找不到主机。我已经尝试了好几天 publicPath
、outputPath
等所有其他 *** 帖子的组合,但没有任何效果。
除了搜索js还有什么办法可以查看webpack生成的url? webpack 配置不正确吗?故障排除建议?
这是我在代码中处理图像的方式:
import nav_logo from "Images/white_nav_logo.svg";
<img src=nav_logo />
这是我的 webpack.common.js:
module.exports =
mode: mode,
entry:
app: ["./src/js/app.js"]
,
output:
path: path.resolve(__dirname, "dist"),
filename: '[name].bundle.js',
publicPath: '/',
chunkFilename: '[name].bundle.js'
,
module:
rules: [
test: /\.(sc|c|)ss$/,
issuer:
exclude: /\.less$/,
,
use: [
loader: 'style-loader',
options:
,
,
loader: 'css-loader',
options:
importLoaders: 1,
localIdentName: '[name]-[local]-[hash:base64:5]',
,
,
],
,
test: /\.less$/,
use: [
loader: 'style-loader',
,
loader: 'css-loader',
options:
importLoaders: 1,
,
,
],
,
test: /\.(jsx?)/,
exclude: ["/node_modules", "/src/js/elm"],
use: [
loader: "babel-loader?cacheDirectory=true",
]
,
test: /\.scss$/,
issuer: /\.less$/,
use:
loader: './src/js/sassVarsToLess.js'
,
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
loader: 'url-loader',
options:
limit: 10000,
name: 'images/[name].[ext]',
,
loader: "image-webpack-loader",
options:
disable: true,
mozjpeg:
progressive: true,
quality: 65
,
// optipng.enabled: false will disable optipng
optipng:
enabled: true,
,
pngquant:
quality: '65-90',
speed: 4
,
gifsicle:
interlaced: false,
,
// the webp option will enable WEBP
webp:
quality: 75
,
],
,
test: /\.(ttf|otf|eot|woff2?)$/,
loader: "file-loader",
options:
name: 'fonts/[name].[ext]',
],
noParse: [/\.elm$/]
,
node:
fs: 'empty'
,
plugins: [
new Dotenv(),
new CopyWebpackPlugin([
from: "./src/assets/css",
to: "css"
,
]),
]
;
和 webpack.prod.js
module.exports = merge(common,
mode: 'production',
module:
rules: [
test: /\.(sc|c|)ss$/,
issuer:
exclude: /\.less$/,
,
use: [
loader: MiniCssExtractPlugin.loader,
,
loader: 'css-loader',
options:
importLoaders: 1,
localIdentName: '[name]-[local]-[hash:base64:5]',
,
,
],
,
test: /\.less$/,
use: [
loader: MiniCssExtractPlugin.loader,
,
loader: 'css-loader',
options:
importLoaders: 1,
,
],
,
test: /\.(jsx?)/,
exclude: ["/node_modules", "/src/js/elm"],
use: [
loader: "babel-loader?cacheDirectory=true",
]
,
test: /\.scss$/,
issuer: /\.less$/,
use:
loader: './src/js/sassVarsToLess.js' // Change path if necessary
,
test: /\.(jpe?g|png|gif|svg)$/i,
use: [
loader: 'url-loader',
options:
limit: 10000,
name: 'images/[name]-[hash:8].[ext]'
,
loader: "image-webpack-loader",
options:
disable: false,
mozjpeg:
progressive: true,
quality: 65
,
// optipng.enabled: false will disable optipng
optipng:
enabled: true,
,
pngquant:
quality: '65-90',
speed: 4
,
gifsicle:
interlaced: false,
,
// the webp option will enable WEBP
webp:
quality: 75
,
],
,
test: /\.(ttf|otf|eot|woff2?)$/,
loader: "file-loader",
options:
name: 'fonts/[name].[ext]',
],
noParse: [/\.elm$/]
,
optimization:
minimizer: [new TerserJSPlugin(), new OptimizeCSSAssetsPlugin()]
,
plugins: [
new htmlWebpackPlugin(
template: './src/assets/prod.index.html'
),
new MiniCssExtractPlugin(
filename: '[name].css',
chunkFilename: '[id].css',
),
],
)
这里是 nginx default.conf
server
listen 80;
server_name <domain_name>;
root /usr/share/nginx/html;
access_log /var/log/nginx/host.access.log main;
index index.html;
location /
try_files $uri $uri/ =404;
location /images/
alias /usr/share/nginx/html/images/;
try_files $uri $uri/ =404;
error_log /var/log/nginx/error.log debug;
error_page 500 502 503 504 /50x.html;
location = /50x.html
root /usr/share/nginx/html;
【问题讨论】:
【参考方案1】:使用 url-loader 加载图片
如果你注意到里面config/webpack.config.js
有一个module object
,里面有rules object
。
对于提供的规则或规则列表,有限制键
限制键很重要
限值的意义
-如果要加载的图像大小大于提供的限制值,则默认使用文件加载器。
例如
如果我有以下webpack.config.js
配置
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options:
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
,
,
在我的moudules -> rules object
里面
超过限制值为10000字节 因此 webpack 将仅使用 url-loader 加载大小小于 10000 字节的图像,如果发现图像的大小等于或大于 10000,则默认使用 file-loader,直到未指定备用加载器。
假设您在代码中动态添加类似这样的图像。
import largeimage from '../static/images/largeimage.jpg'
或任何路径
并且largeimage
的大小小于图像不会被加载的限制值。
解决方案
为了让 webpack 使用 url-loader 加载图片,你的大图片尺寸应该小于限制值。
所以要么增加限制,要么减少图像的大小。
参考 https://webpack.js.org/loaders/url-loader/#limit
【讨论】:
【参考方案2】:url-loader
不会将图像作为单独的文件加载,它会将文件编码为 base64 格式并将其包含在 js 包中。因此,不会有对图像文件的单独请求。看到这个答案:
Url-loader vs File-loader Webpack
尝试使用 file-loader
加载图像。我通常使用file-loader
加载字体和图像,它工作正常。
我正在使用这个工作配置(开发):
// this is configured outside of the exported webpack configuration code
const BASE_DIR = resolve(`$__dirname`);
module.exports =
mode: 'development',
devtool: 'eval-source-map',
resolve:
modules: [
resolve(BASE_DIR),
'node_modules'
]
,
output:
// ...
publicPath: '/'
,
module:
rules: [
// ...
test: /\.(png|svg|jpg|jpeg|gif|tiff)$/,
use: [
'file-loader?name=assets/[name].[ext]'
]
,
// ...
]
// ...
我的图像文件实际位于“src/assets/logo_arc.png”,我正在以这种方式使用它:
import logo from 'src/assets/logo_arc.png';
// ...
<img src=logo alt='company logo' />
我可以看到我的文件位于子目录assets
下的开发构建目录中,正如我所期望的那样。
在 webopack 开发服务器(在 localhost,我的自定义端口 9901)上运行应用程序时,图像在地址 http://localhost:9901/assets/logo_arc.png
上提供。
在开发包中,我可以看到涉及的部分:
// definition of webpack public path
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/";
// ...
// the image itself as a webpack module
/***/ "./src/assets/logo_arc.png":
/*!*********************************!*\
!*** ./src/assets/logo_arc.png ***!
\*********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__)
eval("module.exports = __webpack_require__.p + \"assets/logo_arc.png\";//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9zcmMvYXNzZXRzL2xvZ29fYXJjLnBuZz8wMmVlIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGlCQUFpQixxQkFBdUIiLCJmaWxlIjoiLi9zcmMvYXNzZXRzL2xvZ29fYXJjLnBuZy5qcyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gX193ZWJwYWNrX3B1YmxpY19wYXRoX18gKyBcImFzc2V0cy9sb2dvX2FyYy5wbmdcIjsiXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/assets/logo_arc.png\n");
/***/ ),
// importing webpack module into variable, it is used later in the img element
var src_assets_logo_arc_png__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! src/assets/logo_arc.png */ "./src/assets/logo_arc.png");
// ...
// usage in the img element
react__WEBPACK_IMPORTED_MODULE_0__["createElement"]("img",
src: src_assets_logo_arc_png__WEBPACK_IMPORTED_MODULE_7___default.a,
alt: 'company logo'
))
【讨论】:
我都试过很多很多次了。两者似乎都在做正确的事情,但仍然没有加载图像。网址中有 data:image/jpeg 等,但仍然只有 chrome 和 safari 占位符图像。 正如我所说的url-loader
将图像转换为 base64 格式。将其替换为 file-loader
并在构建的包中搜索图像文件名。文件名将以路径为前缀,它可以帮助您查看发生了什么。
感谢您的提示,但我的一个文件超过了为 url-loader 设置的 10000 个限制,并且它也没有显示,但有 data:image/jpeg 显示它应该在哪里。
我听从了你的建议,在 app.bundle.js 中搜索了 image/。我看到一堆带有 n.p + 'images/image_file.jpeg' 的地方,当我搜索 n.p 时,我看到 n.p="",所以它一定不是设置 n.p 吗? webpack 在哪里获取 url?顺便说一句,这是在本地主机上
好的,在查看后我看到我得到了两张图片:-rw-r--r-- 1 root root 183K Oct 5 03:29 hero-217ea6c8.jpeg -rw-r--r-- 1 root root 71 Oct 5 03:29 hero.jpeg
,而没有哈希的一张里面有这个:module.exports = __webpack_public_path__ + "images/hero-217ea6c8.jpeg";
,这就是它没有出现的原因。有什么方法可以让 webpack 显示散列版本?以上是关于Webpack url-loader 或 file-loader 不起作用反应应用程序的主要内容,如果未能解决你的问题,请参考以下文章
url-loader / file-loader 使用 webpack 破坏 css 输出中的相对路径
webpack学习笔记-2-file-loader 和 url-loader
Webpack 使用url-loader和file-loader打包资源文件