在compiler
中找到的parser
实例用于解析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(/* ... */);
});
});
与编译器一样,tapAsync
和 tapPromise
也可能可用,具体取决于钩子的类型。
parser
暴露了以下生命周期钩子,可以通过以下方式访问它们
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;
SyncBailHook
在评估表达式时调用。
expressionType
expression
例如
index.js
const a = new String();
MyPlugin.js
parser.hooks.evaluate.for('NewExpression').tap('MyPlugin', (expression) => {
/* ... */
return expressionResult;
});
其中表达式类型包括
'ArrowFunctionExpression'
'AssignmentExpression'
'AwaitExpression'
'BinaryExpression'
'CallExpression'
'ClassExpression'
'ConditionalExpression'
'FunctionExpression'
'Identifier'
'LogicalExpression'
'MemberExpression'
'NewExpression'
'ObjectExpression'
'SequenceExpression'
'SpreadElement'
'TaggedTemplateExpression'
'TemplateLiteral'
'ThisExpression'
'UnaryExpression'
'UpdateExpression'
SyncBailHook
在评估作为自由变量的标识符时调用。
identifier
expression
SyncBailHook
在评估作为已定义变量的标识符时调用。
identifier
expression
SyncBailHook
在评估成功评估的表达式的成员函数调用时调用。
identifier
expression
param
此表达式将触发钩子
index.js
const a = expression.myFunc();
MyPlugin.js
parser.hooks.evaluateCallExpressionMember
.for('myFunc')
.tap('MyPlugin', (expression, param) => {
/* ... */
return expressionResult;
});
SyncBailHook
一个通用钩子,用于代码片段中每个解析的语句。
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'
SyncBailHook
在解析if语句时调用。与statement
钩子相同,但仅当statement.type == 'IfStatement'
时触发。
statement
SyncBailHook
在解析带有label的语句时调用。这些语句的statement.type === 'LabeledStatement'
。
labelName
statement
SyncBailHook
为代码片段中的每个import语句调用。source
参数包含导入文件的名称。
statement
source
以下import语句将触发钩子一次
index.js
import _ from 'lodash';
MyPlugin.js
parser.hooks.import.tap('MyPlugin', (statement, source) => {
// source == 'lodash'
});
SyncBailHook
为每个import
语句的每个说明符调用。
statement
source
exportName
identifierName
以下import语句将触发钩子两次
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'
*/
}
);
SyncBailHook
为代码片段中的每个export
语句调用。
statement
SyncBailHook
为每个export
-import语句(例如:export * from 'otherModule';
)调用。
statement
source
SyncBailHook
为每个导出声明的export
语句调用。
statement
declaration
这些导出将触发此钩子
export const myVar = 'hello'; // also var, let
export function FunctionName() {}
export class ClassName {}
SyncBailHook
为每个导出表达式的export
语句(例如export default expression;
)调用。
statement
declaration
SyncBailHook
为每个export
语句的每个说明符调用。
statement
identifierName
exportName
index
SyncBailHook
为每个export
-import语句的每个说明符调用。
statement
source
identifierName
exportName
index
SyncBailHook
在解析变量声明时调用。
declaration
SyncBailHook
在解析使用let
定义的变量声明时调用
declaration
SyncBailHook
在解析使用const
定义的变量声明时调用
declaration
SyncBailHook
在解析使用var
定义的变量声明时调用
declaration
SyncBailHook
在重命名标识符之前触发,以确定是否允许重命名。这通常与rename
钩子一起使用。
identifier
expression
var a = b;
parser.hooks.canRename.for('b').tap('MyPlugin', (expression) => {
// returning true allows renaming
return true;
});
SyncBailHook
在重命名时触发,以获取新的标识符。此钩子仅当canRename
返回true
时才会被调用。
identifier
expression
var a = b;
parser.hooks.rename.for('b').tap('MyPlugin', (expression) => {});
SyncBailHook
在解析AssignmentExpression
之前,先解析被赋值的表达式时调用。
identifier
expression
a += b;
parser.hooks.assigned.for('a').tap('MyPlugin', (expression) => {
// this is called before parsing b
});
SyncBailHook
在解析AssignmentExpression
之前,先解析赋值表达式时调用。
identifier
expression
a += b;
parser.hooks.assigned.for('a').tap('MyPlugin', (expression) => {
// this is called before parsing a
});
SyncBailHook
在解析标识符的typeof
时触发
identifier
expression
SyncBailHook
在解析函数调用时调用。
identifier
expression
eval(/* something */);
parser.hooks.call.for('eval').tap('MyPlugin', (expression) => {});
SyncBailHook
在解析对对象成员函数的调用时触发。
objectIdentifier
expression, properties
myObj.anyFunc();
parser.hooks.callMemberChain
.for('myObj')
.tap('MyPlugin', (expression, properties) => {});
SyncBailHook
在解析new
表达式时调用。
identifier
expression
new MyClass();
parser.hooks.new.for('MyClass').tap('MyPlugin', (expression) => {});
SyncBailHook
在解析表达式时调用。
identifier
expression
const a = this;
parser.hooks.expression.for('this').tap('MyPlugin', (expression) => {});
SyncBailHook
在解析ConditionalExpression
(例如condition ? a : b
)时调用
expression
SyncBailHook
访问代码片段的抽象语法树(AST)
ast
comments