The parser instance, found in the compiler, is used to parse each module being processed by webpack. The parser is yet another webpack class that extends tapable and provides a variety of tapable hooks that can be used by plugin authors to customize the parsing process.
The parser is found within NormalModuleFactory and therefore takes little more work to access:
compiler.hooks.normalModuleFactory.tap('MyPlugin', (factory) => {
factory.hooks.parser
.for('javascript/auto')
.tap('MyPlugin', (parser, options) => {
parser.hooks.someHook.tap(/* ... */);
});
}); As with the compiler, tapAsync and tapPromise may also be available depending on the type of hook.
The following lifecycle hooks are exposed by the parser and can be accessed as such:
SyncBailHook
Triggered when evaluating an expression consisting in a typeof of a free variable
identifierexpressionparser.hooks.evaluateTypeof
.for('myIdentifier')
.tap('MyPlugin', (expression) => {
/* ... */
return expressionResult;
}); This will trigger the evaluateTypeof hook:
const a = typeof myIdentifier; This won't trigger:
const myIdentifier = 0;
const b = typeof myIdentifier; SyncBailHook
Called when evaluating an expression.
expressionTypeexpressionFor example:
index.js
const a = new String(); MyPlugin.js
parser.hooks.evaluate.for('NewExpression').tap('MyPlugin', (expression) => {
/* ... */
return expressionResult;
}); Where the expressions types are:
'ArrowFunctionExpression''AssignmentExpression''AwaitExpression''BinaryExpression''CallExpression''ClassExpression''ConditionalExpression''FunctionExpression''Identifier''LogicalExpression''MemberExpression''NewExpression''ObjectExpression''SequenceExpression''SpreadElement''TaggedTemplateExpression''TemplateLiteral''ThisExpression''UnaryExpression''UpdateExpression'SyncBailHook
Called when evaluating an identifier that is a free variable.
identifierexpressionSyncBailHook
Called when evaluating an identifier that is a defined variable.
identifierexpressionSyncBailHook
Called when evaluating a call to a member function of a successfully evaluated expression.
identifierexpression paramThis expression will trigger the hook:
index.js
const a = expression.myFunc(); MyPlugin.js
parser.hooks.evaluateCallExpressionMember
.for('myFunc')
.tap('MyPlugin', (expression, param) => {
/* ... */
return expressionResult;
}); SyncBailHook
General purpose hook that is called for every parsed statement in a code fragment.
statementparser.hooks.statement.tap('MyPlugin', (statement) => {
/* ... */
}); Where the statement.type could be:
'BlockStatement''VariableDeclaration''FunctionDeclaration''ReturnStatement''ClassDeclaration''ExpressionStatement''ImportDeclaration''ExportAllDeclaration''ExportDefaultDeclaration''ExportNamedDeclaration''IfStatement''SwitchStatement''ForInStatement''ForOfStatement''ForStatement''WhileStatement''DoWhileStatement''ThrowStatement''TryStatement''LabeledStatement''WithStatement'SyncBailHook
Called when parsing an if statement. Same as the statement hook, but triggered only when statement.type == 'IfStatement'.
statementSyncBailHook
Called when parsing statements with a label. Those statements have statement.type === 'LabeledStatement'.
labelNamestatementSyncBailHook
Called for every import statement in a code fragment. The source parameter contains the name of the imported file.
statement sourceThe following import statement will trigger the hook once:
index.js
import _ from 'lodash'; MyPlugin.js
parser.hooks.import.tap('MyPlugin', (statement, source) => {
// source == 'lodash'
}); SyncBailHook
Called for every specifier of every import statement.
statement source exportName identifierNameThe following import statement will trigger the hook twice:
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
Called for every export statement in a code fragment.
statementSyncBailHook
Called for every export-import statement eg: export * from 'otherModule';.
statement sourceSyncBailHook
Called for every export statement exporting a declaration.
statement declarationThose exports will trigger this hook:
export const myVar = 'hello'; // also var, let
export function FunctionName() {}
export class ClassName {} SyncBailHook
Called for every export statement exporting an expression e.g.export default expression;.
statement declarationSyncBailHook
Called for every specifier of every export statement.
statement identifierName exportName indexSyncBailHook
Called for every specifier of every export-import statement.
statement source identifierName exportName indexSyncBailHook
Called when parsing a variable declaration.
declarationSyncBailHook
Called when parsing a variable declaration defined using let
declarationSyncBailHook
Called when parsing a variable declaration defined using const
declarationSyncBailHook
Called when parsing a variable declaration defined using var
declarationSyncBailHook
Triggered before renaming an identifier to determine if the renaming is allowed. This is usually used together with the rename hook.
identifierexpressionvar a = b;
parser.hooks.canRename.for('b').tap('MyPlugin', (expression) => {
// returning true allows renaming
return true;
}); SyncBailHook
Triggered when renaming to get the new identifier. This hook will be called only if canRename returns true.
identifierexpressionvar a = b;
parser.hooks.rename.for('b').tap('MyPlugin', (expression) => {}); SyncBailHook
Called when parsing an AssignmentExpression before parsing the assigned expression.
identifierexpressiona += b;
parser.hooks.assigned.for('a').tap('MyPlugin', (expression) => {
// this is called before parsing b
}); SyncBailHook
Called when parsing an AssignmentExpression before parsing the assign expression.
identifierexpressiona += b;
parser.hooks.assigned.for('a').tap('MyPlugin', (expression) => {
// this is called before parsing a
}); SyncBailHook
Triggered when parsing the typeof of an identifier
identifierexpressionSyncBailHook
Called when parsing a function call.
identifierexpressioneval(/* something */);
parser.hooks.call.for('eval').tap('MyPlugin', (expression) => {}); SyncBailHook
Triggered when parsing a call to a member function of an object.
objectIdentifierexpression, propertiesmyObj.anyFunc();
parser.hooks.callMemberChain
.for('myObj')
.tap('MyPlugin', (expression, properties) => {}); SyncBailHook
Invoked when parsing a new expression.
identifierexpressionnew MyClass();
parser.hooks.new.for('MyClass').tap('MyPlugin', (expression) => {}); SyncBailHook
Called when parsing an expression.
identifierexpressionconst a = this;
parser.hooks.expression.for('this').tap('MyPlugin', (expression) => {}); SyncBailHook
Called when parsing a ConditionalExpression e.g. condition ? a : b
expressionSyncBailHook
Get access to the abstract syntax tree (AST) of a code fragment
ast comments