欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

走近webpack(3)--图片的处理

程序员文章站 2022-04-14 13:41:31
上一章,咱们学了如何用webpack来打包css,压缩js等。这一篇文章咱们来学习一下如何用webpack来处理图片。废话不多说,咱们开始吧。 首先,咱们随便找一张你喜欢的图片放到src/images目录下,然后把图片设置为背景图片,代码是这个样子。 src/index.html: src/css/ ......

  上一章,咱们学了如何用webpack来打包css,压缩js等。这一篇文章咱们来学习一下如何用webpack来处理图片。废话不多说,咱们开始吧。

  首先,咱们随便找一张你喜欢的图片放到src/images目录下,然后把图片设置为背景图片,代码是这个样子。

src/index.html:

<div id="title"></div>
<div id="name"></div>
<div id="img"></div>
<script src="./entry1.js"></script>
<script src="./entry2.js"></script>

src/css/index.css:

body{
   background:red; 
}
#title{
  background:orange;  
  color:blue;      
}
#img{
    background: url(../images/dog.jpg);
    width: 500px;
    height: 500px;
}

  ok,我们写完了代码,现在webpack是无法解析的,我们可以打包试一下,发现会报错。嗯,没有加入loader肯定会报错的!

  那么,接下来我们来安装一下打包图片需要用到的loader:

npm install --save-dev file-loader url-loader

  在等待安装之际,我们先解释一下这两个loader分别都是做什么的:

  file-loader:解决引用路径的问题,拿background样式用url引入背景图来说,我们都知道,webpack最终会将各个模块打包成一个文件,因此我们样式中的url路径是相对入口html页面的,而不是相对于原始css文件所在的路径的。这就会导致图片引入失败。这个问题是用file-loader解决的,file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件

  url-loader:如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。其实简单来说,url-loader的作用就是根据配置来判断图片是否需要转换成字符串编码,来使项目的性能和速度更快。

  那么,接下来我们在module中配置一下loader,现在我们的module看起来是这样的,其中limit参数就是用来判断需要把图片转换成字符串编码的大小范围,单位是B。

module:{
        rules: [
            {
              test: /\.css$/,
              use: [ 'style-loader', 'css-loader' ]
            },{
               test:/\.(png|jpg|gif)/ ,
               use:[{
                   loader:'url-loader',
                   options:{
                       limit:500000
                   }
               }]
            }
          ]
    },

  唉?不对啊,你安装了两个loader,为什么只用了url-loader啊?!因为url-loader内置了file-loader。这里安装file-loader是为了方便下面用到的时候不用再安装了。

  OK,咱们来打包一下看看会发生什么吧。打开页面发现我们引入的图片已经显示了。

  下面说一下怎么把css从js中分离出来,我们上面的css都是通过import引入到js中再进行打包的,这样不利于维护,也违背了js,css,html互相分离的基本原则。但是一旦分离了css,那么原本的图片路径就会出现问题。我们下面来解决一下。但是webpack官方认为css就应该打包进js中以减少http请求。所以,仁者见仁智者见智,怎么做看具体情况来选择吧。

  其实要解决这个问题很简单,用插件,extract-text-webpack-plugin。怎么安装就不说了,已经说了好多遍了,跟上面的安装方法一样,改个名字而已。

  既然是插件,我们就需要在config中引入并且new一个实例之后才可以使用:

module:{
    rules: [
        {
          test: /\.css$/,
/*修改了一下使用的方式*/
          use: extractTextPlugin.extract({
            fallback: "style-loader",
            use: "css-loader"
          })
        },{
           test:/\.(png|jpg|gif)/ ,
           use:[{
               loader:'url-loader',
               options:{
                   limit:500000
               }
           }]
        }
      ]
},
//插件,用于生产模版和各项功能
plugins:[
    new uglify(),
    new htmlPlugin({
        minify:{
            removeAttributeQuotes:true
        },
        hash:true,
        template:'./src/index.html'
       
    }),
/*这里new了一个插件的实例*/
    new extractTextPlugin("css/index.css")
],

  ok,我们兴致勃勃地去打包一下,竟然报错了,报错的主要原因是extract-text-webpack-plugin当前还没有支持webpack4.x,那么我们该怎么办呢?别急,咱们想想办法解决:

npm install --save-dev extract-text-webpack-plugin@next
/*更新版本*/

  这样就可以打包了,但是我们打包完成之后发现index.html并没有引入相应的css,页面没有任何css,别急,我们来进行下一步解决这个问题。

  我们在config中定义一个路径变量:

var webpath={
    publicPath:"http://192.168.199.124:9090/"
}
/*就是你在devServer中定义的host和端口*/

  然后在output属性中定义一个publicPath属性:

output:{
    path:path.resolve(__dirname,'dist'),
    filename:'[name].js',
    publicPath:webpath.publicPath
},

  并且要把之前配置在devServer中的host修改成你自己的本机host,我的是http://192.168.199.124,如果你不知道,可以在cmd中使用ipconfig来查询。

  然后,我们npm run server一下,发现打开的页面已经有图片和样式了。

  那么我们就学会了如何处理css中的图片问题,下面我们学习一下如何处理html中的图片(也是用插件,各种插件,你可以去github随便找一个你喜欢的可以处理这中问题类型的插件):

  这里我们使用html-withimg-loader,然后在config中如下配置:

npm install html-withimg-loader --save
/*因为在生产环节中也需要用到,所以使用--save命令*/
{
    test: /\.(htm|html)$/i,
     use:[ 'html-withimg-loader'] 
}

  完事了。。。。。。简单吧。

  前边的内容,打包后的图片并没有放到images文件夹下,要放到images文件夹下,其实只需要配置我们的url-loader选项就可以了。前面也说到了,要限制limit的大小,不然图片在小于limit的范围内会进行转码,咱们来小小的修改下代码就可以了:

{
   test:/\.(png|jpg|gif)/ ,
   use:[{
       loader:'url-loader',
       options:{
           limit:500,
           outputPath:'images/'
       }
   }]
}

  我们在src/index.html中加入一个图片的引入:

<div id="title"></div>
<div id="name"></div>
<div id="img"></div>
<!-- 通过src引入图片 -->
<img id="htmlImg" src="./images/dog.jpg">

  然后在src/css/index.css下写上这样的css:

body{
   background:red; 
}
#title{
  background:orange;  
  color:blue;      
}
#img{
    background: url(../images/dog.jpg);
    width: 500px;
    height: 500px;
}
/*设置图片大小*/
#htmlImg{
    width: 500px;
    height: 500px;
}

  然后我们npm run server一下看看结果吧。这里说明一下,可能细心的小伙伴会问,为什么以前打包用npm run build 而这里用npm run server呢?

  通常情况下,我们有两种环境,一种是dev,一种是prod,也就是开发环境和生产环境,一般在开发环境下,我们本地会通过webpack-dev-server通过express起一个node服务器,而不是真正的打包,而我们以前所一起学习的webpack使用方法即包含了开发环境下的需求,又有生产环境下的内容,当我们要把整个项目打包上线的时候,我们会压缩js,压缩图片,整合资源以减少http请求,但是我们在开发环境下的时候,往往需要更多的功能以使代码更容易阅读和debug。再有就是,我们在引入图片的时候,用的是绝对地址,也就是node起服务器后你本地的ip地址,如果不通过npm run server起本地服务器,是无法找到图片的。有兴趣的小伙伴可以试试npm run build然后手动打开dist下的html看看效果。

  至此,图片的处理方式就结束了。下一章咱们来看看怎么处理less啊,sass这样的css预编译语言,毕竟现在很少用css来写样式了。