教你写个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'] // 顺序一定要注意
      }
    ]
  }
}

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

查看所有标签

猜你喜欢:

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

Mission Python

Mission Python

Sean McManus / No Starch Press / 2018-9-18 / GBP 24.99

Launch into coding with Mission Python, a space-themed guide to building a complete computer game in Python. You'll learn programming fundamentals like loops, strings, and lists as you build Escape!, ......一起来看看 《Mission Python》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

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

RGB CMYK 互转工具