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

Plugins: single file plugin format (like JSX but for plugins) #119

Open
hzoo opened this issue Jun 4, 2020 · 2 comments
Open

Plugins: single file plugin format (like JSX but for plugins) #119

hzoo opened this issue Jun 4, 2020 · 2 comments

Comments

@hzoo
Copy link
Member

hzoo commented Jun 4, 2020

Just another idea I had for making it easier to create new syntax (not necessarily for production or standardization but to test out ideas).

Currently, the only thing you can do now in transform plugin itself is modify existing AST/syntax.

export function customPlugin() {
  return {
    visitor: {
      OptionalChaining() {}
    }
}

In order to add new syntax, you need to modify the parser (we don't allow plugins on purpose but I kinda want to re-think that but in a way that doesn't ruin the ecosystem, which is I suppose why the parser is "bundled" now).

Currently you can pass overrides for the parser/generator if you want fork the parser or use recast/prettier to do codemods.

return {
    parserOverride: parse,
    generatorOverride(ast, options) {
      return {
        code: prettier.format(
          generate(ast).code,
          config
        ),
      }
    },
  }

Even in a PR to babel (ex: tc39/proposal-private-fields-in-in
, babel/babel#11372) you have to change a lot of different files (a good thing as it's independent), but maybe it's possible to keep it in one place? I know this wouldn't work if you are modifying different nodes, but just thinking out loud here.

So it would be interesting if we supported adding your own "types", "printer nodes" in the plugin itself?

export function customPlugin() {
  return {
    parser: { // @babel/parser
      parserOverrideFunction() { // parse a?.b }
    },
    visitor, // same as usual
    generator: { // @babel/generator
      OptionalChaining() { // print a?.b }
    },
    types: { // for @babel/types
      OptionalChaining: {
        builder: ["operator", "left", "right"],
        visitor: ["left", "right"],
        aliases: ["Binary", "Expression"]
      }
    }
  };
}
@ljharb
Copy link
Member

ljharb commented Jun 4, 2020

I think any change that makes it easier to add new syntax locally would likely make it easier to add in a published package, thus "ruining the ecosystem" :-/

@hzoo
Copy link
Member Author

hzoo commented Jun 4, 2020

It's already pretty simple but we don't document it well. I would like more people to understand ASTs/compilers/etc so it comes with the territory I guess. My ideal is allowing people to write the whole thing in the repl/whatever we call it. Doesn't mean you can publish but you can share a link for people to test it out and get feedback. Just thinking how to balance it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants