Javascript 解析器钩子

parser 实例位于 compiler 中,用于解析 webpack 处理的每个模块。parser 是另一个扩展 tapable 的 webpack 类,它提供各种 tapable 挂钩,插件作者可以使用这些挂钩来自定义解析过程。

parser 位于 NormalModuleFactory 中,因此需要更多工作才能访问它。

compiler.hooks.normalModuleFactory.tap('MyPlugin', (factory) => {
  factory.hooks.parser
    .for('javascript/auto')
    .tap('MyPlugin', (parser, options) => {
      parser.hooks.someHook.tap(/* ... */);
    });
});

compiler 一样,tapAsynctapPromise 也可能根据挂钩类型而可用。

挂钩

以下生命周期挂钩由 parser 公开,可以这样访问它们

evaluateTypeof

SyncBailHook

在评估包含自由变量的 typeof 的表达式时触发

  • 挂钩参数:identifier
  • 回调参数:expression
parser.hooks.evaluateTypeof
  .for('myIdentifier')
  .tap('MyPlugin', (expression) => {
    /* ... */
    return expressionResult;
  });

这将触发 evaluateTypeof 挂钩

const a = typeof myIdentifier;

这不会触发

const myIdentifier = 0;
const b = typeof myIdentifier;

evaluate

SyncBailHook

在评估表达式时调用。

  • 挂钩参数:expressionType
  • 回调参数:expression

例如

index.js

const a = new String();

MyPlugin.js

parser.hooks.evaluate.for('NewExpression').tap('MyPlugin', (expression) => {
  /* ... */
  return expressionResult;
});

其中表达式的类型为

  • 'ArrowFunctionExpression'
  • '赋值表达式'
  • '等待表达式'
  • '二元表达式'
  • '调用表达式'
  • '类表达式'
  • '条件表达式'
  • '函数表达式'
  • '标识符'
  • '逻辑表达式'
  • '成员表达式'
  • '新建表达式'
  • '对象表达式'
  • '序列表达式'
  • '扩展元素'
  • '标记模板表达式'
  • '模板字面量'
  • 'this 表达式'
  • '一元表达式'
  • '更新表达式'

evaluateIdentifier

SyncBailHook

在评估一个自由变量的标识符时调用。

  • 挂钩参数:identifier
  • 回调参数:expression

evaluateDefinedIdentifier

SyncBailHook

在评估一个已定义变量的标识符时调用。

  • 挂钩参数:identifier
  • 回调参数:expression

evaluateCallExpressionMember

SyncBailHook

在评估对已成功评估表达式的成员函数的调用时调用。

  • 挂钩参数:identifier
  • 回调参数:expression param

此表达式将触发钩子

index.js

const a = expression.myFunc();

MyPlugin.js

parser.hooks.evaluateCallExpressionMember
  .for('myFunc')
  .tap('MyPlugin', (expression, param) => {
    /* ... */
    return expressionResult;
  });

statement

SyncBailHook

通用钩子,在代码片段中解析的每个语句都会调用。

  • 回调参数:statement
parser.hooks.statement.tap('MyPlugin', (statement) => {
  /* ... */
});

其中 statement.type 可以是

  • '块语句'
  • '变量声明'
  • '函数声明'
  • '返回语句'
  • '类声明'
  • '表达式语句'
  • '导入声明'
  • '导出所有声明'
  • '导出默认声明'
  • '导出命名声明'
  • 'if 语句'
  • 'switch 语句'
  • 'for...in 语句'
  • 'for...of 语句'
  • 'for 语句'
  • 'while 语句'
  • 'do...while 语句'
  • '抛出语句'
  • 'try 语句'
  • '带标签语句'
  • 'with 语句'

statementIf

SyncBailHook

在解析 if 语句时调用。与 statement 钩子相同,但仅在 statement.type == 'IfStatement' 时触发。

  • 回调参数:statement

label

SyncBailHook

在解析带有 标签 的语句时调用。这些语句具有 statement.type === 'LabeledStatement'

  • 钩子参数:labelName
  • 回调参数:statement

import

SyncBailHook

在代码片段中的每个导入语句都会调用。source 参数包含导入文件的名称。

  • 回调参数:statement source

以下导入语句将触发钩子一次

index.js

import _ from 'lodash';

MyPlugin.js

parser.hooks.import.tap('MyPlugin', (statement, source) => {
  // source == 'lodash'
});

importSpecifier

SyncBailHook

针对每个import语句的每个说明符调用。

  • 回调参数:statement source exportName identifierName

以下导入语句将触发钩子两次

index.js

import _, { has } from 'lodash';

MyPlugin.js

parser.hooks.importSpecifier.tap(
  'MyPlugin',
  (statement, source, exportName, identifierName) => {
    /* First call
    source == 'lodash'
    exportName == 'default'
    identifierName == '_'
  */
    /* Second call
    source == 'lodash'
    exportName == 'has'
    identifierName == 'has'
  */
  }
);

export

SyncBailHook

针对代码片段中的每个export语句调用。

  • 回调参数:statement

exportImport

SyncBailHook

针对每个export-import语句调用,例如:export * from 'otherModule';

  • 回调参数:statement source

exportDeclaration

SyncBailHook

针对每个导出声明的export语句调用。

  • 回调参数:statement declaration

这些导出将触发此钩子

export const myVar = 'hello'; // also var, let
export function FunctionName() {}
export class ClassName {}

exportExpression

SyncBailHook

针对每个导出表达式的export语句调用,例如:export default expression;

  • 回调参数:statement declaration

exportSpecifier

SyncBailHook

针对每个export语句的每个说明符调用。

  • 回调参数:statement identifierName exportName index

exportImportSpecifier

SyncBailHook

针对每个export-import语句的每个说明符调用。

  • 回调参数:statement source identifierName exportName index

varDeclaration

SyncBailHook

解析变量声明时调用。

  • 回调参数:declaration

varDeclarationLet

SyncBailHook

解析使用let定义的变量声明时调用

  • 回调参数:declaration

varDeclarationConst

SyncBailHook

解析使用const定义的变量声明时调用

  • 回调参数:declaration

varDeclarationVar

SyncBailHook

在解析使用var定义的变量声明时调用。

  • 回调参数:declaration

canRename

SyncBailHook

在重命名标识符之前触发,以确定是否允许重命名。这通常与rename钩子一起使用。

  • 挂钩参数:identifier
  • 回调参数:expression
var a = b;

parser.hooks.canRename.for('b').tap('MyPlugin', (expression) => {
  // returning true allows renaming
  return true;
});

rename

SyncBailHook

在重命名时触发,以获取新的标识符。仅当canRename返回true时才会调用此钩子。

  • 挂钩参数:identifier
  • 回调参数:expression
var a = b;

parser.hooks.rename.for('b').tap('MyPlugin', (expression) => {});

assigned

SyncBailHook

在解析AssignmentExpression之前解析分配的表达式时调用。

  • 挂钩参数:identifier
  • 回调参数:expression
a += b;

parser.hooks.assigned.for('a').tap('MyPlugin', (expression) => {
  // this is called before parsing b
});

assign

SyncBailHook

在解析AssignmentExpression之前解析分配表达式时调用。

  • 挂钩参数:identifier
  • 回调参数:expression
a += b;

parser.hooks.assigned.for('a').tap('MyPlugin', (expression) => {
  // this is called before parsing a
});

typeof

SyncBailHook

在解析标识符的typeof时触发。

  • 挂钩参数:identifier
  • 回调参数:expression

call

SyncBailHook

在解析函数调用时调用。

  • 挂钩参数:identifier
  • 回调参数:expression
eval(/* something */);

parser.hooks.call.for('eval').tap('MyPlugin', (expression) => {});

callMemberChain

SyncBailHook

在解析对对象成员函数的调用时触发。

  • 钩子参数:objectIdentifier
  • 回调参数:expression, properties
myObj.anyFunc();

parser.hooks.callMemberChain
  .for('myObj')
  .tap('MyPlugin', (expression, properties) => {});

new

SyncBailHook

在解析new表达式时调用。

  • 挂钩参数:identifier
  • 回调参数:expression
new MyClass();

parser.hooks.new.for('MyClass').tap('MyPlugin', (expression) => {});

expression

SyncBailHook

在解析表达式时调用。

  • 挂钩参数:identifier
  • 回调参数:expression
const a = this;

parser.hooks.expression.for('this').tap('MyPlugin', (expression) => {});

expressionConditionalOperator

SyncBailHook

在解析ConditionalExpression时调用,例如condition ? a : b

  • 回调参数:expression

program

SyncBailHook

访问代码片段的抽象语法树 (AST)

  • 参数:ast comments

6 位贡献者

byzykDeTeammisterdevEugeneHlushkochenxsansnitin315