Webpack:JavascriptParser Hooks

2023-05-11 11:04 更新

?parser? 實(shí)例,在 ?compiler? 中被發(fā)現(xiàn),是用來(lái)解析由 webpack 處理過(guò)的每個(gè)模塊。?parser? 也是擴(kuò)展自 ?tapable? 的 webpack 類 并且提供多種 ?tapable? 鉤子,

以下示例中,?parser? 位于 NormalModuleFactory 中,因此需要調(diào)用額外鉤子 來(lái)進(jìn)行獲取:

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

和 ?compiler? 用法相同,取決于不同的鉤子類型, 也可以在某些鉤子上訪問(wèn) ?tapAsync? 和 ?tapPromise?。

鉤子

以下生命周期鉤子函數(shù),是由 ?parser? 暴露,可以通過(guò)如下方式訪問(wèn):

evaluateTypeof

SyncBailHook

當(dāng)對(duì)自由變量使用 ?typeof? 表達(dá)式進(jìn)行求值時(shí)觸發(fā)

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?
parser.hooks.evaluateTypeof
  .for('myIdentifier')
  .tap('MyPlugin', (expression) => {
    /* ... */
    return expressionResult;
  });

這會(huì)觸發(fā) ?evaluateTypeof? 鉤子的調(diào)用:

const a = typeof myIdentifier;

這不會(huì)觸發(fā):

const myIdentifier = 0;
const b = typeof myIdentifier;

evaluate

SyncBailHook

在求值表達(dá)式時(shí)調(diào)用

  • Hook parameters: ?expressionType?
  • Callback parameters: ?expression?

示例:

index.js

const a = new String();

MyPlugin.js

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

表達(dá)式的類型:

  • 'ArrowFunctionExpression'
  • 'AssignmentExpression'
  • 'AwaitExpression'
  • 'BinaryExpression'
  • 'CallExpression'
  • 'ClassExpression'
  • 'ConditionalExpression'
  • 'FunctionExpression'
  • 'Identifier'
  • 'LogicalExpression'
  • 'MemberExpression'
  • 'NewExpression'
  • 'ObjectExpression'
  • 'SequenceExpression'
  • 'SpreadElement'
  • 'TaggedTemplateExpression'
  • 'TemplateLiteral'
  • 'ThisExpression'
  • 'UnaryExpression'
  • 'UpdateExpression'

evaluateIdentifier

SyncBailHook

當(dāng)評(píng)估一個(gè)自由變量的標(biāo)識(shí)符時(shí)調(diào)用

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?

evaluateDefinedIdentifier

SyncBailHook

當(dāng)評(píng)估一個(gè)已定義變量的標(biāo)識(shí)符時(shí)調(diào)用

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?

evaluateCallExpressionMember

SyncBailHook

當(dāng)對(duì)已成功求值的表達(dá)式調(diào)用成員函數(shù)時(shí)調(diào)

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression? ?param?

將會(huì)觸發(fā)鉤子的表達(dá)式:

index.js

const a = expression.myFunc();

MyPlugin.js

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

statement

SyncBailHook

用于在代碼片段中解析每個(gè)語(yǔ)句時(shí)調(diào)用的通用的鉤子

  • Callback Parameters: ?statement?
parser.hooks.statement.tap('MyPlugin', (statement) => {
  /* ... */
});

其中 ?statement.type? 可能是:

  • ?'BlockStatement'?
  • ?'VariableDeclaration'?
  • ?'FunctionDeclaration'?
  • '?ReturnStatement'?
  • ?'ClassDeclaration'?
  • ?'ExpressionStatement'?
  • ?'ImportDeclaration'?
  • ?'ExportAllDeclaration'?
  • ?'ExportDefaultDeclaration'?
  • ?'ExportNamedDeclaration'?
  • ?'IfStatement'?
  • ?'SwitchStatement'?
  • ?'ForInStatement'?
  • ?'ForOfStatement'?
  • ?'ForStatement'?
  • ?'WhileStatement'?
  • ?'DoWhileStatement'?
  • ?'ThrowStatement'?
  • ?'TryStatement'?
  • ?'LabeledStatement'?
  • ?'WithStatement'?

statementIf

SyncBailHook

在解析 if 語(yǔ)句時(shí)調(diào)用。和 ?statement? 鉤子相同,但僅在 ?statement.type == 'IfStatement'? 時(shí)觸發(fā)

  • Callback Parameters: ?statement?

label

SyncBailHook

當(dāng)解析帶標(biāo)簽的語(yǔ)句時(shí)調(diào)用此鉤子。這些語(yǔ)句的類型為 ??statement.type === 'LabeledStatement'??

  • Hook Parameters: ?labelName?
  • Callback Parameters: ?statement?

import

SyncBailHook

在代碼片段中每個(gè)導(dǎo)入語(yǔ)句都會(huì)調(diào)用此鉤子。?source? 參數(shù)包含所導(dǎo)入文件的名稱

  • Callback Parameters: ?statement? ?source?

The following import statement will trigger the hook once:

index.js

import _ from 'lodash';

MyPlugin.js

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

importSpecifier

SyncBailHook

對(duì)于每個(gè)?import?語(yǔ)句中的每個(gè)指定符,都會(huì)調(diào)用此鉤子函數(shù)

  • Callback Parameters: ?statement? ?source? ?exportName? ?identifierName?

以下 import 語(yǔ)句將會(huì)觸發(fā)兩次鉤子:

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

該鉤子函數(shù)會(huì)在代碼片段中的每個(gè) export 語(yǔ)句被解析時(shí)觸發(fā)

  • Callback Parameters: ?statement?

exportImport

SyncBailHook

在代碼片段中的每個(gè)導(dǎo)出導(dǎo)入語(yǔ)句(例如:export * from 'otherModule';)都會(huì)調(diào)用該鉤子

  • Callback Parameters: ?statement? ?source?

exportDeclaration

SyncBailHook

每個(gè)導(dǎo)出聲明的導(dǎo)出語(yǔ)句都會(huì)調(diào)用此鉤子

  • Callback Parameters: ?statement? ?declaration?

這些導(dǎo)出語(yǔ)句會(huì)觸發(fā)該鉤子函數(shù):

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

exportExpression

SyncBailHook

被用于解析并評(píng)估代碼中的導(dǎo)出表達(dá)式,例如 export default expression;,在導(dǎo)出表達(dá)式時(shí)觸發(fā)此鉤子

  • Callback Parameters: ?statement? ?declaration?

exportSpecifier

SyncBailHook

該鉤子會(huì)為每個(gè)導(dǎo)出語(yǔ)句的每個(gè)成員說(shuō)明符調(diào)用

  • Callback Parameters: ?statement? ?identifierName? ?exportName? ?index?

exportImportSpecifier

SyncBailHook

該鉤子將在每個(gè)導(dǎo)出-導(dǎo)入語(yǔ)句的每個(gè)成員說(shuō)明符上觸發(fā)

  • Callback Parameters: ?statement? ?source? ?identifierName? ?exportName? ?index?

varDeclaration

SyncBailHook

解析變量聲明時(shí)觸發(fā)

  • Callback Parameters: ?declaration?

varDeclarationLet

SyncBailHook

在解析使用 ?let? 定義的變量聲明時(shí)調(diào)用

  • Callback Parameters: ?declaration?

varDeclarationConst

SyncBailHook

解析使用 const 定義的變量聲明時(shí)被調(diào)用

  • Callback Parameters: ?declaration?

varDeclarationVar

SyncBailHook

當(dāng)解析使用 var 定義的變量聲明時(shí)調(diào)用

  • Callback Parameters: ?declaration?

canRename

SyncBailHook

當(dāng)解析使用 var 定義的變量聲明時(shí)調(diào)用

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?
var a = b;

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

rename

SyncBailHook

在重命名標(biāo)識(shí)符之前觸發(fā)以確定是否允許重命名。通常與重命名鉤子一起使用

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?
var a = b;

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

assigned

SyncBailHook

會(huì)在解析 ?AssignmentExpression? 時(shí),在解析被賦值的表達(dá)式之前觸發(fā)

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?
a += b;

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

assign

SyncBailHook

會(huì)在解析 ?AssignmentExpression? 時(shí),在解析賦值的表達(dá)式之前觸發(fā)

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?
a += b;

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

typeof

SyncBailHook

當(dāng)解析標(biāo)識(shí)符的? typeof? 操作符時(shí)觸發(fā)

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?

call

SyncBailHook

在解析函數(shù)調(diào)用時(shí)被調(diào)用

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?
eval(/* something */);

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

callMemberChain

SyncBailHook

當(dāng)解析對(duì)象的成員函數(shù)的調(diào)用時(shí)觸發(fā)

  • Hook Parameters: ?objectIdentifier?
  • Callback Parameters: ?expression?? properties?
myObj.anyFunc();

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

new

SyncBailHook

該鉤子在解析 ?new? 表達(dá)式時(shí)被調(diào)用

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?
new MyClass();

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

expression

SyncBailHook

該鉤子會(huì)在解析表達(dá)式時(shí)被觸發(fā)

  • Hook Parameters: ?identifier?
  • Callback Parameters: ?expression?
const a = this;

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

expressionConditionalOperator

SyncBailHook

在解析條件表達(dá)式(例如 condition ? a : b)時(shí)調(diào)用

  • Callback Parameters: ?expression?

program

SyncBailHook

獲取代碼片段的抽象語(yǔ)法樹(shù)(AST)的訪問(wèn)權(quán)限

  • Parameters: ?ast? ?comments?


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)