webpack学习笔记(2) --- loader

loader

什么是loader

Loader的作用是帮助webpack去打包,webpack不能识别的文件。 webpack只能识别js文件,那些webpack不能识别的文件,就需要loader去进行识别解析。

下面以打包图片为例,简单分析一下loader的工作过程。

  • 首先下载一张图片

  • 将图片存进src/imgs之下,目录结构如下:

    • 项目结构
  • 在我们的入口文件引用,并将它插入进html之中
    ​
    import img from './imgs/twice.jpg'
    console.log('file is', img)
    const ImgElement = new Image();
    ImgElement.src = img;
    document.getElementById('root').append(ImgElement)</pre>
  • 这时候直接去使用webpack打包会报错,因为webpack不能识别以jpq为结尾的图片文件。这时候需要借助loader

    • 具体使用什么loader,翻阅官方文档。图片可以使用file-loader

      • 安装:npm install file-laoder -D
    • 将loader配置进webpack的文件内

const path = require('path');
module.exports = {
  mode: 'development',
  entry: './src/index.js',
  module: {
    rules: [{
      test: /\.jpg$/,//匹配jpg为结尾的文件
      use: [{
        loader: 'file-loader'
      }]
    }]
  },
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, 'dist')
  }
}
  • 再运行命令,这次成功打包并且页面上也可以看到。

  • 结果
  • 打开控制台,可以看到刚刚输出的内容,是文件的文件名

    • 控制台
  • 并且在dist目录之下,也同样生成了一份乱码后的图片,文件名与输出内容一致。

  • 由此可以看出,loader会先将文件移动到dist这个文件夹下,然后再返回这个文件的地址,最终打包

  • 总结:file-loader执行顺序

    • 会先将文件移动到dist这个目录下面

    • 然后将这个文件的地址返回给这个变量

打包静态资源

打包图片

在上面的loader介绍中,已经使用过file-loader对文件进行过简单的打包。接下来会使用file-loader以及url-loader对图片资源进行打包

为loader配置option,对打包产生的文件增加更多的配置。

  • 使用placehodler设置文件名,当前输出文件是以hash值作为文件名

  • 使用outputPath设置图片的存放路径

  •    test: /\.jpg$/,
       use: [{
         loader: 'url-loader',
         options: {
           name: '[name].[ext]',
           outputPath: 'images'
         }
       }]
     }]
    
    
  • 重新生成的就是想要的文件路径与文件名了。

  • image.png

使用url-loader

除了file-loader以外,url-loader也可以对文件资源进行打包。

安装:npm install url-loader --save-dev

将原有的file-loader替换成url-loader

 module: {
    rules: [{
      test: /\.jpg$/,
      use: [{
        loader: 'url-loader',
        options: {
          name: '[name].[ext]',
          outputPath: 'images'
        }
      }]
    }]
  }

图片还是可以成功被打包出来。

image.png

那么url-loaderfile-loader的区别在于哪里呢?我们可以点开F12去查看一下这个文件

image.png

可以发现,这个文件已经被url-loader解析成了base 64的String。然后直接将这个字符串放进bundle.js之中。

所以对比file-loader, url-loader更适用与小的图片,并且可以少请求一次对图片的http请求。不然图片过大会增加页面的加载速度,降低性能。

url-loader可以配置一个limit属性,在超过限制大小时,会像file-loader一样解析图片。

options: {
          name: '[name].[ext]',
          outputPath: 'images',
          limit:8192 //limit to 8kb
        }

这里将大小限制到8kb(源文件大小在11kb左右),由于图片大于限制大小,所以并不会被打进bundle.js

image.png

打包样式

想要给图片增加一些样式,添加一个style.css的样式文件。里面添置一些文件的样式:

.twice_img {
  width: 400px;
  height: 400px;
  margin: auto;
}

将这个样式文件引入到入口文件之中,并将这个class添加到img element之中。

import img from './imgs/twice.jpg'
import './style.css'

console.log('file is', img)
const ImgElement = new Image();
ImgElement.src = img;
ImgElement.classList.add('twice_img');
document.getElementById('root').append(ImgElement)

现在直接打包显然肯定是会失败的。还是哪一个原则:webpack只能识别js,不能识别其他文件。这里要引入两个loader去识别css文件:css-loader, style-loader

  • 安装
    npm install style-loader css-loader -S
    在安装完成之后,在webpack.config.js文件之中添加css的配置
{
      test: /\.css$/,
      use: ['style-loader', 'css-loader']
 }

重新打包之后,打开页面,可以看到图片变大,并且居中,样式也覆盖上去了。


新的样式

这里说明一下,为什么需要两个loader。

  • css-loader的作用是帮助webpack去识别样式文件
  • style-loader的作用是将样式挂载到html的style标签里。


    从style里可以看到之前的样式

打包scss文件

在项目中一啊不能都会使用sass或者less的预编译css文件。这里也打包一下sass文件。

  • 安装loader npm install sass-loader sass -S
    改写一下样式文件style.css ---> style.scss
body {
  #root {
    width: 100%;
    height: 100%;
  }
  .twice_img {
    display: block;
    width: 400px;
    height: 400px;
    margin: auto;
  }
}

更改一下打包策略

{
        test: /\.scss$/,
        use: ['style-loader', 'css-loader', 'sass-loader']
      }

再重新打包一下,打开页面


image.png

添加postcss

如果在样式中需要使用一些css新特性如grid之类的,需要对样式做兼容性处理,前面拼上厂商前缀如,-webkit-
安装postcss-loader以及autoprefixer
npm install postcss-loader autoprefixer -S
配置postcss.config.js,放在和webpack.config.js同一目录之下。

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

配置完之后重新打包,但是从页面上并没有看到拼的厂商前缀:


image.png

原因是在package.json文件之中需要添加浏览器支持配置,添加一下就可以看到了。

...
  "devDependencies": {
    "css-loader": "^3.5.3",
    "style-loader": "^1.2.1"
  },
  "browserslist": [
    "defaults",
    "not ie <= 8",
    "last 2 versions",
    "> 1%",
    "iOS >= 7",
    "Android >= 4.0"
  ]
}

打包样式,loader常用的配置项

importLoaders

先描述一种场景,将scss的代码进行分割,放置在不同的文件之中。然后在style.scss这个文件中引入其他的scss文件。

image.png

image.png

这种场景之下,scss文件中引入的其他scss文件可能会不依次走['style-loader', 'css-loader', 'sass-loader', 'postcss-loader']这个顺序,可能会直接走css-loader以及style-loader这两个loader,从而导致样式失效。

importLoaders的作用就是,可以确保引入的scss文件也能将执行css-loaders之前的loaders执行完。

use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2,
              // 0 => no loaders (default);
              // 1 => postcss-loader;
              // 2 => postcss-loader, sass-loader
            }
          },
          'sass-loader',
          'postcss-loader'
        ]

modules

这loader使用的场景是:css模块化。
比如我现在将创造图片元素这一段逻辑抽离出来变成一个function。并且放在一个新的文件createImg.js之中。然后在index.js之中去调用这一个方法。

import img from './imgs/twice.jpg'
import './style.scss'
import createImage from './createImg'

createImage()
const ImgElement = new Image();
ImgElement.src = img;
ImgElement.classList.add('twice_img');
document.getElementById('root').append(ImgElement)

这样从页面上就会得到两个一模一样的图片,并且样式也一样。因为在index.js中都引用了样式文件,在一定程度上造成了样式污染。为了让两个图片拥有不一样的样式,可以将样式模块化。
添加module的配置

{
        test: /\.scss$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2,
              // 0 => no loaders (default);
              // 1 => postcss-loader;
              // 2 => postcss-loader, sass-loader,
              modules: true
            }
          },
          'sass-loader',
          'postcss-loader'
        ]
      }

同时对代码进行改写

import style from './style.scss'
import createImage from './createImg'

createImage()
const ImgElement = new Image();
ImgElement.src = img;
ImgElement.classList.add(style.twice_img); // twice_img是class的类名
document.getElementById('root').append(ImgElement)

分成不同模块之后,生成的图片样式就不相同了。


image.png

打包字体

在项目中最常见的字体应用场景就是由font生成的那些icon了。
从iconFont上将字体下载之后,放在src/fonts的文件里。附带的字体申明样式放在font.scss之中,项目的目录如下:

image.png

在生成的dom元素上加上相对应的iconfont的class

const iconHtml = `<span class="icon iconfont icon-Dyanjing"></span><span class="icon iconfont icon-caidan"></span>`

document.getElementById('root').innerHTML = iconHtml;

最后更改一下打包规则,添加对字体文件的打包:

{
        test: /\.(eot|woff2|woff|ttf|svg)$/,
        use: [{
          //placeholder
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'fonts',
          }
        }]
      }

打包一下,打开页面,icon就成功出现啦:


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335