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

Better parser error when using jsx #11499

Closed
hzoo opened this issue Apr 29, 2020 · 15 comments · Fixed by #11722
Closed

Better parser error when using jsx #11499

hzoo opened this issue Apr 29, 2020 · 15 comments · Fixed by #11722
Assignees
Labels
area: errors claimed good first issue i: enhancement outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: parser

Comments

@hzoo
Copy link
Member

hzoo commented Apr 29, 2020

Was checking #11478 and testing out syntax and noticed we don't error with the normal "use this plugin/preset" like we do for proposals with JSX itself. @nicolo-ribaudo mentioned it's probably since jsx is implemented as a normal plugin so we didn't have this.expectPlugin("recordAndTuple");

unknown: Unterminated regular expression (1:5)

> 1 | <a></a>
    |      ^
unknown: Support for the experimental syntax 'pipelineOperator' isn't currently enabled (1:3):

> 1 | a |> b
    |   ^

Add @babel/plugin-proposal-pipeline-operator (https://git.io/vb4SU) to the 'plugins' section of your Babel config to enable transformation.
@nicolo-ribaudo
Copy link
Member

This bug needs different steps in order to be fixed, but they can be done in the same PR.

  1. First, we should make @babel/parser throw a developer-friendly error.
    Consider these examples:

    require("@babel/parser").parse("<div></div>", {});
    require("@babel/parser").parse("a |> b", {});

    The first one throws SyntaxError: Unexpected token (1:0), while the second one throws a more actionable SyntaxError: This experimental syntax requires enabling the parser plugin: 'pipelineOperator' (1:2).
    Why this difference? If you search for the "pipelineOperator" string in packages/babel-parser/src, you'll see that (as @hzoo mentioned above) we are calling the this.expectPlugin("pipelineOperator") function when we find the "pipeline" (|>) operator.

    We can do something similar for JSX, but it's harder. The main problem is that checks for ECMAScript proposals (such as |>) are inlined in the parser code, while checks for JSX code are only enabled when the jsx plugin is enabled.

    However, we know that JSX elements are _atomic expressions (parsed by the parseExprAtom method) and that no other expression can start with <.
    That method contains a big switch statement, and (at the end) we throw this.unexpected() if we don't find any valid token. We could add a new case and, if the token is <, call this.expectPlugin("jsx").

    Here are a few possible tests:

    • When the jsx plugin is not enabled, this code should throw the "nice" error:
      <div /></div>
    • This is valid JS code, and it should never throw:
      "use strict"
      <div
    • When the typescript plugin is enabled, this code shouldn't throw because it's a type parameter:
      <div>() => {}
  2. Then, we should make @babel/core handle the parser error and suggest the correct @babel/... plugin/preset. You can add the syntax plugin and the react preset at packages/babel-core/src/parser/util/missing-plugin-helper.js.


If it is the first time that you contribute to Babel, follow these steps: (you need to have make and yarn available on your machine)

  1. Write a comment there to let other possible contributors know that you are working on this bug.
  2. Fork the repo
  3. Run git clone https://github.com/<YOUR_USERNAME>/babel.git && cd babel
  4. Run yarn && make bootstrap
  5. Wait ⏳
  6. Run make watch (or make build whenever you change a file)
  7. Add some tests: packages/babel-parser/test/fixtures/jsx/errors/_no-plugin, packages/babel-parser/test/fixtures/jsx/errors/_no-plugin-no-jsx and packages/babel-parser/test/fixtures/jsx/errors/_no-plugin-ts-type-param. You can see an example at packages/babel-parser/test/fixtures/experimental/_no-plugin/import-meta.
  8. Update the code!
  9. yarn jest babel-parser to run the tests
    • If some test outputs don't match but the new results are correct, you can delete the bad output.js files and run the tests again
    • If you prefer, you can run OVERWRITE=true yarn jest babel-parser and they will be automatically updated.
  10. If it is working, run make test to run all the tests
  11. Run git push and open a PR!

@karansapolia
Copy link
Contributor

I would like to take this up.

@existentialism
Copy link
Member

@karansapolia it's yours! let us know (here or on slack) if you have any questions!

@existentialism
Copy link
Member

@karansapolia friendly ping, are you still working on this? no worries if not!

@karansapolia
Copy link
Contributor

@existentialism so sorry, I have not been able to work on this yet. In case someone wants to pick this up, please feel free. I really want to start helping out with Babel, will try to chip in where I can next 🙂

@existentialism
Copy link
Member

@karansapolia no need to apologize at all!

@iosh
Copy link

iosh commented May 25, 2020

i want to try this.

@kaicataldo
Copy link
Member

Awesome! Please feel free to reach out if you have any questions.

@penguingovernor
Copy link
Contributor

Is this still available to pickup ? (:

@nicolo-ribaudo
Copy link
Member

There is a PR opened for this: #11629 (@HiMrHu I noticed that you haven't responded, to my review: are you still working on it?)

@iosh
Copy link

iosh commented Jun 15, 2020 via email

@nicolo-ribaudo
Copy link
Member

No problem, thanks for telling us!

@Yokubjon-J
Copy link
Contributor

Yokubjon-J commented Jun 21, 2020

Hello! Can I pick this issue up?

@nicolo-ribaudo
Copy link
Member

We are working on this at #11722 with @penguingovernor. I'm looking for another issue you could help with.

@Yokubjon-J
Copy link
Contributor

Yokubjon-J commented Jun 21, 2020

Please let me know that issue! I am so excited! I will try to help as much as I can!

JLHwung pushed a commit that referenced this issue Jun 22, 2020
* Add "<" parser tests

*  No {jsx,flow,typescript} plugin

* Type parameter

* Valid JS Code

* Add: better parser error when using jsx

Address #11499

* Add: babel parser test

Test parser with no plugins and when jsx is given with a js expression

* Add: no flow but with typescript test

* Add: type paramter test with no plugins (no flow)

* Add: unclosed jsx element test
@github-actions github-actions bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Sep 22, 2020
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: errors claimed good first issue i: enhancement outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: parser
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants