Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

webpack css-loader not finding images within url() reference in an external stylesheet

I'm new to the whole Node/NPM/Webpack world, so apologies if this is obvious.

I'm attempting to build a simple front-end project bundled with Webpack. I've got node installed, and have a package.json file configured. If I run "npm start" in my root directory, I get no errors from the console, and I'm able to go to "localhost:3000" in a browser and see my "hello, world" output.

My next task is to include a stylesheet, which contains a reference to an image, like this:

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

With things set up like this, I can view the image via the webpack-dev-server (by going to localhost:3000 in a web browser), but if I build the project, the path to the image is wrong. I have no idea what I'm doing wrong, so I'm throwing this out to the Stackiverse in the hopes that somebody out there will know what stupid thing I'm doing.

Here's my package.json file:

{   "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"   } } 

...and here's my webpack.config.js file:

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' }     ] }  }; 

...and then the index.html file:

<!doctype html> <html> <head>     <title>Webpack Test</title> </head>  <body>     <div class="imgtest">hello, world</div>     <script src="build/bundle.js"></script> </body> </html> 

...the "start.js" file referenced in the config file:

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

...and finally, the contents of the css file itself:

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

Like I said at the top, in webpack-dev-server world, the path to the image resolves properly, and it shows up as the background to the DOM element. In published world, the browser tells me it can't find the file, with Safari's console clearly showing a bad file path:

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

The correct local path is this:

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

Clearly, I'm doing something wrong, but I can't figure out what. Any help or advice is appreciated.

Thanks!

like image 700
hairbo Avatar asked Jul 21 '15 20:07

hairbo


People also ask

How do I reference an image in Webpack using CSS?

In Sprockets, when referencing images in CSS, you would use a special image-url () helper. In Webpack, simply use the standard url () expression in CSS with a relative path. The output for the style rule will, again, look something like background-image: url (/packs/media/images/burritos-efgh5678.jpg);.

How do I find the path of an image in Webpack?

In Webpack, simply use the standard url () expression in CSS with a relative path. The output for the style rule will, again, look something like background-image: url (/packs/media/images/burritos-efgh5678.jpg);. This technique will also work for image paths in CSS Modules.

How to import images with Webpack(ER)?

Importing images with Webpack (er) 1 Folder structure. First, where should you put your images? ... 2 Images in JS. ... 3 Interested to learn more about Webpack on Rails? ... 4 Subscribe to rossta.net to get updates . 5 Images in CSS. ... 6 Images in CSS within NPM modules. ... 7 Images in Rails views. ... 8 Reconfiguring. ... 9 Diving Deeper. ...

Why is CSS-loader not parsing my path?

If set to false, css-loader will not parse any paths specified in url or image-set . A function can also be passed to control this behavior dynamically based on the path to the asset. Starting with version 4.0.0, absolute paths are parsed based on the server root.


1 Answers

Okay...ugh. I just figured it out. The problem was with the "publicPath" variable inside webpack.config.js. I had this:

publicPath: '/build/' 

...which in retrospect is obviously an absolute path. What I needed instead was this:

publicPath: './build/' 

...which is a relative path. Things seem to work now.

UPDATE:

I'm still very new to Webpack, so all of this is still pretty confusing. Having said that...

I think I've gone about this the wrong way. My Webpack project has had an index.html file at the root of the project, and I was trying to use that both as the file the webpack-dev-server would hit AND what the build would use as its entry point. That was causing me no end of headaches, and I don't think any solution I hit upon really worked. Then I found this:

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

This lets you create your index.html page from a template, which means it doesn't actually have to exist as a file. webpack-dev-server creates it on the fly and stores it in memory, and when you publish to your "build" folder, an index.html file gets created within that folder.

There may be a true "right" way to handle the problem I raised here, but this seems to work really well, and in a roundabout way, it solves my problems, since it ducks the whole path question entirely.

Anyway, this is kind of rambling. I hope it helps somebody, and/or I hope somebody who knows more about this comes here and sets me straight.

like image 132
hairbo Avatar answered Sep 28 '22 05:09

hairbo