Babel插件和preset

前面的章节学习了babel的编译流程,也深入了原理,知道了怎么用babel的api来完成一些代码转换功能,但平时我们很少单独使用babel的api,更多的是封装成插件,插件可以上传到npm来复用。

这一节来学习下babel插件的格式以及preset。

plugin 的使用

首先回顾下plugin的使用,babel的plugin是在配置文件里面通过plugins选项配置,值为字符串或者数组。

js 复制代码
{
    "plugins": ["pluginA", ["pluginB"], ["pluginC", {/* options */}]]
}

如果需要传参就用数组格式,第二个元素为参数。

plugin的格式

babel plugin有两种格式:

返回对象的函数

第一种是一个函数返回一个对象的格式,对象里有pre、visitor、post、inherits、manipulateOptions等属性。

js 复制代码
export default function(api, options, dirname) {
  return {
    inherits: parentPlugin,
    manipulateOptions(options, parserOptions) {
        options.xxx = '';
    },
    pre(file) {
      this.cache = new Map();
    },
    visitor: {
      StringLiteral(path, state) {
        this.cache.set(path.node.value, 1);
      }
    },
    post(file) {
      console.log(this.cache);
    }
  };
} 

首先插件函数有三个参数api、options、dirname:

  • api里包含了babel的各种api,如types、template等,这些包就不需要在插件里单独引入了,直接取来用就行。
  • options就是外面传入的参数
  • dirname是目录名(不常用)

返回的对象有inheritsvisitorpostpremanipulateOptions等属性:

  • inherits: 指定继承某个插件,和当前插件的options合并,通过Object.assign的方式。
  • visitor: travers时调用的函数。
  • pre和post分别在遍历前后调用,可以做一些插件调用前后的逻辑,比如可以往file(表示文件的对象,在插件里面通过state.file拿到)中放一些东西,在遍历的过程中取出来。
  • manipulateOptions:用于修改options,是在插件里面修改配置的方式,比如syntaxt plugin一般都会修改parse options:

插件做的事情就是通过api拿到types、template等,通过state.opts拿到参数,然后通过path来修改AST。可以通过state放一些遍历过程中共享的数据,通过file放一些整个插件都能访问到的一些数据,除了这两种之外,还可以通过this来传递本对象共享的数据。

对象

插件的第二种格式就是直接写一个对象,不用函数包裹,这种方式用于不需要处理参数的情况。

js 复制代码
export default plugin =  {
    pre(state) {
      this.cache = new Map();
    },
    visitor: {
      StringLiteral(path, state) {
        this.cache.set(path.node.value, 1);
      }
    },
    post(state) {
      console.log(this.cache);
    }
};

preset

plugin是单个转换功能的实现,当plugin比较多或者plugin的options比较多的时候,就会导致使用成本的增高。这个时候可以封装成一个preset,用户可以通过preset来批量引入plugin,并进行一些配置。preset就是对babel配置的一层封装。

比如使用plugin的时候,开发者需要知道每个plugin是干嘛的:

而有preset之后就不再需要知道用到了什么插件,只需要选择合适的preset,然后配置一下,就会引入需要的插件,这就是preset的 意义。可以说preset是plugin的集合。我们学babel的内置功能就是学preset的配置,比如preset-env、preset-typescript等:

preset和plugin格式一样,也可以是一个对象或者是一个函数,函数的参数也是一样的api和options,区别只是preset返回的是配置对象,包含plugin和preset:

js 复制代码
export default function(api, options) {
  return {
      plugins: ['pluginA'],
      presets: [['presetsB', { options: 'bbb'}]]
  }
}

js 复制代码
export default obj = {
      plugins: ['pluginA'],
      presets: [['presetsB', { options: 'bbb'}]]
}

ConfigItem

@babel/core提供了createConfigItem的api,用于创建配置项。之前都是字面量的形式创建的。当需要抽离配置出去的时候,可以使用createConfigItem。

js 复制代码
const pluginA = createConfigItem('pluginA);
const presetB = createConfigItem('presetsB', { options: 'bbb'})

export default obj = {
      plugins: [ pluginA ],
      presets: [ presetB ]
  }
}

顺序

preset和plugin从形式上看差不多,但是应用顺序是不同的。

bable会按照如下顺序处理plugin和preset:

  1. 先应用plugin,再应用preset。
  2. plugin从前到后,preset从后往前。

这个顺序是babel规定的。

相关推荐
aoi3 个月前
Babel 示例插件:处理 AST 替换变量、箭头函数
javascript·babel
文艺理科生5 个月前
Webpack项目构建入门:babel的核心角色
前端·webpack·babel
阿镇吃橙子6 个月前
由浅入深 ——Vite工具链学习总结
vue.js·vite·babel
总之就是非常可爱6 个月前
提升前端开发效率:利用 Babel 实现 JavaScript 文件的定制化修改
前端·babel
月下点灯6 个月前
小白也能看懂的AST抽象语法树+babel插件开发教程
前端·javascript·babel
let_code6 个月前
Babel
前端·babel
ichimaru_xx6 个月前
node前端工具实战-svg引入整理工具
node.js·babel
每天写一个BUG7 个月前
简单玩一玩 Babel
前端·babel·前端工程化
yuansucai7 个月前
LocatorJS接入
babel
喜欢踢足球的老罗7 个月前
一个H5页面中直接使用React的示例与说明
前端·react.js·前端框架·babel