I'm writing a Webpack plugin that will find all references to i18n/translation functions with the aim of finding all texts that need translations and then uploading them to a translation service.
Any pointers on how to get started? Which hooks should I be using?
Ended up using compiler.hooks.compilation to get the compilation object, then the following to hook into when Webpack parses source code:
normalModuleFactory.hooks.parser
.for('javascript/auto')
.tap(pluginName, parserHandler);
normalModuleFactory.hooks.parser
.for('javascript/dynamic')
.tap(pluginName, parserHandler);
normalModuleFactory.hooks.parser
.for('javascript/esm')
.tap(pluginName, parserHandler);
And parserHandler uses parser.hooks.evaluate hooks to find function and method calls. This part is a bit tricky, because Webpack needs to be fooled into thinking CallExpression callee's are identifiers, otherwise Webpack won't call hooks on method/function calls you're interested in.
Something like this:
// Handler for tricking Webpack into running hooks on expressions we're interested in,
// because it doesn't do it otherwise
const evaluateHandler = (expr: Identifier | MemberExpression) => {
const funcName = isMemberExpression(expr)
? expr.property.name
: expr.name;
if (isCorrectFunction(funcName)) {
return new BasicEvaluatedExpression()
.setRange(expr.range)
.setExpression(expr)
.setIdentifier(SPECIAL_IDENTIFIER);
}
};
// Find all relevant function calls and mark them as identifiers to trick Webpack
// Into invoking the `call` hooks for these CallExpressions
parser.hooks.evaluate
.for('MemberExpression')
.tap(pluginName, evaluateHandler);
// Do the same for when functions are destructured out of the parent object
// These are actually Identifiers, but the Parser implementation doesn't mark them so for some reason
parser.hooks.evaluate
.for('Identifier')
.tap(pluginName, evaluateHandler);
// Get all relevant function call CallExpressions
parser.hooks.call
.for(SPECIAL_IDENTIFIER)
.tap(
pluginName,
(expr: CallExpression<MemberExpression | Identifier>) => {
// FUNCTION CALL FOUND HERE
}
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With