A webpack plugin that accepts a function name, and a callback that will be called with the arguments that were passed to the original function. The callback will be called during the webpack build time.
This was written as an exercise because of this StackOverflow question: Webpack plugin to statically analyze the usage of an exported function?
-
Install dependencies
yarn
-
Run webpack
yarn webpack
Given this source code:
import { log } from './helpers/log';
// these will be logged
log(1);
log(2, 3);
log(2, "foo");
log(2, "foo", 4, "bar");
log(2, "foo", 4, "bar", [1, 2, "asd"]);
log(2, "foo", 4, "bar", [1, 2, "asd"], { foo: "bar" }, [
{ a: "asd", b: 123, c: [] },
]);
// this one will not be logged because it's using a variable
const a = [1,2,3];
log(a);
// this one will also not be logged because it's not using `log` exactly
console.log('asd');
And this webpack configuration:
const FunctionCallPlugin = require('./webpack-plugins/FunctionCall');
module.exports = {
plugins: [ new FunctionCallPlugin({ functionName: 'log', callback: ({ arguments: args }) => {
console.log('`log` function was found and called with the arguments:', args);
// you can do whatever here, make a http request, write to db, etc
}})],
}
This is the terminal outputs when running webpack:
➜ webpack-plugin-function-invoke git:(master) ✗ yarn webpack
yarn run v1.16.0
warning ..\package.json: No license field
$ D:\Projects\webpack-plugin-function-invoke\node_modules\.bin\webpack
`log` function was found and called with the arguments: [ 1 ]
`log` function was found and called with the arguments: [ 2, 3 ]
`log` function was found and called with the arguments: [ 2, 'foo' ]
`log` function was found and called with the arguments: [ 2, 'foo', 4, 'bar' ]
`log` function was found and called with the arguments: [ 2, 'foo', 4, 'bar', [ 1, 2, 'asd' ] ]
`log` function was found and called with the arguments: [
2,
'foo',
4,
{ foo: 'bar' },
[ { a: 'asd', b: 123, c: [] } ]
]
- It loops through all webpack chunks, and all modules inside of each chunks to see if they have any dependencies with the specified name. For example, if you are looking for
log
, it will find any modules that either doesimport { log } from './somewhere'
orimport log from './somewhere'
- For every modules that have the specified dependencies, it collect all the file paths to the original source code by looking at its
fileDependencies
- Each of the files' source code are read as string using
fs
module - The source code are parsed into an AST using babel parser
- The AST is traversed and we look into all
CallExpression
that uses the same specified function name - We collect all the arguments used in the function call
- We run the specified callback, while passing the collected arguments