Giter VIP home page Giter VIP logo

jsx-runtime's Introduction

@itsjavi/jsx-runtime

Extremely lightweight JSX runtime (~ 2 KiB when minified) compatible with TypeScript and JavaScript, to be used together with Bable automatic JSX runtime.

Why another React clone?

Compared to other solutions like Preact and Inferno, which are an alternative to all React features, this project just focuses on minimalism: a simplistic JSX runtime with basic features to build things like standalone widgets that require some JavaScript like: form controls, context menus, modal forms, pop ups, color pickers, etc.

The idea is that the final build of your widget will include the jsx-runtime, so it will be standalone and others won't need React or this runtime in order to use it. microbundle is a nice zero-configuration bundler for projects like that.

Designed Features

  • JSX Runtime written in TypeScript to ensure 100% compatibility
  • Minimal size (~2KiB minified), perfect for standalone UI packages
  • Can be used in the browser, node or electron (multi target builds)
  • Class components and props support
  • Function components support (experimental)
  • props.children support (experimental)
  • Simple onWillMount and onDidMount component life-cycle methods (experimental)
  • Auto-join (with space) of array of strings in the className attribute
  • Auto-bind of functions to the component's "this", e.g. on <div onClick={this.doSomething} />

Install

npm i -D @itsjavi/jsx-runtime

or

yarn add -D @itsjavi/jsx-runtime

Configuration

The most important part is to configure @babel/plugin-transform-react-jsx correctly, which will be the one detecting this library and using it to transform JSX / TSX to JS.

These example configurations showcase a setup with Babel, Webpack, TypeScript and CSS loaders.

Example babel.config.js:

{
  "presets": [
    "@babel/preset-env",
    [
      "@babel/preset-typescript",
      {
        "isJSX": true,
        "allExtensions": true,
        "jsxPragma": "jsx",
        "jsxPragmaFrag": "'jsx.Fragment'"
      }
    ]
  ],
  "plugins": [
    [
      "@babel/plugin-transform-react-jsx",
      {
        "throwIfNamespace": false,
        "runtime": "automatic",
        "importSource": "@itsjavi"
      }
    ]
  ],
  "comments": false
}

Example tsconfig.json:

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "noImplicitAny": true,
    "module": "ESNext",
    "target": "ESNext",
    "lib": [
      "ESNext",
      "DOM",
      "DOM.Iterable"
    ],
    "allowJs": true,
    "jsx": "preserve",
    "esModuleInterop": true,
    "strict": true,
    "sourceMap": true,
    "moduleResolution": "Node" // important to find the proper JSX types on type check when writing TSX
  },
  "files": [
    "src/index.ts"
  ],
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx"
  ]
}

Example webpack.config.js (you can use other bundlers too):

// Generated using webpack-cli http://github.com/webpack-cli
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

const baseConfig = {
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: ['/node_modules/'],
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.(ts|tsx)$/,
        exclude: ['/node_modules/'],
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-typescript']
          }
        }
      },
      {
        test: /\.(js|css)$/,
        enforce: 'pre',
        use: ['source-map-loader']
      },
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader', 'postcss-loader']
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif)$/,
        type: 'asset'
      }

      // Add your rules for custom modules here
      // Learn more about loaders from https://webpack.js.org/loaders/
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js', '.jsx']
  }
}

module.exports = [
  Object.assign({}, baseConfig, {
    name: 'my-component',
    devtool: 'inline-source-map',
    entry: ['./src/index.ts'],
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: 'my-component.js'
    }
  })
]

Example package.json:

{
  "name": "my-component",
  "amdName": "myComponent",
  "private": true,
  "version": "0.0.1",
  "description": "My Component",
  "author": "",
  "license": "ISC",
  "main": "./dist/my-component.js",
  "module": "./dist/my-component.module.js",
  "esmodule": "./dist/my-component.modern.js",
  "exports": "./dist/my-component.modern.js",
  "umd:main": "./dist/my-component.umd.js",
  "source": "src/index.ts",
  "types": "src/index.d.ts",
  "scripts": {
    "test": "run-s test:*",
    "test:typecheck": "tsc --noEmit",
    "build": "run-s clean build:*",
    "build:webpack": "webpack --mode=development && webpack --mode=production",
    "build:tsc": "tsc --declaration --emitDeclarationOnly",
    "watch": "webpack --watch",
    "serve": "npm run clean && webpack serve",
    "clean": "rm -rf ./dist/*"
  },
  "devDependencies": {
    "@babel/cli": "^7.13.16",
    "@babel/core": "^7.13.16",
    "@babel/plugin-transform-react-jsx": "^7.13.12",
    "@babel/preset-env": "^7.13.15",
    "@babel/preset-typescript": "^7.13.0",
    "@itsjavi/jsx-runtime": "github:itsjavi/jsx-runtime",
    "autoprefixer": "^10.2.5",
    "babel-loader": "^8.2.2",
    "css-loader": "^5.2.4",
    "html-webpack-plugin": "^5.3.1",
    "npm-run-all": "^4.1.5",
    "postcss": "^8.2.12",
    "postcss-loader": "^5.2.0",
    "source-map-loader": "^2.0.1",
    "style-loader": "^2.0.0",
    "typescript": "^4.2.4",
    "webpack": "^5.35.1",
    "webpack-cli": "^4.6.0",
    "webpack-dev-server": "^3.11.2"
  },
  "browserslist": [
    "defaults",
    "not IE 11"
  ]
}

Usage

Examples:

import { Component } from '@itsjavi/jsx-runtime'

function fnComp ({ a, b, children }: { a: number, b: number, children: any }): JSX.Element {
  return <div>hey{a}, {b} <br/>{children}</div>
}

class PointInfo extends Component {
  constructor (public props: { x: number, y: number }) {
    super(props);
  }

  onClickFn (e: Event) {
    console.log(this, e, "I am a sub button")
  }

  render () {
    const { x, y } = this.props
    return (<div>{x} + {y}
      <button onClick={this.onClickFn}>Sub button</button>
    </div>)
  }
}

export default class Point extends Component {
  private ratio: number

  constructor (public props: { x: number, y: number }) {
    super(props)
    this.ratio = this.props.y / this.props.y
    this.onClickFn.bind(this)
  }


  onClickFn (e: Event) {
    console.log(this, e, e.target)
  }

  render () {
    const { x, y } = this.props

    return <div id="demo" className={['xx', 'yx']}>
      <p>
        Lorem
        <b>
          ipsum
          <i>dolor</i>
        </b>
      </p>
      <div>sit</div>
      <hr/>
      <>
        amet
      </>
      <fnComp className="test-class">hello world</fnComp>
      <PointInfo x={x} y={y}/>
      <button onClick={this.onClickFn}>Click me</button>
    </div>
  }
}

jsx-runtime's People

Contributors

itsjavi avatar

Watchers

 avatar

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.