Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack doesn't combine all images into single sprite #69

Open
MwumLi opened this issue Oct 3, 2016 · 18 comments
Open

Webpack doesn't combine all images into single sprite #69

MwumLi opened this issue Oct 3, 2016 · 18 comments

Comments

@MwumLi
Copy link

MwumLi commented Oct 3, 2016

I use code to express my mean:

// aa.css
.a {
  background: url(./img/sprites/default/table/edit-icon.png)
}

// bb.css
.b {
  background: url(./img/sprites/default/table/offline-icon.png)
}
// main.js
require('aa.css');
require('bb.css'))

when I use webpack, generated a sprite : sprite.table.png, but only offline-icon was bundle into sprite.table.png, the correct result should be sprite.table.png include edit-icon.png and offline-icon.png both.
when use require and run loader once and you cann't make cache for this, so the 'wrong' result appear

can you solve the question ?

@vvasilev-
Copy link
Member

@MwumLi Can you give more information about your setup of Webpack?

@vvasilev- vvasilev- changed the title Cann't Combine multiple file images into a sprite Webpack doesn't combine all images into single sprite Oct 4, 2016
@MwumLi
Copy link
Author

MwumLi commented Oct 8, 2016

webpack config :

module.exports = {
    entry: {
        main: './src/main.js'
    },
    output: {
        path: './dist/',
        filename: 'js/[name].js',
        publicPath: '/'
    },
    module: {
        loaders: [
            {
                test: /\.css$/,
                loader: "style!css!postcss"
            },
            {
                test: /\.(png|jpg)$/,
                loader: 'ul-loader',
                query: {
                    limit: 1,
                    name: "img/[name].[hash].[ext]"
                }
            }
        ]
    }.
    plugins: [
        new HtmlWebpackPlugin({
            title: "webpack demos",
            filename: "index.html"
        })
    ],
   postcss: function() {
        return [postcssSprites({
          stylesheetPath: "./dist/css/",
          spritePath: "./dist/img/",
          relativeTo: 'file',
          basePath: './src/',
          filterBy: function(image) {
            if (image.url.indexOf('img/sprites') === -1) {
              return Promise.reject();
            }
            return Promise.resolve();
          },
          groupBy: function(image) {
            if (image.url.indexOf('img/sprites') === -1) {
              return Promise.resolve(Date.now().toString());
            } else {
              return Promise.resolve(image.url.split('/').slice(-2, -1)[0])
            }
          },
          hooks: {
            onUpdateRule: function(rule, comment, image) {
                var spriteUrl = image.spriteUrl;
                image.spriteUrl = dir.publicPath + dir.dist.img + spriteUrl.split('/').pop();
                postcssSpritesCore.updateRule(rule, comment, image);
            }
        /*                  ,*/
            //onSaveSpritesheet: function(opts, groups) {
                 //return path.join(opts.spritePath, ['sprite', ...groups, _.now(), 'png'].join('.'));
            /*}*/
          },
          spritesmith: {
            padding: 8
          }
        })]
    }
}

@evandavis
Copy link
Contributor

I'm having the same issue with a pretty simple webpack config:

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const isPROD = process.env.NODE_ENV === 'production';

/**
 * Plugins
 */
const plugins = [
  new ExtractTextPlugin('common.css', {allChunks: true})
];


const styleLoaders = ['css-loader', 'postcss'];
const sprites = require('postcss-sprites');

/**
 * Paths
 */
const SRC = path.resolve('./src');
const EXT = path.resolve('./node_modules');
const OUT = path.resolve('./dist/bundle');

module.exports = {
  devtool: isPROD ? 'source-map' : 'eval',
  entry: {
    common: ['./src/index']
  },
  output: {
    filename: '[name].js',
    chunkFilename: 'chunk.[id].js',
    path: OUT,
    /* prod setting is for CSS images; js path is provided at runtime */
    publicPath: isPROD ? '' : 'http://localhost:8888/static/'
  },
  plugins,
  module: {
    loaders: [{
      test: /\.css$/,
      loader: isPROD ? ExtractTextPlugin.extract(styleLoaders) : ['style'].concat(styleLoaders).join('!'),
      include: [SRC, EXT]
    }, {
      test: /\.(gif|jpg|png)$/,
      loader: `file-loader?name=${isPROD ? '../' : ''}assets/[hash].[ext]`
    }]
  },
  resolve: {
    modulesDirectories: [
      'src',
      'node_modules'
    ],
    extensions: ['', '.js', '.json', '.jsx', '.gif', '.png', '.jpg']
  },
  postcss: [
    sprites({
      stylesheetPath: SRC,
      spritePath: 'sprites',
      basePath: SRC
    })
  ]
};

The last stylesheet to get processed overwrites the sprite. Does this only work as a secondary process after the full stylesheet has been generated?

@evandavis
Copy link
Contributor

This is the same issue as #43; Webpack processes files individually, so the sprite contains only the last file.

@lcxfs1991
Copy link

same issue here.

@skyujilong
Copy link

same to me! how to fix this?

@vvasilev-
Copy link
Member

Hi guys,

The problem is that your files are processed individually by Webpack while the plugin expects a single CSS stylesheet. I'm open for discussion if someone have an idea how this can be fixed.

@gaaoge
Copy link

gaaoge commented Dec 21, 2016

I have the same issue with vue...

{
    test: /\.vue$/,
    loader: 'vue-loader',
    options: {
        postcss: [cssnext(), sprites(spritesOptions), px2rem()],
        loaders: {
            css: ExtractTextPlugin.extract({
            loader: 'css-loader',
            fallbackLoader: 'vue-style-loader'
            })
        }
     }
}

@perfey
Copy link

perfey commented Jan 12, 2017

I have the same issue, Just in css.

// a.css
.box1 {
  background: url(./sprite/icon1.png);
}
.box2 {
  background: url(./sprite/icon2.png)
}
.box3 {
  background: url(./sprite/icon3.png)
}

// b.css
.box1 {
  background: url(./sprite/icon1.png);
}
.box2 {
  background: url(./sprite/icon2.png)
}

Then I use gulp to get sprite img.

gulp.task('dist', function (done) {
    var opts = {
        stylesheetPath: './dist',
        spritePath: './img',
        spritesmith: {padding: 4},
        retina:  2,
        hooks: false,
        groupBy: function (image) {
            var groupName = 'x';
            image.retina = true;
            image.ratio = 2;
            return Promise.resolve(groupName);
        }
    };

    var stream = gulp.src('./css/*.css')
        .pipe(postcss([sprites(opts)]))
        .pipe(gulp.dest('./dist'));
    return stream;
});

I got two new css. And They use the same sprite img. But the same sprite img only has icon1.png and icon2.png. There ditn't has icon3.png in the sprite img.

@jednano
Copy link
Contributor

jednano commented Feb 24, 2017

I use the following webpack CSS rule:

exports.css = {
    test: /\.css$/,
    use: [
        'style-loader',
        'css-loader',
        {
            loader: 'postcss-loader',
            options: { plugins: postcssInit }
        }
    ]
};

function postcssInit() {
    const sheetName = basename(this.resourcePath, '.css');
    return loadPlugins.call(this, { sheetName });
}

function loadPlugins({ sheetName }) {
    return [
        // some plugins...
        require('postcss-sprites')({
            groupBy: () => Promise.resolve(sheetName),
            // more opts...
        }),
        // more plugins...
    ];
}

See #83 for some more details about my setup as well as #85.

@hoanguyen311
Copy link

hoanguyen311 commented Mar 17, 2017

Does that mean postcss-sprite will not work with webpack?

@hycript
Copy link

hycript commented Mar 30, 2017

same issue ...

@inoutw
Copy link

inoutw commented Jul 10, 2017

same issue+1

1 similar comment
@shenzhim
Copy link

same issue+1

@SilenceOfNight
Copy link

Has the problem been solved?

@xierenyuan
Copy link

same issue+1

2 similar comments
@yeungtg
Copy link

yeungtg commented Aug 14, 2018

same issue+1

@Chorer
Copy link

Chorer commented Aug 18, 2021

same issue+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests