如何使用 webpack-4 解析 sass 文件中的背景图像 URL?
Posted
技术标签:
【中文标题】如何使用 webpack-4 解析 sass 文件中的背景图像 URL?【英文标题】:How can I resolve background image URL inside sass file using webpack-4? 【发布时间】:2019-12-20 07:56:20 【问题描述】:这是我第一次在这里写作,所以请记住这一点。我是第一次在项目中使用 webpack,我遇到了一个问题,我试图在我的 sass 文件中使用背景 url() 函数设置背景图像,如下所示:
.img-container
background: url('../../img/homepage-login-prog.jpg') no-repeat center center fixed;
background-size: cover;
我的文件夹结构是:
- css
| app.css
- dist (this folder is created after building for production)
- img
| some-image.jpg
- js
| app.js (entry point for webpack output,
this is where I import main.scss file)
- js-vendor
| vendor.js (third-party libraries like bootstrap, jquery)
- sass (this is where I keep all my sass files which get compiled using
webpack loaders)
| components
| greetings-section.scss
| navbar.scss
| main.scss
| variables.scss
- template.html
- webpack.common.js
- webpack.dev.js
- webpack.prod.js
因为我已经为开发和生产配置了 webpack,所以我为它们都有单独的文件,它们都扩展了通用(通用)配置文件。那个看起来像这样:
const path = require("path");
module.exports =
entry:
main: "./js/app.js",
vendor: "./js-vendor/vendor.js"
,
module:
rules: [
test: /\.html$/,
use: ["html-loader"]
,
test: /\.(svg|png|jp(e*)g|gif)$/,
use: [
loader: "file-loader",
options:
name: "[name].[hash].[ext]",
outputPath: "img",
]
]
;
我的 webpack 开发配置如下所示:
const common = require("./webpack.common");
const merge = require("webpack-merge");
const path = require("path");
var HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = merge(common,
mode: "development",
output:
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist")
,
plugins: [
new HtmlWebpackPlugin(
template: "./template.html"
),
new MiniCssExtractPlugin(
filename: "[name].[contentHash].min.css"
),
],
module:
rules: [
test: /\.scss$/,
use: [
loader: MiniCssExtractPlugin.loader,
options:
publicPath: "../../"
,
"css-loader",
"sass-loader"
]
]
);
所以,webpack-dev-server启动后,会弹出一个错误:
ERROR in ./sass/main.scss (./node_modules/css-loader/dist/cjs.js!./node_modules/sass-loader/lib/loader.js!./sass/main.scss)
Module not found: Error: Can't resolve '../../img/homepage-login-prog.jpg' in 'C:\Users\...\...\...\sass'
如您所见,我尝试使用 mini-css-extract-plugin 中的 publicPath 选项设置相对路径,但它并没有为我解决问题。 我也一直在阅读其他人有类似的问题,但他们的解决方案都不适合我,所以我想问的是,有谁知道我如何配置 webpack 来识别我的 sass 中图像的 url文件,并正确绑定?
抱歉发了这么长的帖子,任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:这种图片是 webpack 的静态资源。所以你可以使用url-loader
来加载。
要安装它:
npm install url-loader --save-dev
在你的 webpack 配置文件中使用加载器中的 url-loader
test: /\.(png|jpg)$/,
loader: 'url-loader'
【讨论】:
它仍然不起作用,我仍然得到同样的错误:/ 如果你错过了它,我正在使用文件加载器来解析所有类型的图像,但这只有在我已经有的情况下才有效我的 html 中带有 src 属性的图像。我需要一种从 sass 加载背景图片 url 的方法:/ 仍然感谢您的快速响应,希望其他人能提出解决方案。【参考方案2】:遇到了类似的问题,对我有用的是将 main.scss 文件移动到我的 sass 文件夹中。之前,它位于 src 文件夹中。 main.scss 文件导入我所有的其他 .scss 文件。在作为入口点的 index.js 中,我导入 main.scss 文件。
我的文件结构与你的不同。
我有一个用于输出的 dist 文件夹和一个用于输入的 src 文件夹。
index.js:
import "./sass/main.scss";
main.scss:
@import "./footer";
@import "./header";
@import "./home";
@import "./navigation";
@import "./reset";
@import "./typography";
@import "./variables";
_header.scss:
#hero
background-image: url("../assets/heroImage.jpg");
background-size: cover;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
由于我的 scss 代码中的 background-image: url() 问题,我遇到了同样的错误。这个导入结构为我解决了这个问题。
对于我的 webpack,我有一个非常相似的配置,分为 3 个、common、dev 和 prod。我添加的唯一插件是 webpack.dev 中的“resolve-url-loader”。我已经尝试过 miniCssExtractPlugin 中的 publicpath 无济于事。
除了入口点之外,我的 common 和你的几乎完全相同。我的是 src 文件夹中的 index.js 而不是 app.js。
webpack.dev.js
const path = require("path");
const common = require("./webpack.common");
const merge = require("webpack-merge");
var HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = merge(common,
mode: "development",
output:
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist")
,
plugins: [
new HtmlWebpackPlugin(
template: "./src/template.html"
)
],
module:
rules: [
test: /\.scss$/,
use: [
loader: "style-loader"
,
loader: "css-loader"
,
loader: "resolve-url-loader"
,
loader: "sass-loader"
]
]
);
这在无数小时后为我解决了这个问题。让我知道这是否对您有任何帮助。干杯。
【讨论】:
这应该可以工作 - background-image: url("./assets/heroImage.jpg");【参考方案3】:问题不在 webpack 中。您的问题出在后台 url 路径中。由于您已将所有 css 导入到单个 main.scss 中,因此您需要在背景 url 中执行以下操作 -
.img-container
background: url('./../img/homepage-login-prog.jpg') no-repeat center center fixed;
background-size: cover;
【讨论】:
【参考方案4】:您也可以尝试使用resolve.modules 来获取相对路径和绝对路径。 通过添加到您的配置文件:
module.exports =
...,
resolve:
modules: [
path.resolve(__dirname, "img"),
"node_modules"
],
,
...
然后你可以从你的 sass 文件中访问你的图片:
background-image: url("~homepage-login-prog.jpg");
或者用相对路径替换波浪号。
【讨论】:
【参考方案5】:npm install url-loader --save-dev
和
test: /\.(png|jpg)$/,
loader: 'url-loader'
这是我的解决方案,谢谢!
【讨论】:
【参考方案6】:如果这不是 SASS 样式问题。那么为什么会出现这个错误呢?
图片位置正确,我检查了。你可以看到这个截图。
图片位置:
NPM 错误详情:
ERROR in ./resources/sass/app.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/css-loader/dist/cjs.js):
Error: Can't resolve '../images/icon-sprite.png' in 'C:\laragon\www\bhalokisu\resources\sass'
at finishWithoutResolve (C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\Resolver.js:293:18)
at C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\Resolver.js:362:15
at C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\Resolver.js:410:5
at eval (eval at create (C:\laragon\www\bhalokisu\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:16:1)
at C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\Resolver.js:410:5
at eval (eval at create (C:\laragon\www\bhalokisu\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:27:1)
at C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\DescriptionFilePlugin.js:87:43
at C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\Resolver.js:410:5
at eval (eval at create (C:\laragon\www\bhalokisu\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:15:1)
at C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\Resolver.js:410:5
at eval (eval at create (C:\laragon\www\bhalokisu\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:16:1)
at C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\Resolver.js:410:5
at eval (eval at create (C:\laragon\www\bhalokisu\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:27:1)
at C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\DescriptionFilePlugin.js:87:43
at C:\laragon\www\bhalokisu\node_modules\enhanced-resolve\lib\Resolver.js:410:5
at eval (eval at create (C:\laragon\www\bhalokisu\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:16:1)
at processResult (C:\laragon\www\bhalokisu\node_modules\webpack\lib\NormalModule.js:743:19)
at C:\laragon\www\bhalokisu\node_modules\webpack\lib\NormalModule.js:844:5
at C:\laragon\www\bhalokisu\node_modules\loader-runner\lib\LoaderRunner.js:399:11
at C:\laragon\www\bhalokisu\node_modules\loader-runner\lib\LoaderRunner.js:251:18
at context.callback (C:\laragon\www\bhalokisu\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
at Object.loader (C:\laragon\www\bhalokisu\node_modules\css-loader\dist\index.js:155:5)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
1 ERROR in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details)
webpack compiled with 2 errors
图片错误:
更新:
我正在使用 Laravel 项目。我发现问题出在目录相关。我是在公共目录中为我的图像创建的。在resources/images/imageName.png
创建目录后,问题就消失了。如果有人不明白,我可以帮助你。
【讨论】:
这并不能真正回答问题。如果您有其他问题,可以点击 进行提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review以上是关于如何使用 webpack-4 解析 sass 文件中的背景图像 URL?的主要内容,如果未能解决你的问题,请参考以下文章
webpack 4 sass-loader 不生成 scss 源映射
使用 Angular 7 构建的 Webpack 4 在尝试访问 node_modules 时会出现 sass-loader 问题