Babel AST transform drops Recast's `original` property
NickHeiner opened this issue · comments
Bug Report
Maybe you don't consider this a bug, but I thought I'd flag it anyway.
Current behavior
Recast (0.20.4
) works by attaching an original
property to AST nodes. babel.transformFromAst
drops that property, preventing Recast from working as expected.
This is demonstrated by the following script:
const babel = require('@babel/core');
const recast = require('recast');
const _ = require('lodash');
const filename = 'file.js';
const source = `
function f(
a,
b,
c
) {
return d;
}
`;
const babelOpts = {
filename,
ast: true
};
const parser = {
parse(source, opts) {
return babel.parse(source, {
...babelOpts,
..._.omit(
opts,
'jsx', 'loc', 'locations', 'range', 'comment', 'onComment', 'tolerant', 'ecmaVersion'
)
});
}
};
const ast = recast.parse(source, {parser});
const result = babel.transformFromAstSync(ast, source, babelOpts);
const printedFromRecastParse = recast.print(ast).code;
const printedFromBabelTransform = recast.print(result.ast).code;
console.log('printedFromRecastParse', printedFromRecastParse);
console.log();
console.log('printedFromBabelTransform', printedFromBabelTransform);
This produces:
printedFromRecastParse
function f(
a,
b,
c
) {
return d;
}
printedFromBabelTransform "use strict";
function f(a, b, c) {
return d;
}
Expected behavior
Program output:
printedFromRecastParse
"use strict";
function f(
a,
b,
c
) {
return d;
}
printedFromBabelTransform "use strict";
function f(
a,
b,
c
) {
return d;
}
Environment
System:
OS: macOS 11.2.1
Binaries:
Node: 12.14.0 - ~/.nvm/versions/node/v12.14.0/bin/node
Yarn: 1.22.5 - /usr/local/bin/yarn
npm: 6.13.4 - ~/.nvm/versions/node/v12.14.0/bin/npm
npmPackages:
@babel/core: 7.13.1 => 7.13.1
@babel/plugin-syntax-pipeline-operator: 7.12.13 => 7.12.13
@babel/plugin-transform-typescript: 7.13.0 => 7.13.0
@babel/preset-env: 7.11.5 => 7.11.5
@babel/preset-typescript: 7.10.4 => 7.10.4
babel-jest: 26.3.0 => 26.3.0
eslint: 7.9.0 => 7.9.0
jest: 26.4.2 => 26.4.2
- Monorepo: no
- How you are using Babel: Standalone
Possible Solution
This workaround addresses the issue, but it's a bit cumbersome. Here's the snippet above with the workaround applied:
const babel = require('@babel/core');
const recast = require('recast');
const _ = require('lodash');
const filename = 'file.js';
const source = `
function f(
a,
b,
c
) {
return d;
}
`;
const babelOpts = {
filename,
ast: true,
code: false
};
const parser = {
parse(source, opts) {
return babel.parse(source, {
...babelOpts,
..._.omit(
opts,
'jsx', 'loc', 'locations', 'range', 'comment', 'onComment', 'tolerant', 'ecmaVersion'
)
});
}
};
const ast = recast.parse(source, {parser});
const setAst = babel => ({
visitor: {
Program(path) {
path.replaceWith(ast.program);
}
}
});
const result = babel.transformSync('', {
...babelOpts,
plugins: [setAst]
});
const printedFromRecastParse = recast.print(ast).code;
const printedFromBabelTransform = recast.print(result.ast).code;
console.log('printedFromRecastParse', printedFromRecastParse);
console.log();
console.log('printedFromBabelTransform', printedFromBabelTransform);
Additional context
Hey @NickHeiner! We really appreciate you taking the time to report an issue. The collaborators on this project attempt to help as many people as possible, but we're a limited number of volunteers, so it's possible this won't be addressed swiftly.
If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack community that typically always has someone willing to help. You can sign-up here for an invite."
You can try passing cloneInputAst: false
to transformFromAst
's options.
That fixes it! Thanks.