0.3.1 • Published 5 years ago

restencil v0.3.1

Weekly downloads
3
License
MIT
Repository
github
Last release
5 years ago

restencil

Automatically generates React components for a component library created with stencil.js. No more worrying about whether props are arrays or objects, and no more cumbersome attachment of event listeners. Just use them like any other React component.

Example

Assume we have a web component with an html tag of my-formatted-button that:

  • Has an attribute called title, of type string
  • Has a property called values of type object
  • Fires a custom event called buttonClicked

Without restencil, quite a bit of setup is needed just to pass down some values:

const TestComponent = (props) => {
  // need a handle to the native DOM element
  const ref = React.useRef()

  React.useEffect(() => {
    // can't pass objects as attributes in the render phase
    ref.current.values = props.values
  }, [props])

  React.useEffect(() => {
    const element = ref.current
    const handleClick = () => console.log('button was clicked')
    // have to attach event listeners via DOM methods
    element.addEventListener('buttonClicked', handleClick)
    // and don't forget to remove the listener on unmount!
    return () => {
      element.removeEventListener('buttonClicked', handleClick)
    }
  }, [])

  return <my-formatted-button ref={ref} title={props.title} />
}

With restencil:

import { MyFormattedButton } from 'awesome-lib-react'

const RestencilTestComponent = (props) => {
  const handleClick = () => console.log('button was clicked')
  return (
    <MyFormattedButton
      title={props.title}
      options={props.options}
      onButtonClicked={handleClick}
    />
  )
}

Setup

All that is required for restencil project is a package.json. No source code, no additional config files. restencil takes care of everything. Assuming the stencil component library is called awesome-lib:

Create a new project with a package.json

mkdir awesome-lib-react
npm init -y
npm i awesome-lib
npm i -D restencil

Configure package.json

  • Add a source entry, which is the destination path for the generated source code file. This will be overwritten on each build.
  • Add one or more build targets. These can include commonjs, es module, and umd for unpkg.
    • main - commonjs module
    • module - es module
    • unpkg - umd module

Example package.json

{
  "name": "awesome-lib-react",
  "version": "1.0.0",
  "description": "React components for the awesome-lib component library",
  "source": "dist/src.js", // this source file will be generated by restencil on each build
  "main": "dist/awesome-lib-react.js", // desination for the compiled commonjs module
  "module": "dist/awesome-lib-react.mjs", // desination for the compiled es module
  "unpkg": "dist/awesome-lib-react.umd.js", // desination for the compiled umd module
  "files": [ "dist" ], // base dir of the compiled files above
  "scripts": {
    "build": "restencil -m awesome-lib" // build script, with '-m stencil-module-name'
  },
  "peerDependencies": {
    "awesome-lib": "1.2.3", // the stencil component module
    "react": "^16.8.0" // must be used with React 16.8.x
  },
  "devDependencies": {
    "awesome-lib": "1.2.3" // the stencil component module
    "restencil": "^0.2.0"
  }
}

Build

npm run build

Motivation

stencil.js creates web components that can be shared between different frameworks. Unfortunately, React doesn't have the best support for web components (see unsupported features). Working with them requires native DOM interactions, and that clashes somewhat with archetypal React patterns of allowing React to manage everything via the JSDOM.

This means that when using them, props passed to web components within JSX can only be primitives. Arrays, any type of object, or functions will be passed as their toString() text. In particular, this means that any props you want to pass that are objects or arrays have to be set on the DOM element directly, and any events you want to handle have to be attached via addEventListener (and also removed on unmount).


Future plans:

  • Generate package.json with an init script.
  • Automate checking for updates of the stencil library, and use lockstep versions with it