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

hai*_*rbo 50 node.js webpack webpack-style-loader

我是整个Node/NPM/Webpack世界的新手,所以如果这很明显就道歉.

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

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

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

设置这样的东西,我可以通过webpack-dev-server查看图像(通过在Web浏览器中访问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"
  }
}
Run Code Online (Sandbox Code Playgroud)

...这是我的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' }
    ]
}

};
Run Code Online (Sandbox Code Playgroud)

...然后是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>
Run Code Online (Sandbox Code Playgroud)

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

require('./test.css');
console.log("y u no work?");
Run Code Online (Sandbox Code Playgroud)

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

.imgtest { background: url(img/volcano.jpg);}
Run Code Online (Sandbox Code Playgroud)

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

http://localhost/build/1b05d814aa13ac035c6b122b9f5974f8.jpg
Run Code Online (Sandbox Code Playgroud)

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

http://localhost/~username/webpack1/build/1b05d814aa13ac035c6b122b9f5974f8.jpg
Run Code Online (Sandbox Code Playgroud)

显然,我做错了什么,但我无法弄清楚是什么.任何帮助或建议表示赞赏.

谢谢!

hai*_*rbo 32

好吧...啊.我刚想通了.问题出在webpack.config.js中的"publicPath"变量.我有这个:

publicPath: '/build/'
Run Code Online (Sandbox Code Playgroud)

...回想起来显然是一条绝对的道路.我需要的是这样的:

publicPath: './build/'
Run Code Online (Sandbox Code Playgroud)

......这是一条相对路径.事情似乎现在有效.

更新:

我对Webpack仍然很陌生,所以这一切仍然令人困惑.话说回来...

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

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

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

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

无论如何,这有点漫无边际.我希望它可以帮助某个人,并且/或者我希望有更多关于此事的人来到这里并让我直截了当.

  • @hairbo - 同意!但是一旦你到达那里,它就是美丽而美丽的东西. (3认同)

小智 12

我遇到的错误是

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
Run Code Online (Sandbox Code Playgroud)

这解决了我的问题:

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]'
    }
  ]}
Run Code Online (Sandbox Code Playgroud)

再次运行您的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
Run Code Online (Sandbox Code Playgroud)

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