mixtur / webpack-spritesmith

Webpack plugin that converts set of images into a spritesheet and SASS/LESS/Stylus mixins
498 stars 56 forks source link

The path to the sprite breaks down #86

Open frontbastard opened 5 years ago

frontbastard commented 5 years ago

Hey!

My path to the sprite breaks down. When I check the code I see something like this: background-image: url(D:OSPanelomainsjusttestrontendweb_newimg_originalspagesprofilesprite.png)

This is my config:

// Webpack v4
const path = require('path');
const SpritesmithPlugin = require('webpack-spritesmith');

module.exports = {
...
    plugins: [
       ...
        new SpritesmithPlugin({
            src: {
                cwd: path.resolve(__dirname, '../../img_originals/pages/profile/sprite'),
                glob: '*.png'
            },
            target: {
                image: path.resolve(__dirname, '../../img_originals/pages/profile/sprite.png'),
                css: path.resolve(__dirname, '../../img_originals/pages/profile/sprite.scss')
            },
            spritesmithOptions: {
              padding: 10
            }
        })
    ],
    resolve: {
        modules: ["node_modules", "spritesmith-generated"]
    }
};

The fact is that when I use image: '../../img_originals/pages/profile/sprite.png' instead of image: path.resolve(__dirname, '../../img_originals/pages/profile/sprite.png') everything is ok.

Thank you for help!

mixtur commented 5 years ago

uh... I never saw anything like this. I think some other part of your pipeline is doing this. How do you load styles and png's in webpack?

killerbytes commented 5 years ago

make sure you add this apiOptions: { cssImageRef: '~sprite.png', },

facinick commented 4 years ago

Hey I didn't fully understood the cssImageRef part. What does it do? why the "~" ? I understand the generated sprites less/css file is used to find coordinates of all images in sprites.png. so we have to import the css/less file but how do I import it and use it?

mixtur commented 4 years ago

When ~ is used in css in webpack it will be resolved "globally"-ish. Independent of where it is required from. With ~ you also need to use resolve.modules.

It matters because if you import for example sass file B from another sass file A and sass file B uses some image C webpack will actually resolve C relative to A, not B. Or more specificly relative to topmost file in sass import hierarchy. The same goes for less/stylus. Plain css actually may behave more intuitive I am not sure.

Applied to sprites it would be like this You have js file with some component. Say Button.js. Button.js imports its own styles. Button.sass. Button.sass imports sass file generated by plugin, say Sprites.sass (which is somewhere else in the project hierarchy) Sprites.sass uses image generated by plugin.

Webpack doesn't know anything about what is happening inside sass files, so it will think that request to image is issued from Button.sass. Therefore you can't simply use relative request in generated sass file. Because you never know where it will be used from. And even if you would figure out correct relative path with lots of ../../. It would still be a problem because if you had another component say Checkbox.js, that also uses sprites the same way, but lives deeper in project hierarchy, that relative path would be incorrect for Checkbox.