Webpack - 背景图片未加载
Webpack - background images not loading
我是 webpack 的新手,但在使用 css-loader 或 file-loader 时遇到了一些问题。
我正在尝试加载 background-image,但效果不佳。 background-image 未显示,即使 devtools 显示 background-image
样式。
如果我将 background-image
样式复制到 element.style
块,一切正常。我是不是在某个地方犯了一个愚蠢的错误?
body 标签应该有背景图片。样式出现在开发者工具中并且没有错误:
我可以加载文件5a09e4424f2ccffb6a33915700f5cb12.jpg
,但是正文没有背景。
如果我在 DevTools 中手动复制并粘贴 css 行到 element.style
,一切正常:
如果我在 Chrome 和 Firefox 中使用 webpack-dev-server
或仅 webpack
进行捆绑,就会发生这种情况。
其他样式,例如 body { background-color: red }
工作正常。
这是webpack.config.js:
const path = require('path');
module.exports = {
"entry": [
'./src/index.js'
],
"output": {
"path": path.join(__dirname, 'build'),
"filename": "bundle.js"
},
devtool: "source-map",
"module": {
"loaders": [
{
"test": /\.scss$/,
"loaders": ["style", "css?sourceMap", "sass?sourceMap"]
},
{
test: /\.jpg$/,
loader: "file-loader"
}
]
},
devServer: {
contentBase: './build'
}
};
浏览器似乎不喜欢 body 标签上背景图片的相对路径。 (另见 CSS Background image not loading and css background-image not working properly)
稍微更改代码似乎可以解决问题:
- 将 URL 更改为绝对值 URL:
background-image: url(http://localhost:8080/5a09e4424f2ccffb6a33915700f5cb12.jpg)
。这不太理想。
- 在正文中添加一个 class,并更改样式以引用此 class:
<body class="foo">
.foo {
background-image: url('../img/test.jpg');
}
这些都不能解决真正的问题,但确实能让你摆脱困境。
Webpack 通过 blob:
url 生成 css 和 <link>
s 它们,这似乎会导致加载背景图像出现问题。
开发解决方法
通过开发中的文件加载器内嵌图像(在 css 中创建大的 base64 字符串)
但允许热重载。
生产解决方法
使用 ExtractTextPlugin 作为普通文件提供 css。
目前在将 sourceMap 与 css-loader 一起使用时存在错误。从您的 css 加载程序中删除 sourceMap 应该可以修复它。
"module": {
"loaders": [
{
"test": /\.scss$/,
"loaders": ["style", "css", "sass?sourceMap"]
},
{
test: /\.jpg$/,
loader: "file-loader"
}
]
}
输出中的 publicPath 条目在哪里?例如:
publicPath: 'http://localhost:5000/', // 此处要求 css 中的图像使用源映射的绝对路径。必须是实际的数字ip才能在局域网上访问。
https://github.com/webpack/docs/wiki/configuration#outputpublicpath
在为这个问题苦苦挣扎了一天之后,我终于想出了如何使用postcss
重写css内的url
webpack.config.js
const _ = require('lodash');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const argv = {
verbose: _.includes(process.argv, '-v') || _.includes(process.argv, '--verbose'),
json: _.includes(process.argv, '--json'),
production: _.includes(process.argv, '--production'),
};
module.exports = {
cache: true,
devtool: argv.production ? "source-maps" : "eval",
output: {
path: 'public/build',
filename: '[name].js',
publicPath: "/build/",
pathinfo: true // use with devtool: "eval",
},
resolve: {
modulesDirectories: ['node_modules'],
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
{
test: /\.less$/,
loader: argv.production
? ExtractTextPlugin.extract('style-loader?sourceMap=1', [
'css-loader?sourceMap=1&importLoaders=1',
'postcss-loader?sourceMap=1',
'less-loader?sourceMap=1'
]) : [
'style-loader?sourceMap=1',
'css-loader?sourceMap=1&importLoaders=1',
'postcss-loader?sourceMap=1',
'less-loader?sourceMap=1'
].join('!')
},
{
test: /\.css$/,
loader: argv.production
? ExtractTextPlugin.extract('style-loader?sourceMap=1', [
'css-loader?sourceMap=1&importLoaders=1',
'postcss-loader?sourceMap=1',
]) : [
'style-loader?sourceMap=1',
'css-loader?sourceMap=1&importLoaders=1',
'postcss-loader?sourceMap=1',
].join('!')
},
]
}
}
postcss.config.js
const argv = {
verbose: _.includes(process.argv, '-v') || _.includes(process.argv, '--verbose'),
json: _.includes(process.argv, '--json'),
production: _.includes(process.argv, '--production'),
};
module.exports = {
plugins: [
require('autoprefixer')({
browsers: [
"> 5%", // https://www.netmarketshare.com/browser-market-share.aspx?qprid=2&qpcustomd=0
"last 2 versions", // http://caniuse.com/
]
}),
require('postcss-url-mapper')(function(url) {
return argv.production ? url : url.replace(new RegExp('^/'), 'http://localhost:3000/');
})
]
};
您也可以尝试在文件前面使用 ~
,以便 webpack 回退到加载器 require
来解析 url.
background-url: (~assets/image/myimagefile);
请尝试使用,例如:
html {
background: url(~/Public/img/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
css-webpack中的loader:
{
test: /\.(css|eot|svg|ttf|woff|jpg|png)$/i,
use: ExtractTextPlugin.extract({
use: [{
loader: 'css-loader',
options: {
importLoaders: 1,
minimize: true
},
}],
}),
},
bundle.css 中的结果是:
html{background:url(/Public/img/bg-picking.jpg) no-repeat 50% fixed;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover}
当在 React 中使用 img 时遇到问题,你必须检查目录结构,调用指向父目录的路由时通常会出错。
例如:如果你有这个结构
-public
--图片
---testImage.jpg
-组件
--家
---index.js
如果您尝试在 index.js 中使用以下代码,它将失败:
{background : url('/public/images/testImage.jpg')}
但是如果您知道文件夹结构并使用下面代码中所示的 [../] 导航到外部文件夹,我认为它会像我一样工作。
{background : url('../public/images/testImage.jpg')}
这个问题在使用相对路径时多次发生,在你的路径中尝试 [../] 直到你将自己定位在项目目录结构中的正确级别,然后使用正确的路径转到你想要的目录.
几个小时后,我只是简单地降级了 css-loader
npm install css-loader@4.3.0
我是 webpack 的新手,但在使用 css-loader 或 file-loader 时遇到了一些问题。
我正在尝试加载 background-image,但效果不佳。 background-image 未显示,即使 devtools 显示 background-image
样式。
如果我将 background-image
样式复制到 element.style
块,一切正常。我是不是在某个地方犯了一个愚蠢的错误?
body 标签应该有背景图片。样式出现在开发者工具中并且没有错误:
我可以加载文件5a09e4424f2ccffb6a33915700f5cb12.jpg
,但是正文没有背景。
如果我在 DevTools 中手动复制并粘贴 css 行到 element.style
,一切正常:
如果我在 Chrome 和 Firefox 中使用 webpack-dev-server
或仅 webpack
进行捆绑,就会发生这种情况。
其他样式,例如 body { background-color: red }
工作正常。
这是webpack.config.js:
const path = require('path');
module.exports = {
"entry": [
'./src/index.js'
],
"output": {
"path": path.join(__dirname, 'build'),
"filename": "bundle.js"
},
devtool: "source-map",
"module": {
"loaders": [
{
"test": /\.scss$/,
"loaders": ["style", "css?sourceMap", "sass?sourceMap"]
},
{
test: /\.jpg$/,
loader: "file-loader"
}
]
},
devServer: {
contentBase: './build'
}
};
浏览器似乎不喜欢 body 标签上背景图片的相对路径。 (另见 CSS Background image not loading and css background-image not working properly)
稍微更改代码似乎可以解决问题:
- 将 URL 更改为绝对值 URL:
background-image: url(http://localhost:8080/5a09e4424f2ccffb6a33915700f5cb12.jpg)
。这不太理想。 - 在正文中添加一个 class,并更改样式以引用此 class:
<body class="foo">
.foo {
background-image: url('../img/test.jpg');
}
这些都不能解决真正的问题,但确实能让你摆脱困境。
Webpack 通过 blob:
url 生成 css 和 <link>
s 它们,这似乎会导致加载背景图像出现问题。
开发解决方法
通过开发中的文件加载器内嵌图像(在 css 中创建大的 base64 字符串)
但允许热重载。
生产解决方法
使用 ExtractTextPlugin 作为普通文件提供 css。
目前在将 sourceMap 与 css-loader 一起使用时存在错误。从您的 css 加载程序中删除 sourceMap 应该可以修复它。
"module": {
"loaders": [
{
"test": /\.scss$/,
"loaders": ["style", "css", "sass?sourceMap"]
},
{
test: /\.jpg$/,
loader: "file-loader"
}
]
}
输出中的 publicPath 条目在哪里?例如:
publicPath: 'http://localhost:5000/', // 此处要求 css 中的图像使用源映射的绝对路径。必须是实际的数字ip才能在局域网上访问。
https://github.com/webpack/docs/wiki/configuration#outputpublicpath
在为这个问题苦苦挣扎了一天之后,我终于想出了如何使用postcss
重写css内的urlwebpack.config.js
const _ = require('lodash');
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const argv = {
verbose: _.includes(process.argv, '-v') || _.includes(process.argv, '--verbose'),
json: _.includes(process.argv, '--json'),
production: _.includes(process.argv, '--production'),
};
module.exports = {
cache: true,
devtool: argv.production ? "source-maps" : "eval",
output: {
path: 'public/build',
filename: '[name].js',
publicPath: "/build/",
pathinfo: true // use with devtool: "eval",
},
resolve: {
modulesDirectories: ['node_modules'],
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
{
test: /\.less$/,
loader: argv.production
? ExtractTextPlugin.extract('style-loader?sourceMap=1', [
'css-loader?sourceMap=1&importLoaders=1',
'postcss-loader?sourceMap=1',
'less-loader?sourceMap=1'
]) : [
'style-loader?sourceMap=1',
'css-loader?sourceMap=1&importLoaders=1',
'postcss-loader?sourceMap=1',
'less-loader?sourceMap=1'
].join('!')
},
{
test: /\.css$/,
loader: argv.production
? ExtractTextPlugin.extract('style-loader?sourceMap=1', [
'css-loader?sourceMap=1&importLoaders=1',
'postcss-loader?sourceMap=1',
]) : [
'style-loader?sourceMap=1',
'css-loader?sourceMap=1&importLoaders=1',
'postcss-loader?sourceMap=1',
].join('!')
},
]
}
}
postcss.config.js
const argv = {
verbose: _.includes(process.argv, '-v') || _.includes(process.argv, '--verbose'),
json: _.includes(process.argv, '--json'),
production: _.includes(process.argv, '--production'),
};
module.exports = {
plugins: [
require('autoprefixer')({
browsers: [
"> 5%", // https://www.netmarketshare.com/browser-market-share.aspx?qprid=2&qpcustomd=0
"last 2 versions", // http://caniuse.com/
]
}),
require('postcss-url-mapper')(function(url) {
return argv.production ? url : url.replace(new RegExp('^/'), 'http://localhost:3000/');
})
]
};
您也可以尝试在文件前面使用 ~
,以便 webpack 回退到加载器 require
来解析 url.
background-url: (~assets/image/myimagefile);
请尝试使用,例如:
html {
background: url(~/Public/img/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
css-webpack中的loader:
{
test: /\.(css|eot|svg|ttf|woff|jpg|png)$/i,
use: ExtractTextPlugin.extract({
use: [{
loader: 'css-loader',
options: {
importLoaders: 1,
minimize: true
},
}],
}),
},
bundle.css 中的结果是:
html{background:url(/Public/img/bg-picking.jpg) no-repeat 50% fixed;-webkit-background-size:cover;-moz-background-size:cover;-o-background-size:cover;background-size:cover}
当在 React 中使用 img 时遇到问题,你必须检查目录结构,调用指向父目录的路由时通常会出错。
例如:如果你有这个结构
-public
--图片
---testImage.jpg
-组件
--家
---index.js
如果您尝试在 index.js 中使用以下代码,它将失败:
{background : url('/public/images/testImage.jpg')}
但是如果您知道文件夹结构并使用下面代码中所示的 [../] 导航到外部文件夹,我认为它会像我一样工作。
{background : url('../public/images/testImage.jpg')}
这个问题在使用相对路径时多次发生,在你的路径中尝试 [../] 直到你将自己定位在项目目录结构中的正确级别,然后使用正确的路径转到你想要的目录.
几个小时后,我只是简单地降级了 css-loader
npm install css-loader@4.3.0