babel / babel/babel

[Bug]: Bindings from a removed path and `@babel/plugin-transform-function-name`

Open
#14,818 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
44k
Forks
6k
Avg merge
5d 15h
Merged PRs (30d)
23

Description

### 💻

- [ ] Would you like to work on a fix?

### How are you using Babel?

@babel/cli

### Input code

```js
import foo from 'bar';
const obj = {
foo: function() { return foo(); },
};
```

### Configuration file name

babel.config.mjs

### Configuration

```js
export default {
plugins: [
() => ({
visitor: {
ImportDeclaration(path) {
path.remove();
},
}
}),
'@babel/plugin-transform-function-name',
]
};
```

### Current and expected behavior

The current output is as follows:
```js
const obj = {
foo: function foo() {
return foo();
}
};
```
which recurses infinitely. Without the import statement, the output is as follows:
```js
const obj = {
foo: function (_foo) {
function foo() {
return _foo.apply(this, arguments);
}

foo.toString = function () {
return _foo.toString();
};

return foo;
}(function () {
return foo();
})
};
```

### Environment

- Babel v7.18.10
- Node v16.16.0
- npm 8.15.1

### Possible solution

I'm actually not sure whether this is a bug or the intended behavior. The problem is that removing the path removes the binding but doesn't add a global in its place, which trips up `@babel/plugin-transform-function-name`. I can fix this in my plugin by extending it as follows:
```js
() => ({
visitor: {
ImportDeclaration(path) {
path.node.specifiers?.forEach(specifier => {
const name = specifier.local.name;
if (!path.scope.hasGlobal(name)) path.scope.addGlobal(t.identifier(name));
});
path.remove();
},
}
}),
```
This works just fine, but I wanted to file this in case this is *not* the intended behavior for babel.

### Additional context

The reason I'm doing this is because our project isn't ready for any kind of module support, but I still want on-hover information in VSCode. By adding import statements I get the on-hover information, and by stripping them out (and setting the sourceType to `unambiguous`) they don't affect the output. The full plugin does a bit more than the simplified version above.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.