前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2021了自己写个loader吧

2021了自己写个loader吧

作者头像
terrence386
发布2022-07-14 21:17:43
3170
发布2022-07-14 21:17:43
举报
文章被收录于专栏:JavaScript高级程序设计

其实你爱我像谁,扮演什么角色我都会。

前情回顾

上篇文章简单介绍了一下loader,今天谈一谈自己对loader的理解。

什么是loader

loader的定义:一个导出了一个函数的node模块儿。当某些资源或文件需要转换时这个函数被调用。并且这个函数或方法有权调用webpack提供的Loader API

loader的配置

通常情况下loader的配置在webpack的module.rules对象中,例如:

代码语言:javascript
复制
    module: {
      rules: [
        {
          // test: /\.vue$/,
          // use: [
          //   {
          //     loader: 'iview-loader',
          //     options: {
          //       prefix: true
          //     }
          //   }
          // ]
          test:/\.vue/,
          loader: 'test-loader'
        },
      ],
    },

test表示匹配到哪些文件,loader表示使用哪个loader对这些文件进行转换。这里我写了个test-loader,用来测试我本地自己写的一个demo。

测试自己的loader

自己的电脑里有之前的项目,随便起了一个基于vue的项目,在项目的根目录创建文件夹test-loader。我项目的文件夹名称为h5_pay。所以直接执行了以下命令:

代码语言:javascript
复制
# h5_pay 是我自己的项目名称 这个可以根据自己的改
cd h5_pay
mkdir test-loader && npm init

然后在test-loader文件夹下的index.js中添加如下代码:

代码语言:javascript
复制
module.exports = function(content) {
  console.log('content',content)
  return content && content.replace(/terrence/gi, 'Javascript高级程序设计')
}

这个函数接受一个参数content,表示匹配到的文件内容。如果内容中匹配到terrence这个单词,就替换为Javascript高级程序设计

接下来执行:

代码语言:javascript
复制
npm link test-loader

npm link这个命令会将本地的测试包放入node_modules中。放入的动作其实是个软连接或者硬链接,应该是个软连接。如图:

执行完这个命令以后,重启本地服务,打开页面,就会发现代码中的terrence已经被替换为Javascript高级程序设计

而对于index.js中函数接收的参数content,打印出来就是接收到的整个vue文件的代码,如图:

content是什么

再举个例子 iview-loader

iview-loader的主要功能是将带有前缀i-的组件替换为驼峰,例如i-affix替换为Affix

iview-loader中有两个文件,tag-map.jsloader.js

tag-map.js定义了带前缀组件和驼峰组件(暂且怎么叫吧)的映射关系。

代码语言:javascript
复制
// tag-map.js
exports.tag = {
    'Switch': 'i-switch',
    'Circle': 'i-circle'
};

exports.prefixTag = {
    'i-affix': 'Affix',
    'i-alert': 'Alert',
    'i-anchor': 'Anchor',
    'i-anchor-link': 'AnchorLink',
    'i-auto-complete': 'AutoComplete',
    'i-avatar': 'Avatar',
    'i-back-top': 'BackTop',
    'i-badge': 'Badge',
    'i-breadcrumb': 'Breadcrumb',
    'i-breadcrumb-item': 'BreadcrumbItem',
    'i-button': 'Button',
    'i-button-group': 'ButtonGroup',
    'i-card': 'Card',
    'i-carousel': 'Carousel',
    'i-carousel-item': 'CarouselItem',
    'i-cascader': 'Cascader',
    ...
};

loader.js定义了组件名称的替换法则,并在匹配到vue文件时进行替换。

代码语言:javascript
复制
// loader.js
"use strict";

const loaderUtils = require('loader-utils');
const { tag, prefixTag } = require('./tag-map');

function replaceTag(source, tagMap) {
    Object.keys(tagMap).forEach(i => {
        source = source.replace(new RegExp(`<${i}(?!-)`, 'g'), `<${tagMap[i]}`)
            .replace(new RegExp(`<\/${i}>`, 'g'), `<\/${tagMap[i]}>`);
    })
    return source;
}

module.exports = function (source) {
    const options = loaderUtils.getOptions(this);
    this.cacheable();

    let newSource = source;
    newSource = replaceTag(newSource, tag);

    if ('prefix' in options && options.prefix) {
        newSource = replaceTag(newSource, prefixTag);
    }

    return newSource;
};

这里需要注意的是引用了一个新的包loader-utils。loader-utils是一个webpack工具类,通过一些方法配合loader处理文件。大致内容如图:

这个包在开发loader时非常重要。

总结

  • 自己如何开发一个loader
  • 简单分析下iview-loader
  • 加深对loader的理解

javascript基础知识总结

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JavaScript高级程序设计 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前情回顾
  • 什么是loader
  • loader的配置
  • 测试自己的loader
  • 再举个例子 iview-loader
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档