教你写个webpack的loader

栏目: CSS · 发布时间: 6年前

loader介绍

loader 是将指定格式的资源文件转化成一定格式输出,例如 sass-loaderscss 文件转化成 css 文件, babel-loaderES6 转化成 ES5 .一个 loader 的结构就是一个函数,最简单 loader 如下:

module.exports = function(content){  // content就是你要处理文件的内容,如处理App.vue文件,content就是你在App.vue写的代码
    //... 中间可以对content处理
    return content  // 这里你也可以用this.callback(null, content)导出
}

loader 的使用,配置 webpack 文件

{
        test: /\.css$/,
        // easy-css-loader就是下面我要写的loader
        use: ['style-loader', 'css-loader', 'easy-css-loader'] 
    }

loader 解析顺序是:从右向左, 上一个 loader 处理完的 content 传递给下一个 loader , 一般每种 loader 功能是单一的

easy-css-loader实现

easy-css-loader 将实现一些 css 代码的简写(虽然 sass 等已经有这个功能,但是每次都要写个 .scss 文件在导入,不大方便).

效果图

教你写个webpack的loader

例:

对应代码

<div>
    <div class="easy-css">2</div>
</div>
<style >
.easy-css{
  border: 1px solid red;
  posC;    
  wh(100px, 80px);
  font(20px, blue, center);
  comB(http://ww1.sinaimg.cn/large/b44313e1gy1fyz1li77jzj20q411wdop.jpg); 
}
</style>

下面讲讲 font(..) 解析过程

<!--你代码写的样式-->
<style >
  .easy-css{
    font(20px, yellow);
  }
</style>
<!-- 会解析成 -->
<style >
  .easy-css{
    font-size: 20px;
    color: yellow;
    text-align: left;
  }
</style>

上面的代码, 如果在 webpack 配置解析 .css 的自定义的 loader , 那么在 loader 里,前面说的 content 就长成这样了

.easy-css{
    font(20px, yellow);
  }

是不是只要正则匹配 font(20px, yellow) ,替换成

font-size: 20px;
color: yellow;
text-align: left;

下面是 loader 的代码

/**
 * @param {*} fontStr 待解析字符串的`font(..)`
 * @returns 解析完css字体样式
 */
function fontParse(fontStr) {
  let start = fontStr.indexOf('(') + 1  // ‘(’后面一个字符位置
  let args = fontStr.slice(start, -1)  // 就是取font(..)括号里面字符串,按例子args为'20px, yellow'
  let argsList = args.split(',')  // 分割成数组['20px', 'yellow']
  switch (argsList.length) { // 判断开发者传递参数个数
    case 2:
      argsList.push('left')
      break
    case 1:
      argsList.push('#000', 'left')
      break
  }
  cssName = ['font-size', 'color', 'text-align'].map((item, index) => {
    return `${item}:${argsList[index]}` // 组合成新的样式数组
  })
  let cssStr = cssName.join(';')  //形成新css字符串
  return cssStr  // 回调
}
module.exports = function (content) {  // content就是在<style>..</style>写的里面的内容,或者引入的.css文件
  content = content.replace(/font\((.|\n)*?\)/ig, (str) => fontParse(str)) 
  this.cacheable()  // 缓存
  this.callback(null, content)  // 回调
}

上面的正则会匹配到 font(..) , str 就匹配到的 font(20px, yellow) 字符串, 最终会被 fontParse(str) 值替换.就已经完成 font 的解析

其它样式的解析可以写成链式

module.exports = function (content) {  // content就是在<style>..</style>写的里面的内容,或者引入的.css文件
  content = content.replace(/font\((.|\n)*?\)/ig, (str) => fontParse(str))  // 解析font()字体样式
                    .replace(/wh\((.|\n)*?\)/ig, (str) => whParse(str))  // 解析wh()宽高样式
                      .replace(/posC(.|\n)*?;/ig, (str) => posCParse(str))  // 解析posC居中样式
                          .replace(/flex(.|\n)*?;/ig, (str) => flexParse(str))  // 解析flex布局样式
                            .replace(/comB(.|\n)*?;/ig, (str) => backParse(str))  // 解析comB(..)背景图片样式
                              .replace(/posL(.|\n)*?;/ig, (str) => posLRParse(str, 'left')) // 解析posL(..)居左样式
                                .replace(/posR(.|\n)*?;/ig, (str) => posLRParse(str, 'right'))  // 解析posR(..)居右样式
  this.cacheable()  // 缓存
  this.callback(null, content)  // 回调
}

一个 loader 大功告成

说明

具体的可以去看源码,在 github 上,觉得可以的话帮忙 star 一下

我发布 npmeasy-css-loader 使用如下配置

{
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader', 'easy-css-loader'] // 顺序一定要注意
      }
    ]
  }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

创新

创新

理查德·福斯特 / 王宇锋 / 中信出版社 / 2008-10 / 32.00元

《创新:进攻者的优势》内容简介:为什么一流企业突然间将它们的市场拱手让与新的竞争者?要避免这样的命运,需要无情地抛弃那些过去使它们成功的技能和产品,那么究竟哪些企业能够做到这一点呢?企业如果总是墨守成规、因循守旧,那么长期下去,必然无法以市场的速度及规模进行革新或创造价值。这样的企业会像得州仪器、施乐等市场领先者一样,被一些资源较少、技术较差、市场支配力较弱的竞争对手超越,而这些所谓进攻者的优势,......一起来看看 《创新》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具