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

Handling babylon parsing errors in a better way #6961

Merged
merged 4 commits into from Dec 18, 2017

Conversation

maazadeeb
Copy link
Contributor

@maazadeeb maazadeeb commented Dec 3, 2017

Q                       A
Fixed Issues? Fixes #6205
Patch: Bug Fix? No
Major: Breaking Change? No
Minor: New Feature? No
Tests Added + Pass? Yes
Documentation PR No
Any Dependency Changes? No
License MIT

Introduces a better way to handle missing plugin errors from babylon, in babel. Previously, the errors used to be directly displayed, as is, from babylon. This was not so friendly as the error used to have only an internal name of the plugin required.

With this change, there is a mapping done between internal plugin names to the external plugin names, where required. There are 2 possible messages that are generated

  1. When a plugin has both syntax and transform plugins:

Support for the experimental syntax [babylon plugin name] isn't currently enabled ([loc]):

[code frame]

Add [npm package name] ([url]) to the 'plugins' section of your Babel config to enable transformation.

  1. When a plugin has only a syntax plugin:

Support for the experimental syntax [babylon plugin name] isn't currently enabled ([loc]):

[code frame]

Add [npm package name] ([url]) to the 'plugins' section of your Babel config to enable parsing.

All the URLs are shortened using git.io, and point directly to the repository field of the plugin's package.json.

@maazadeeb
Copy link
Contributor Author

I need some feedback on writing tests for this. They might probably be fixtures which expect an error to be thrown. If the messages that I have chosen to output are approved, then I'll add tests. As a change in the messages will result in changing the tests.

Also, open to feedback if I should write multiple fixtures or just some sort of unit tests for the new file added.

@babel-bot
Copy link
Collaborator

babel-bot commented Dec 3, 2017

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/6213/

Copy link
Member

@nicolo-ribaudo nicolo-ribaudo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I left a few comments about the error messages; the implementation looks good to me.

You can add the tests in babel-core/test/fixtures. One for each kind of message is enough.

@@ -102,7 +103,8 @@ function parser(pluginPasses, options, code) {
},
},
options,
);
) +
`\n${generateHelpMessage(err.missingPlugin)}`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can \n be added only if generateHelpMessage doesn't return ""?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also can we rename generateHelpMessage to something more descriptive like generateMissingPluginMessage?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll incorporate both these changes

if (syntaxPlugin) {
if (transformPlugin) {
helpMessage =
`Use the ${syntaxPlugin} plugin to enable parsing. ` +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about adding This experimental syntax isn't enabled by default as an "inroduction" to the error message?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we even need a different message in the case where there's only a syntax plugin and not a transform (just dynamic-import)? I feel like we can just simplify this down to something like:

Support for this experimental syntax isn't currently enabled. Add <insert syntax plugin here> to the plugins section of your Babel config.

Support for this experimental syntax isn't currently enabled. Add either <insert transform plugin here> or <insert syntax plugin> (if you only need parsing support) to the plugins section of your Babel config.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also add a link to the website because we can explain the user how to install it, and if a transformation is needed. What do you think? That also means we should have doc about all the proposals (or issues if not official)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll use @existentialism 's messages. I think they take care of @nicolo-ribaudo 's suggestion as well.
@xtuc like you mentioned, not all the plugins have docs on the website. Would it be better to point to the particular package's README instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maaz93 Yes it is. Since it's a link it's generic enough, we can change it later if needed.

Copy link
Contributor Author

@maazadeeb maazadeeb Dec 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xtuc Let me clear my understanding. So, if I was suggesting a message for missing asyncGenerators plugin, I would have to add https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-async-generators and https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-async-generator-functions in the message? Or I just need to suggest https://babeljs.io/docs/plugins/ for more info?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can use the READMEs for now, I'm not sure that we have the complete doc on the website tho.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While trying to add this, I realised that the message will get very long with links in it. I thought I'll just suggest

You can find more details about every plugin at https://github.com/babel/babel/tree/master/packages

Will this be enough?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could even use git.io and make it shorter

Copy link
Contributor Author

@maazadeeb maazadeeb Dec 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolo-ribaudo That was a great suggestion! I wrote a quick dirty script to use gitio in a loop and generate short URLs. The map looks something like this now

asyncGenerators: {
  syntax: {
    name: "@babel/plugin-syntax-async-generators",
    url: "https://git.io/vb4SY",
  },
  transform: {
    name: "@babel/plugin-proposal-async-generator-functions",
    url: "https://git.io/vb4yp",
  },
}

With this, the message would look like

Support for this experimental syntax isn't currently enabled. Add either <insert transform plugin here>(insert URL) or <insert syntax plugin>(insert URL) (if you only need parsing support) to the plugins section of your Babel config.

Is this more clear?

}
} else if (issueLink) {
helpMessage =
`This syntax is not supported yet. ` +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This experimental syntax...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And it's -> its

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It this used? That means we are adding early errors in the parser at a very early stage of the proposal, we don't do that currently?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add the changes suggested in the first two comments. @xtuc I guess so. I'm not well versed with the parser yet, so I don't have a concrete answer. I just picked up all the plugins from the babylon README.

if (transformPlugin) {
helpMessage =
`Use the ${syntaxPlugin} plugin to enable parsing. ` +
`Use the ${transformPlugin} plugin to enable transformation.` +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we suggest the transform plugin before the syntax plugin, since it is the most important one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

@nicolo-ribaudo nicolo-ribaudo added the PR: Polish 💅 A type of pull request used for our changelog categories label Dec 3, 2017
@xtuc
Copy link
Member

xtuc commented Dec 3, 2017

Nice first contribution @maaz93, it's so much clearer!

@@ -103,6 +104,10 @@ function parser(pluginPasses, options, code) {
},
options,
);
const missingPluginMessage = generateMissingPluginMessage(missingPlugin);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just thinking aloud, but looking at this again... right now it outputs something like:

This experimental syntax requires enabling the parser plugin: 'asyncGenerators' (1:14)
> 1 | async function* agf() {
      |                         ^
   2 | await 1;
   3 | yield 2;
   4 | }
Support for this experimental syntax isn't currently enabled. Add either @babel/plugin-syntax-async-generators (https://git.io/vb4SY) or @babel/plugin-syntax-async-generators (https://git.io/vb4SY) (if you only need parsing support) to the 'plugins' section of your Babel config.

Should we just omit the error from Babylon if missingPlugin and maybe just do:

Support for the experimental syntax 'asyncGenerators' isn't currently enabled (1:14)

> 1 | async function* agf() {
      |                         ^
   2 | await 1;
   3 | yield 2;
   4 | }

Add either @babel/plugin-syntax-async-generators (https://git.io/vb4SY) or @babel/plugin-syntax-async-generators (https://git.io/vb4SY) (if you only need parsing support) to the 'plugins' section of your Babel config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, I thought about this. But I didn't know how it can be improved. The current message repeats the fact that there is some experimental plugin missing, twice.

I like the new message proposal. It's more meaningful and less repetitive. Can I go ahead and make this change?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original purpose for making the issue is that yes we would remove the original message and output the new one. I would only add the syntax part for things that we don't have a default transform for, otherwise it should only say the plugin. This is because the use case for babel is the transform not the syntax (because then you would be using babylon by itself)

Copy link
Contributor Author

@maazadeeb maazadeeb Dec 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hzoo @existentialism Then, the apt message would be

Support for the experimental syntax 'asyncGenerators' isn't currently enabled (1:14)
<codeFrame>
Add @babel/plugin-proposal-async-generator-functions (https://git.io/vb4yp) to the 'plugins' section of your Babel config to enable transformation.

And, in the case where there is only a syntax plugin available

Support for the experimental syntax 'dynamicImport' isn't currently enabled (1:14)
<codeFrame>
Add @babel/plugin-syntax-dynamic-import (https://git.io/vb4Sv) to the 'plugins' section of your Babel config to enable parsing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I'm fine with that. Note, can we add line breaks around the codeframe:

Support for the experimental syntax [babylon plugin name] isn't currently enabled ([loc]):

[code frame]

Add [npm package name] ([url]) to the 'plugins' section of your Babel config to enable [parsing|transformation].

@nicolo-ribaudo
Copy link
Member

(NOTE) If #7008 gets merged before this PR, it should be added to the plugins list.

@maazadeeb
Copy link
Contributor Author

@nicolo-ribaudo I'll do that.

I just had another thought. Do you think it makes sense to write a test case which iterates through all the plugins in the map and makes sure that only syntax or/and transform keys are present per plugin and the url matches https://git.io/* ? I feel this will ensure strict rules on the structure of the map. Only side effect of this would be that I'll have to export the map. Let me know if that would be a good addition to this PR. 😄

Copy link
Member

@existentialism existentialism left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Seems like adding the tests you mention are slightly overkill, though we can consider stricter enforcement through flow types.

type Plugin = {
  name: string,
  url: string,
};

type PluginNameMap = {
  [name: string]: {
    syntax: Plugin,
    transform?: Plugin,
  },
};

Regardless, I don't consider that a blocker to landing this.

@hzoo hzoo merged commit 17b37b5 into babel:master Dec 18, 2017
@hzoo
Copy link
Member

hzoo commented Dec 18, 2017

Nice work @maaz93, this will help a lot! Looking forward to how we can improve this as well

@maazadeeb
Copy link
Contributor Author

@hzoo Thanks! I would love to improve it based on any suggestions or help anyone who's looking to make any improvements, if needed. 😄

@maazadeeb maazadeeb deleted the better-errors branch January 14, 2018 16:50
@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Oct 5, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 5, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: parser PR: Polish 💅 A type of pull request used for our changelog categories
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Handle syntax errors from babylon that need a plugin
6 participants