Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-export statements are omitted from output using @babel/plugin-transform-typescript@7.5.0 #10162

Closed
elliottsj opened this issue Jul 4, 2019 · 20 comments · Fixed by #10167 or #10174

Comments

@elliottsj
Copy link

elliottsj commented Jul 4, 2019

Bug Report

Current Behavior
Using @babel/plugin-transform-typescript@7.5.0 via @babel/preset-typescript@7.3.3, re-export statements are omitted from the transpiled output.

Repro:

$ npm install @babel/cli @babel/core @babel/preset-typescript
$ echo "export { bar } from './bar';" > script.ts
$ ./node_modules/.bin/babel --presets @babel/preset-typescript script.ts


$ # observe: the above output is empty

Note that separate import + export statements transpile properly:

$ echo "import { bar } from './bar'; export { bar };" > script.ts
$ ./node_modules/.bin/babel --presets @babel/preset-typescript script.ts
import { bar } from './bar';
export { bar };

$ # observe: the output is as expected

Input Code

export { bar } from './bar';

Expected behavior/code
The re-export statement should be included in the output.

Babel Configuration (.babelrc, package.json, cli command)

{
  "presets": ["@babel/preset-typescript"]
}

Environment

  • Babel version(s):

    $ npm ls --depth=1                                                                                                                                                                                                                                          (522ms)
    /Users/spencerelliott/Dev/temp
    ├─┬ @babel/cli@7.5.0
    │ ├── chokidar@2.1.6
    │ ├── commander@2.20.0
    │ ├── convert-source-map@1.6.0
    │ ├── fs-readdir-recursive@1.1.0
    │ ├── glob@7.1.4
    │ ├── lodash@4.17.11
    │ ├── mkdirp@0.5.1
    │ ├── output-file-sync@2.0.1
    │ ├── slash@2.0.0
    │ └── source-map@0.5.7
    ├─┬ @babel/core@7.5.0
    │ ├── @babel/code-frame@7.0.0
    │ ├── @babel/generator@7.5.0
    │ ├── @babel/helpers@7.5.0
    │ ├── @babel/parser@7.5.0
    │ ├── @babel/template@7.4.4
    │ ├── @babel/traverse@7.5.0
    │ ├── @babel/types@7.5.0
    │ ├── convert-source-map@1.6.0 deduped
    │ ├── debug@4.1.1 extraneous
    │ ├── json5@2.1.0
    │ ├── lodash@4.17.11 deduped
    │ ├── resolve@1.11.1
    │ ├── semver@5.7.0
    │ └── source-map@0.5.7 deduped
    └─┬ @babel/preset-typescript@7.3.3
      ├── @babel/helper-plugin-utils@7.0.0
      └── @babel/plugin-transform-typescript@7.5.0
    
  • Node/npm version: Node v10.15.0, npm 6.9.0

  • OS: macOS 10.14.5

  • Monorepo: no

  • How you are using Babel: see above

@babel-bot

This comment has been minimized.

Copy link
Collaborator

babel-bot commented Jul 4, 2019

Hey @elliottsj! 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.

@nicolo-ribaudo nicolo-ribaudo added this to the v7.5.1 milestone Jul 4, 2019
@nicolo-ribaudo nicolo-ribaudo pinned this issue Jul 4, 2019
@hzoo

This comment has been minimized.

Copy link
Member

hzoo commented Jul 4, 2019

Ah thanks for the report! I did want to confirm, is this only happening with the TS plugin?

edit: looking at https://github.com/babel/babel/releases/tag/v7.5.0 there's a few TS PRs. I'm thinking it's from #10034, so might not be too hard of a fix cc @Wolvereness? @airato

I would pin to the TS plugin to 7.4.5 for now, apologies!

@elliottsj

This comment has been minimized.

Copy link
Author

elliottsj commented Jul 4, 2019

Yes, I've only noticed this issue with the TS plugin. Pinned to 7.4.5 for now. Thanks!

@eyousefifar

This comment has been minimized.

Copy link

eyousefifar commented Jul 4, 2019

I'm having the same problem

@Turbo87

This comment has been minimized.

Copy link

Turbo87 commented Jul 4, 2019

I just stepped through this after running into the same issue and I can confirm that 8d492b1 is the issue. The only change to that part of the code since v7.4.5 was that particular commit.

@Wolvereness

This comment has been minimized.

Copy link
Contributor

Wolvereness commented Jul 4, 2019

Just to confirm, 2080042 and a6392bd do not have the issue?

@pixelass

This comment has been minimized.

Copy link

pixelass commented Jul 4, 2019

I noticed that all my default exports were missing.

export default "foo"

with 7.5.0

var _default = "foo";
;

with 7.4.5

const _default = "foo";
var _default2 = _default;
exports.default = _default2;
;

@Wolvereness related to a6392bd

@JLHwung

This comment has been minimized.

Copy link
Contributor

JLHwung commented Jul 4, 2019

@Wolvereness Hi I just figure out a quick fix of this issue and it works well on my cases. Are you also working on a fix? If so I would leave it as-is and stop here.

diff --git a/packages/babel-plugin-transform-typescript/src/index.js b/packages/babel-plugin-transform-typescript/src/index.js
index a768907a5..79ca00102 100644
--- a/packages/babel-plugin-transform-typescript/src/index.js
+++ b/packages/babel-plugin-transform-typescript/src/index.js
@@ -98,9 +98,10 @@ export default declare(
         ExportNamedDeclaration(path) {
           // remove export declaration if it's exporting only types
           if (
+            !path.node.source &&
             path.node.specifiers.length > 0 &&
             !path.node.specifiers.find(exportSpecifier =>
-              path.scope.hasOwnBinding(exportSpecifier.local.name),
+              path.scope.hasBinding(exportSpecifier.local.name),
             )
           ) {
             path.remove();
@@ -109,7 +110,10 @@ export default declare(
 
         ExportSpecifier(path) {
           // remove type exports
-          if (!path.scope.hasOwnBinding(path.node.local.name)) {
+          if (
+            !path.parent.source &&
+            !path.scope.hasBinding(path.node.local.name)
+          ) {
             path.remove();
           }
         },
@@ -118,7 +122,7 @@ export default declare(
           // remove whole declaration if it's exporting a TS type
           if (
             t.isIdentifier(path.node.declaration) &&
-            !path.scope.hasOwnBinding(path.node.declaration.name)
+            !path.scope.hasBinding(path.node.declaration.name)
           ) {
             path.remove();
           }
@Wolvereness

This comment has been minimized.

Copy link
Contributor

Wolvereness commented Jul 5, 2019

Edit: was told I may have messed up the tests - updated with reruns, and this is only babel-plugin-transform-typescript

bff79e1 (fix commit):

  • Input:

    export default "foo";

    Output:

    export default "foo";
  • Input:

    export { bar } from './bar';

    Output:

    export { bar } from './bar';
  • Input:

    export default "foo";
    export { bar } from './bar';

    Output:

    export default "foo";
    export { bar } from './bar';

bff79e1~1:

  • Input:

    export default "foo";

    Output:

    export default "foo";
  • Input:

    export { bar } from './bar';

    Output:

  • Input:

    export default "foo";
    export { bar } from './bar';

    Output:

    export default "foo";

8d492b1 (my rewrite commit):

  • Input:

    export default "foo";

    Output:

    export default "foo";
  • Input:

    export { bar } from './bar';

    Output:

  • Input:

    export default "foo";
    export { bar } from './bar';

    Output:

    export default "foo";

8d492b1~1:

  • Input:

    export default "foo";

    Output:

    export default "foo";
  • Input:

    export { bar } from './bar';

    Output:

    export { bar } from './bar';
  • Input:

    export default "foo";
    export { bar } from './bar';

    Output:

    export default "foo";
    export { bar } from './bar';

a6392bd:

  • Input:

    export default "foo";

    Output:

    export default "foo";
  • Input:

    export { bar } from './bar';

    Output:

    export { bar } from './bar';
  • Input:

    export default "foo";
    export { bar } from './bar';

    Output:

    export default "foo";
    export { bar } from './bar';

2080042 No change from parent:

  • Input:

    export default "foo";

    Output:

    export default "foo";
  • Input:

    export { bar } from './bar';

    Output:

    export { bar } from './bar';
  • Input:

    export default "foo";
    export { bar } from './bar';

    Output:

    export default "foo";
    export { bar } from './bar';
    

2080042~1

  • Input:

    export default "foo";

    Output:

    export default "foo";
  • Input:

    export { bar } from './bar';

    Output:

    export { bar } from './bar';
  • Input:

    export default "foo";
    export { bar } from './bar';

    Output:

    export default "foo";
    export { bar } from './bar';

@pixelass - Your issue is probably unrelated based on these tests.

@babel babel deleted a comment from shrinktofit Jul 5, 2019
Turbo87 added a commit to Turbo87/ember-cli-typescript that referenced this issue Jul 5, 2019
pointless annoying conventional commit messages restrictions....... 🤬

Restrict `@babel/plugin-transform-typescript` to v7.4.x

see babel/babel#10162
dfreeman added a commit to typed-ember/ember-cli-typescript that referenced this issue Jul 5, 2019
@qiqiboy

This comment has been minimized.

Copy link

qiqiboy commented Jul 6, 2019

This issue seems still exists in v7.5.1.

@JoshRobertson

This comment has been minimized.

Copy link

JoshRobertson commented Jul 6, 2019

In my case:
In 7.5.0 compilation was successful but would throw an error at runtime.
In 7.5.1 compilation fails with an export was not found error, which is the same error I had with 7.4.5. So I'm stuck on 7.4.4 still.

@nicolo-ribaudo nicolo-ribaudo reopened this Jul 6, 2019
@nicolo-ribaudo

This comment has been minimized.

Copy link
Member

nicolo-ribaudo commented Jul 6, 2019

@qiqiboy @JoshRobertson Can you share your code?

@JoshRobertson

This comment has been minimized.

@nicolo-ribaudo

This comment has been minimized.

Copy link
Member

nicolo-ribaudo commented Jul 6, 2019

@JoshRobertson Babel can't handle re-exports of TypeScript types, since we don't do cross-file analysis and by looking at this code:

export { Avatar, AvatarProps } from "./Avatar";

it's impossible to know that AvatarProps is a type.

Since usages of AvatarProps will be removed anyway, you can safely ignore the webpack warning: it tells you that something can't be exported, but it isn't being used anyway.

If you want to make that warning go away, you can "hint" Babel that AvatarProps is a type by using it as such:

export { Avatar } from "./Avatar";

import { AvatarProps as Props } from "./Avatar";
export type AvatarProps = Props;
@qiqiboy

This comment has been minimized.

Copy link

qiqiboy commented Jul 6, 2019

.babelrc

{
  "plugins": ["react-hot-loader/babel", "@babel/plugin-transform-typescript"]
}

Input:

export defualt 'Foo';

Output:

const _default = 'Foo';
; // what???

May this is related with react-hot-loader? I think it's because the updates from >=v7.5.0 make some third-party plugins incompatible.

@nicolo-ribaudo

This comment has been minimized.

Copy link
Member

nicolo-ribaudo commented Jul 7, 2019

Yes, it is a problem with react-hot-loader. A plugin is responsible of maintaining scope information up-to-date, and Babel 7.5.0 brought to the surface that bug in react-hot-loader/babel because it uses scope information to remove exports.
I'm surprised that this didn't come up before, since we use scope info in many other places.

Would you be willing to open a PR to that package (or open an issue)?
https://github.com/gaearon/react-hot-loader/blob/master/src/babel.dev.js#L118
insertBefore returns an array of ast paths, and that plugin should call path.scope.registerDeclaration(resultOfInsertBefore[0])

@theKashey

This comment has been minimized.

Copy link

theKashey commented Jul 7, 2019

So that stuff was there for years, and everybody was just lucky :)

@theKashey

This comment has been minimized.

Copy link

theKashey commented Jul 7, 2019

If someone could verify gaearon/react-hot-loader#1293 with a patch @nicolo-ribaudo proposed - I'll issue a new version of React-Hot-Loader.
I was unable to find documentation for registerDeclaration and have no tests previously red, so you are the ones, who could say "👍"

@sciyoshi

This comment has been minimized.

Copy link

sciyoshi commented Jul 7, 2019

Seems to be fixed for me by updating react-hot-loader to 4.12.5 with gaearon/react-hot-loader#1293 Thank you @theKashey @nicolo-ribaudo!

@nicolo-ribaudo

This comment has been minimized.

Copy link
Member

nicolo-ribaudo commented Jul 8, 2019

We just released Babel 7.5.2. Please check that in your lockfile it contains v7.5.2 of @babel/plugin-transform-typescript!

@nicolo-ribaudo nicolo-ribaudo unpinned this issue Jul 8, 2019
u3u added a commit to u3u/vue-hooks that referenced this issue Jul 17, 2019
@lock lock bot added the outdated label Oct 7, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
You can’t perform that action at this time.