美文网首页程序员让前端飞
webpack中如何使用雪碧图

webpack中如何使用雪碧图

作者: 程序员小哥哥 | 来源:发表于2018-11-10 18:10 被阅读0次

    一、什么是雪碧图?

    CSS雪碧 即CSS Sprite,也有人叫它CSS精灵,是一种CSS图像合并技术,该方法是将小图标和背景图像合并到一张图片上,然后利用css的背景定位来显示需要显示的图片部分。

    二:为什么要用雪碧图

    结合我们公司的需求来说,因为有很多组件,每个组件下有大概50张图片,每张图片是一个请求,也就是发了300多个请求,这样是很可怕的,所以为了优化性能,减少http请求,决定采用雪碧图的形式。

    雪碧图是将你想要的很多张图片整理成一张图片,然后通过background-*来进行图片识别和定位来达到之前的效果。

    三:如何使用雪碧图

    雪碧图在之前有很多方式,如ps之类,现在最佳的方案还是在webpack-spritesmith

    我其实对webpack并不是很了解,我现在列出使用方法和我在使用webpack时候遇到的问题。

    1.安装

    执行命令行npm install --save-dev webpack-spritesmith

    2.在webpack.config.js中写入

     var path = require('path')
    
     var SpritesmithPlugin = require('webpack-spritesmith')
    
     //自定义样式
     var templateFunction = function (data) {
       var shared = '.ico { background-size: TWpx THpx }'
            .replace('TW', data.sprites[0].total_width / 2)
            .replace('TH', data.sprites[0].total_height / 2)
    
       var perSprite = data.sprites.map(function (sprite) {
           return '&.element-N {\n  width: Wpx;\n  height: Hpx;\n  background-position: Xpx Ypx;\n}'
               .replace('N', sprite.name)
               .replace('W', sprite.width / 2)
               .replace('H', sprite.height / 2)
               .replace('X', sprite.offset_x / 2)
               .replace('Y', sprite.offset_y / 2)
               .replace('TW', sprite.total_width / 2)
               .replace('TH', sprite.total_height / 2)
       }).join('\n')
    
       return shared + '\n' + perSprite
     }
    
     module.exports = {
          ...
         module: {
             rules: [
                 {test: /\.styl$/, use: [
                     'style-loader',
                     'css-loader',
                     'stylus-loader'
                 ]},
                 {test: /\.png$/, use: [
                     'file-loader?name=i/[hash].[ext]'
                 ]}
             ]
         },
         resolve: {
             modules: ['node_modules', 'spritesmith-generated']
         },
         plugins: [
             new SpritesmithPlugin({
                 src: { //引入路径
                     cwd: path.resolve(__dirname, 'src/images/ios/'),
                     glob: '*.png'
                 },
                 target: { //输出路径
                     image: path.resolve(__dirname, 'src/spritesmith-generated/ios.png'),
                     css: [
                       [path.resolve(__dirname, 'src/spritesmith-generated/sprite-1.css'), {
                           format: 'function_based_template'
                       }],
                       [path.resolve(__dirname, 'src/spritesmith-generated/sprite-2.css'), {
                           format: 'handlebars_based_template'
                       }]
                     ]
                 },
                 customTemplates: {
                   'function_based_template': templateFunction, //自定义输出什么样的css样式
                 },
                 apiOptions: {
                     cssImageRef: 'ios.png'
                 }
             })
         ]
     }
    

    3.根据地址更改后执行命令

    wbpack

    其实这样已经满足了大部分需求,根据需要将你所在的输入和输出地址进行更改即可,可以设置自己想要设置的的css(style-components、styl等),然后直接复制在自己的项目css文件,很有灵活性。

    四:需要注意的点

    我有的时候指定不同文件下的图片合成一张雪碧图,那该如何呢

    例如我的需求是:

    • resources
      • ios
        • images
      • ant
        • images
      • ios
        • images
      • ...

    翻译: resources下有几个文件夹(ios、ant、ios),相对应下面images文件夹放着各自对应的图片。

    需要注意下,它是支持glob

    src: { 
      //引入路径
      cwd: path.resolve(__dirname, 'src/images/ios/'),
      glob: '*.png' //这里进行更改
    },
    

    这里可以参考在这里根据需求进行设置http://www.globtester.com/

    glob改成

    @(wechat|element|ios)/images/*.png
    

    效果

    五:更深层次的需求

    我其实是想在各自的文件夹下的图片,生成各自文件夹下的雪碧图和css,那该如何实现呢,我写了一部分,还没有写完,感觉遇到了技术难点,我呈现出代码,会继续优化来实现

    var path = require('path')
    var SpritesmithPlugin = require('webpack-spritesmith')
    
    var platforms = ['android', 'ant', 'element', 'ios', 'wechat']//, 'windows']
    
    // var url = 'ant'
    const TARGET = process.env.TARGET
    
    console.log({ TARGET })
    
    module.exports = [TARGET].map(l => {
      console.log(l)
      const url = l
    
      const fn = (data) => {
        console.log(url)
        var shared = 'background-size: TWpx THpx\n'
            .replace('TW', data.sprites[0].total_width / 2)
            .replace('TH', data.sprites[0].total_height / 2)
    
        var perSprite = data.sprites.map(function (sprite) {
            return `&.${url}-N {\n  width: Wpx;\n  height: Hpx;\n  background-position: Xpx Ypx;\n}\n`
                .replace('N', sprite.name)
                .replace('W', sprite.width / 2)
                .replace('H', sprite.height / 2)
                .replace('X', sprite.offset_x / 2)
                .replace('Y', sprite.offset_y / 2)
                .replace('TW', sprite.total_width / 2)
                .replace('TH', sprite.total_height / 2)
        }).join('\n')
    
        return shared + '\n' + perSprite
      }
    
      return {
        module: {
            rules: [
                {test: /\.styl$/, use: [
                    'style-loader',
                    'css-loader',
                    'stylus-loader'
                ]},
                {test: /\.png$/, use: [
                    'file-loader?name=i/[hash].[ext]'
                ]}
            ]
        },
        entry: {
          [url]: path.join(__dirname, url),
        },
        output: {
          path: path.join(__dirname, '../parsed/', url),
          filename: '[name].css'
        },
        resolve: {
            modules: ['node_modules', 'spritesmith-generated']
        },
        plugins: [
            new SpritesmithPlugin({
                src: {
                    cwd: path.resolve(__dirname, 'images/'+url+'/'),
                    glob: '*.png' // '@(android|ant|element|ios|wechat|windows)/*.png'
                },
                target: {
                    image: path.resolve(__dirname, '../parsed/'+url+'/'+url+'.png'),
                    css: [
                        [path.resolve(__dirname, '../parsed/'+url+'/'+url+'.css'), {
                            format: 'function_based_template'
                        }]
                    ]
                },
                customTemplates: {
                    'function_based_template': fn
                }
            })
        ]
      }
    })
    

    以上。

    相关文章

      网友评论

        本文标题:webpack中如何使用雪碧图

        本文链接:https://www.haomeiwen.com/subject/stttfqtx.html