webpack css-loader 在外部样式表的 url() 引用中找不到图像

Posted

技术标签:

【中文标题】webpack css-loader 在外部样式表的 url() 引用中找不到图像【英文标题】:webpack css-loader not finding images within url() reference in an external stylesheet 【发布时间】:2015-10-11 12:14:35 【问题描述】:

我是整个 Node/NPM/Webpack 世界的新手,如果这很明显,请道歉。

我正在尝试构建一个与 Webpack 捆绑的简单前端项目。我已经安装了节点,并配置了一个 package.json 文件。如果我在根目录中运行“npm start”,控制台不会出现任何错误,并且可以在浏览器中转到“localhost:3000”并查看“hello, world”输出。

我的下一个任务是包含一个样式表,其中包含对图像的引用,如下所示:

.myimg background: url(path/to/file.jpg);

通过这样的设置,我可以通过 webpack-dev-server 查看图像(通过在网络浏览器中访问 localhost:3000),但是如果我构建项目,图像的路径是错误的。我不知道我做错了什么,所以我把它扔到了 Stackiverse,希望有人知道我在做什么愚蠢的事情。

这是我的 package.json 文件:


  "name": "webpack-test1",
  "version": "0.0.1",
  "description": "My project WTF.",
  "private": true,
  "scripts": 
    "start": "node server.js"
  ,
  "devDependencies": 
   "css-loader": "^0.15.2",
   "file-loader": "^0.8.4",
   "style-loader": "^0.12.3",
   "url-loader": "^0.5.6"
  ,
  "dependencies": 
    "webpack": "^1.9.6",
    "webpack-dev-server": "^1.8.2"
  

...这是我的 webpack.config.js 文件:

var path = require('path');
var webpack = require('webpack');

module.exports = 
  entry: [
    "./src/start.js"
],
output: 
    filename: "bundle.js",
    path: path.join(__dirname, 'build'),
    publicPath: '/build/'
,
module: 
    loaders: [
         test: /\.css$/, loader: 'style-loader!css-loader' ,
         test: /\.(png|jpg)$/, loader: 'file-loader' 
    ]


;

...然后是 index.html 文件:

<!doctype html>
<html>
<head>
    <title>Webpack Test</title>
</head>

<body>
    <div class="imgtest">hello, world</div>
    <script src="build/bundle.js"></script>
</body>
</html>

...配置文件中引用的“start.js”文件:

require('./test.css');
console.log("y u no work?");

...最后是css文件本身的内容:

.imgtest  background: url(img/volcano.jpg);

就像我在顶部所说的,在 webpack-dev-server 世界中,图像的路径可以正确解析,并显示为 DOM 元素的背景。在已发布的世界中,浏览器告诉我它找不到文件,Safari 的控制台清楚地显示了错误的文件路径:

http://localhost/build/1b05d814aa13ac035c6b122b9f5974f8.jpg

正确的本地路径是这样的:

http://localhost/~username/webpack1/build/1b05d814aa13ac035c6b122b9f5974f8.jpg

很明显,我做错了什么,但我不知道是什么。感谢您提供任何帮助或建议。

谢谢!

【问题讨论】:

我正用头撞墙,this 让我工作。 【参考方案1】:

好吧……呃。我刚刚想通了。问题出在 webpack.config.js 中的“publicPath”变量上。我有这个:

publicPath: '/build/'

...回想起来显然是一条绝对路径。我需要的是这个:

publicPath: './build/'

...这是一个相对路径。现在看来一切正常。

更新:

我对 Webpack 还是很陌生,所以所有这些仍然很混乱。说了这么多……

我认为我做错了。我的 Webpack 项目在项目的根目录中有一个 index.html 文件,我试图将它用作 webpack-dev-server 将命中的文件以及构建将用作其入口点的文件。这让我头疼不已,而且我认为我遇到的任何解决方案都没有真正奏效。然后我发现了这个:

https://www.npmjs.com/package/html-webpack-plugin

这使您可以从模板创建 index.html 页面,这意味着它实际上不必作为文件存在。 webpack-dev-server 动态创建它并将其存储在内存中,当您发布到“build”文件夹时,会在该文件夹中创建一个 index.html 文件。

可能有一种真正“正确”的方式来处理我在这里提出的问题,但这似乎工作得很好,并且以一种迂回的方式解决了我的问题,因为它完全回避了整个路径问题。

无论如何,这有点漫无边际。我希望它对某人有所帮助,和/或我希望对此有更多了解的人来到这里并让我直截了当。

【讨论】:

@hairbo — 同意!但是一旦你到达那里,它就是一件美丽的事情。 您的 index.html 不在构建中,这是主要原因,而且很奇怪,应该是构建的一部分。【参考方案2】:

我遇到的错误是

Module parse failed: PATH:\TO\IMG\XYZ.PNG  Unexpected character '�' (1:0)
 You may need an appropriate loader to handle this file type.
 SyntaxError: Unexpected character '�' (1:0)

.
.
.
.
.
@ ./~/css-loader!./~/sass-loader!./node/static/sass/style.scss 6:399692-399747

这解决了我的问题:

module: 
.
.
.,
       test: /\.scss$/,
       exclude: /node_modules/,
       loader: ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader"),
       root: path.resolve('./node/static/sass')
   ,
   
     test: /\.(jpe?g|gif|png)$/,
     loader: 'file-loader?emitFile=false&name=[path][name].[ext]'
    
  ]

再次运行你的 webpack。

附加所有背景:url('~/../somePath/toImage.png');

> thunderbolt@0.0.1 react-build PATH:\TO\PROJECT
> webpack --watch --display-error-details --display-cached --content-base ./

Hash: f6e4cbbf0068b5792247
Version: webpack 1.13.2
Time: 4882ms
         Asset    Size  Chunks             Chunk Names
  js/bundle.js  760 kB       0  [emitted]  main
css/bundle.css  393 kB       0  [emitted]  main
    + 180 hidden modules
Child extract-text-webpack-plugin:
        + 76 hidden modules

简而言之,文件加载器的作用是 - 它将文件复制到新路径并将该路径放在 css 中,对于我的情况,CSS 文件嵌套在某个公共文件夹中,而文件加载器会将其粘贴到根目录中公共的,在定义了 path=[path] 的情况下,它仍然会操纵相对路径。因此禁用它完全解决了我的相对路径问题,并添加了嵌套的图像文件夹,因此这也避免了解决这些路径的挑战。我不需要相同图像的双重副本。

【讨论】:

url('~/../somePath/toImage.png') 这对我来说适用于 webpack 2。

以上是关于webpack css-loader 在外部样式表的 url() 引用中找不到图像的主要内容,如果未能解决你的问题,请参考以下文章

在外部样式表中查找 CSS 类的定义

在外部样式表文件上分配样式时出现问题

在 Webpack + React 中使用内联 css-loader

webpack-- 样式加载

webpack常用插件

webpack使用五