Git Product home page Git Product logo

react-ast's Introduction

react-ast

npm GitHub stars

render abstract syntax trees using react

Please ★ this repo if you found it useful ★ ★ ★

Abstract syntax trees are difficult to work with by nature. This is a react renderer that makes interacting with abstract syntax trees and rendering code a breeze.

React AST is the ultimate meta programming tool that uses react to render abstract syntax trees. It can be used to build powerful unopinionated code generators and babel plugins that are easy to read and can scale without creating a rats nest of unreadable code.

You can read a post I wrote about this project at the link below.

Render Abstract Syntax Trees with React

Built by BitSpur

BitSpur offers premium Node and React development and support services. Get in touch at bitspur.com.

Features

  • works with babel ast
  • supports typescript

Installation

npm install --save react-ast

Dependencies

Usage

Render Code

import React, { FC } from "react";
import {
  Export,
  Expression,
  Function,
  Identifier,
  Import,
  Interface,
  JSX,
  ReactNode,
  Return,
  TypeAnnotation,
  TypeReference,
  Var,
  VarKind,
} from "react-ast";

const code = await render(
  <>
    <Import default="React" imports={["FC"]} from="react" />
    <Export>
      <Interface name="HelloProps" />
    </Export>
    <Var kind={VarKind.Const} typeAnnotation="FC<HelloProps>" name="Hello">
      <Function
        arrow
        params={[
          <Identifier
            typeAnnotation={
              <TypeAnnotation>
                <TypeReference name="HelloProps" />
              </TypeAnnotation>
            }
          >
            props
          </Identifier>,
        ]}
      >
        <Return>
          <JSX />
        </Return>
      </Function>
    </Var>
    <Expression properties="Hello.defaultProps">{{}}</Expression>
    <Export default>
      <Identifier>Hello</Identifier>
    </Export>
  </>
);

console.log(code);

The rendered code

import React, { FC } from "react";
export interface HelloProps {}

const Hello: FC<HelloProps> = (props: HelloProps) => {
  return <></>;
};

Hello.defaultProps = {};
export default Hello;

Render AST

Sometimes you might want to render the ast instead of rendering the code.

import React from "react";
import { ClassDeclaration, renderAst } from "react-ast";

const ast = renderAst(<Class name="Hello" />);

console.log(ast);

The rendered AST

{ type: 'File',
  program:
   { type: 'Program',
     body: [ [Object] ],
     directives: [],
     sourceType: 'script',
     interpreter: null },
  comments: [],
  tokens: [] }

Support

Submit an issue

Development

You can validate the AST at astexplorer.net with the following settings.

Language ParserSettings Transform
JavaScript babylon7 babelv7

Enabled the following babylon7 plugins

  • jsx
  • typescript
  • asyncGenerators
  • classProperties
  • decorators
  • doExpressions
  • dynamicImport
  • functionBind
  • functionSent
  • numericSeparator
  • objectRestSpread
  • optionalCatchBinding
  • optionalChaining

Contributing

Review the guidelines for contributing

License

Apache-2.0 License

Clay Risser © 2019

Changelog

Review the changelog

Credits

Support on Liberapay

A ridiculous amount of coffee ☕ ☕ ☕ was consumed in the process of building this project.

Add some fuel if you'd like to keep me going!

Liberapay receiving Liberapay patrons

react-ast's People

Contributors

clayrisser avatar dharmendraboddeda avatar ganarepository avatar lavanya881 avatar phani2525 avatar rajak312 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-ast's Issues

Async Functions

Not for lack of trying, but please help me understand how to declare async functions and use the await keyword.

ps.
Love this project, helping me get my head around AST

Running in browser

Is there a way to run this library in the browser?
Made quick example codesandbox, but throws this error:
[["|>"],["??"],["||"],["&&"],["|"],["^"],["&"],["==","===","!=","!=="],["<",">","<=",">=","in","instanceof"],[">>","<<",">>>"],["+","-"],["*","/","%"],["**"]].entries is not a function or its return value is not iterable

Add an example to the Readme

Hi,

The readme would really benefit from a visual example, especially for a visualization library. Otherwise, it's hard to evaluate the quality of the library:

  • If the visual is bad, the library is useless,
  • If the visual is good, it makes me want to use the library!

How to render literals inside an expession?

There is no Literal component, which I expected from that library.

Tried to use Smart component:

<CallExpression
    name="fn"
    arguments={
        <Smart code="'a'"/>
    }/>

that gave totally unexpected output for me: fn('a';);

Starting point for AST transformation

Are there any starter kit or something to play with the generated AST? I'd thought that passing AST JSON through JMESPath will help in quicker code conversion. But, it looks complex than than.

IOW, are there any best practices for the AST transformation or modification?

Unpredictable return statement

      <FunctionDeclaration
        name="add"
        params={[<Param key="a">a</Param>, <Param key="b">b</Param>]}
        returnStatement="result"
      >
        <Code>const result=a+b</Code>
      </FunctionDeclaration>

The jsx above throws the following error

No parser and no filepath given, using 'babel' the parser now but this will throw an error in the future. Please specify a parser or a filepath so one can be inferred.
SyntaxError: Unexpected token (6:10)
  4 | 
  5 | function add(a, b) {
> 6 |   return return 'result';;
    |          ^
  7 |   const result = a + b;
  8 | }
    at e (~/Projects/react-gtk/node_modules/.pnpm/registry.npmjs.org/prettier/1.19.1/node_modules/prettier/parser-babylon.js:1:282)
    at Object.parse (~/Projects/react-gtk/node_modules/.pnpm/registry.npmjs.org/prettier/1.19.1/node_modules/prettier/parser-babylon.js:1:262260)
    at Object.parse (~/Projects/react-gtk/node_modules/.pnpm/registry.npmjs.org/prettier/1.19.1/node_modules/prettier/index.js:9739:19)
    at coreFormat (~/Projects/react-gtk/node_modules/.pnpm/registry.npmjs.org/prettier/1.19.1/node_modules/prettier/index.js:13252:23)
    at format (~/Projects/react-gtk/node_modules/.pnpm/registry.npmjs.org/prettier/1.19.1/node_modules/prettier/index.js:13510:73)
    at formatWithCursor (~/Projects/react-gtk/node_modules/.pnpm/registry.npmjs.org/prettier/1.19.1/node_modules/prettier/index.js:13526:12)
    at ~/Projects/react-gtk/node_modules/.pnpm/registry.npmjs.org/prettier/1.19.1/node_modules/prettier/index.js:44207:15
    at Object.format (~/Projects/react-gtk/node_modules/.pnpm/registry.npmjs.org/prettier/1.19.1/node_modules/prettier/index.js:44226:12)
    at render (~/Projects/react-gtk/node_modules/.pnpm/registry.npmjs.org/react-ast/0.1.26/node_modules/react-ast/src/render.ts:45:21)
    at ~/Projects/react-gtk/packages/generate/src/actions/generate.tsx:14:16
Makefile:102: recipe for target 'start' failed
make: *** [start] Error 1

Optional parameters

I want to generate this code. notice the optional method paramter.

export class Client {
  constructor(axiosInstance?: AxiosInstance) {
  }
}

This is my tsx:

<Class named="Client">
  <ClassMethod name="constructor" params={[
    <Identifier typeAnnotation="AxiosInstance">
      axiosInstance
    </Identifier>
  ]}>
  </ClassMethod>
</Class>

This code was generated:

class Client {
  constructor(axiosInstance: AxiosInstance) {
  }
}

How do I generate optional method parameters?

It would be great if there were some kinds of docs or more examples on how to build common js/ts patterns.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.