-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
74 lines (64 loc) · 1.65 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
const babel = require('@babel/core');
const recast = require('recast');
const _ = require('lodash');
const getBabelOpts = (plugins = []) => ({
filename: 'my-file-name.js',
plugins,
ast: true
});
const parser = {
parse(source, opts) {
const babelOpts = {
...getBabelOpts(),
// There are options that are recognized by recast but not babel. Babel errors when they're passed. To avoid
// this, we'll omit them.
..._.omit(
opts,
'jsx', 'loc', 'locations', 'range', 'comment', 'onComment', 'tolerant', 'ecmaVersion'
),
/**
* We must have babel emit tokens. Otherwise, recast will use esprima to tokenize, which won't have the
* user-provided babel config.
*
* https://github.com/benjamn/recast/issues/834
*/
parserOpts: {
tokens: true
}
};
return babel.parse(source, babelOpts);
}
};
const fileContents = `
jest.mock('./my-module', () => () => ({
mockedFn: jest.fn()
}));
`
const ast = recast.parse(fileContents, {parser});
const setAst = () => ({
visitor: {
Program(path) {
path.replaceWith(ast.program);
}
}
});
const plugin = ({ types: t }) => ({
visitor: {
ArrowFunctionExpression(astPath) {
const getWrappedValue = (originalValue) =>
t.callExpression(t.identifier("wrapped"), [
originalValue
]);
const bodyPath = astPath.get("body");
bodyPath.replaceWith(getWrappedValue(bodyPath.node));
astPath.skip();
}
}
});
const result = babel.transformSync('', getBabelOpts([setAst, plugin]));
console.log(`
Babel result
${result.code}
Recast result
${recast.print(result.ast)}
`)