Skip to content

Instantly share code, notes, and snippets.

@jpellizzari
Created November 16, 2017 20:37
Show Gist options
  • Save jpellizzari/d3824fda5c2eccea246f8a6622080753 to your computer and use it in GitHub Desktop.
Save jpellizzari/d3824fda5c2eccea246f8a6622080753 to your computer and use it in GitHub Desktop.
// Babel plugin to parse the AST and find where mixpanel events are called.
// This is used to generate the `mixpanel-report.json` file.
// https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md
const fs = require('fs');
const _ = require('lodash');
const OUTPUT_PATH = './build-external/mixpanel-report.json';
const events = [];
// Extracts params from `trackMixpanelEvent` calls.
// Tries to parse out strings used as params, but some can only be determined at runtime.
function extractProps(props) {
return _.reduce(props, (r, p) => {
const key = _.get(p, 'key.name');
if (p.value) {
const value = p.value.type === 'StringLiteral' ? p.value.value : `<variable: ${p.value.name}>`;
r[key] = value;
}
return r;
}, {});
}
const findMixpanel = {
CallExpression(path, { name, parent }) {
path.traverse({
Identifier(child) {
if (child.node.name === 'trackMixpanelEvent') {
let mixpanelEventParams;
const mixpanelEventName = _.get(child.parent, 'arguments[0].value');
const params = _.get(child.parent, 'arguments[1].properties');
const description = _.get(child.parent, 'arguments[2].value');
if (params) {
mixpanelEventParams = extractProps(params);
}
const d = {
file: _.get(path.hub, ['file', 'opts', 'sourceFileName']),
mixpanelEventName,
loc: path.node.loc,
mixpanelEventParams,
functionName: name,
parentClass: parent,
description: description || null,
};
events.push(d);
}
}
});
}
};
const classMethods = {
ClassMethod(path, { name }) {
path.traverse(findMixpanel, { name: _.get(path.node, ['key', 'name']), parent: name });
}
};
module.exports = function parse() {
return {
visitor: {
FunctionDeclaration(path) {
// Search in functions
path.traverse(findMixpanel, { name: _.get(path.node, ['id', 'name']) });
},
ClassDeclaration(path) {
// Search in class methods
path.traverse(classMethods, { name: _.get(path.node, ['id', 'name']) });
},
},
post() {
fs.writeFileSync(OUTPUT_PATH, JSON.stringify(events, null, 2));
}
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment