Giter Club home page Giter Club logo

mitosis's Introduction

Write components once, compile to every framework

Try our interactive fiddle

code style: prettier PRs Welcome License Types

PS: We are actively looking for folks interested in becoming contributors to Mitosis. If interested, look at our list of good first issues or reach out on our Discord

Table of contents

Quick Start

To create a new Mitosis project from scratch, run the following create command:

npm create @builder.io/mitosis@latest

It will prompt you for a project name, and create a new directory with a basic monorepo project structure that includes:

  • npm workspaces
  • multiple generated outputs, along with build steps for each
  • multiple test servers that import the outputs for convenient debugging/testing

Once completed, make sure to read the README.md generated in your new project. It will explain the structure of your project, and provide a walkthrough on how to build/test your components.

Manual Setup

If you would like to install Mitosis manually, you can do so with the following steps below. These generally follow the same steps as the create command.

Note on Monorepo structure

Given that Mitosis generates code for multiple frameworks, it is highly recommend to treat each output as its own npm package for building/publishing purposes. This means that you will most likely need a monorepo solution (such as npm/pnpm/yarn workspaces, or Nx, or Turborepo). While we provide this out-of-the-box in the create command, we will leave it up to the user to implement it however they see fit in the Manual setup guide.

Installation

First, in a new npm project, install the Mitosis CLI and the Mitosis packages:

npm install @builder.io/mitosis-cli @builder.io/mitosis

Setup mitosis.config.js

Then, create a mitosis.config.js file in the root of your project, and add the following configuration:

/** @type {import('@builder.io/mitosis').MitosisConfig} */
module.exports = {
  files: 'src/**',
  targets: ['svelte', 'react', 'qwik', 'vue'], //define your desired outputs here
};

Check our configuration docs for how to setup the Mitosis config file.

Setup TypeScript

To setup TypeScript, add the following to your tsconfig.json:

// tsconfig.json
{
  "compilerOptions": {
    "jsx": "preserve",
    "jsxImportSource": "@builder.io/mitosis"
  }
}

Create a Component

Now, create a MyComponent.lite.tsx file in the src/components directory:

// src/components/MyComponent.lite.tsx
import { useStore } from '@builder.io/mitosis';

type Props = {
  message: string;
};

export default function MyBasicComponent(props: Props) {
  const state = useStore({
    name: 'Foo',
  });

  return (
    <div>
      {props.message || 'Hello'} {state.name}! I can run in React, Vue, Solid, Svelte, Qwik
      andeverything else!
    </div>
  );
}

For a deeper look at the Mitosis JSX syntax, check out our Component docs and overall Mitosis Documentation.

Build

npm exec mitosis build

๐ŸŽ‰ You should now have an output directory with your compiled components in all frameworks!

Recommended: Install ESLint Rules

We recommend you install our ESLint plugin to have highly useful rules that guide you as you build your Mitosis components.

Next up

Our recommended next steps are to:

  • add a build step for each generated output (e.g. a Svelte library will need to be build using Sveltekit's svelte-package command)
  • add a test-servers/ folder containing web apps that import your outputs, so that you can test them (either manually or programatically).

Examples

Here are some helpful resources on trying out Mitosis:

What is Mitosis?

  • this talk by Sami Jaber at React Day Berlin is a great intro to Mitosis. It gives a good overview of the impetus behind Mitosis, and a high-level understanding of its different pieces.

  • The below video is a brief introduction by Steve Sewell. Mitosis Video

Docs

Curious about how Mitosis code works under the hood, and how to use it? Learn more in our in-depth docs.

Why use Mitosis?

Mitosis is an incredibly powerful and flexible tool. So far, we have identified 3 broad categories of engineering teams that stand to benefit greatly from it:

Design Systems Maintainers

If you are the maintainer of a design system library that started off in one web framework, then you have felt the tremendous amount of maintenance pain and duplication when creating new versions for subsequent frameworks. Look no further than the popular React library Chakra UI, and how the maintainers have decided to create Zag.js after feeling the pain of maintaining state-logic code across both their React and Vue libraries. While Zag.js focuses on writing framework-agnostic interactions, Mitosis focuses on writing framework-specific components. (PS: We are working on building examples that combine these two together. TBD!)

Teams using multiple web frameworks

If you are part of a team/organization that has multiple frontends built in different frameworks, then you know that coordinating your design system across all of them for a cohesive experience and feel is an absolute nightmare. Mitosis is an excellent tool to eliminate this class of problems, as it allows you to define your designs in your components once and deploy them to all of your separate frontends.

Teams building web SDKs

If your team is building SDKs for a product that integrates directly into a web framework and involves providing components to the end user, then Mitosis is a perfect fit for your team. Our team at Builder.io has this exact use-case: our new generation of SDKs is built with Mitosis! Our engineers have received glowing praise from our sales team for speed of delivery, and all it took was a switch flip ๐Ÿ˜‰


What about XKCD

XKCD comic about solving too many standards by creating new standards just making yet another standard

Yup, we've all seen it. But if this is a concern for you, you may be looking at Mitosis wrong. Rather than just yet-another-component-syntax, Mitosis is a compiler for the frontend, analogous to LLVM. A toolchain that embraces that there are, and forever will be, many ways of writing components. Mitosis defines a common intermediate representation that allows us to author components once then compile to many frameworks, just like LLVM lets us write code that can compile to any instruction set architecture. If you look at Mitosis this way, you may more clearly see the value.

Also similarly to LLVM, multiple syntaxes can compile to Mitosis. Our out-of-the-box syntax uses JSX, but we have explored others, such as a Vue/Svelte-like syntax. Builder.io emits Mitosis IR, allowing you to turn designs to code for any supported framework. JSX and Builder.io are the currently supported frontends of the compiler, and the frameworks listed below are the backends.

E2E test status

Target 01 one component 02 two components
alpine โœ… โœ…
angular โœ… โœ…
qwik โœ… โœ…
react โœ… โœ…
solid โœ… โœ…
svelte โœ… โœ…
vue2 โœ… โœ…
vue3 โœ… โœ…

NOTE: this matrix is programmatically generated and should not be manually edited.

Contribute

Interested in contribute? Head over to the developer docs and see how you can get setup & started!

Once you're ready, checkout our issues page and grab your first issue!

Community

Related Projects

  • Figma plugin: Convert Figma designs into high quality HTML, React, Vue, Svelte, Angular, Solid, etc code via Mitosis.
  • Builder: Drag and drop page builder and CMS for React, Vue, Angular, and more.
  • Qwik: An open-source framework designed for best possible time to interactive, by focusing on resumability of server-side-rendering of HTML, and fine-grained lazy-loading of code.
  • Partytown: Relocate resource intensive third-party scripts off of the main thread and into a web worker. ๐ŸŽ‰


Made with love by Builder.io

mitosis's People

Contributors

akrabdev avatar alujs avatar asyncbanana avatar cmgriffing avatar codyebberson avatar crutchcorn avatar decadef20 avatar dkendal avatar elfpie avatar epreston avatar g-cheishvili avatar kingzez avatar mandx avatar mfranzke avatar mhevery avatar micmro avatar mrkoreye avatar nmerget avatar ohkimur avatar patrickjs avatar raymondmuller avatar razz21 avatar rootenginear avatar rqzheng2015 avatar sachinraja avatar sahilmob avatar samijaber avatar sanyamkamat avatar sidmohanty11 avatar steve8708 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  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

mitosis's Issues

Conditionals not supported?

Any plans to support conditional expressions with JSX?

image

This is fairly idiomatic - not just to React, but to JSX with most frameworks and libraries.

It looks like you do support loops so I was a bit surprised you don't see to support conditionals - it seems like loops would be more difficult to implement, so maybe this is just a bug?

Either way, loops and conditionals are both pretty essential to building any UI, I think. ๐Ÿ™‚

HTML Characters break prettier stage of Vue generation

Minimal reproducible example:
https://mitosis.builder.io/?outputTab=G4VwpkA%3D&code=JYWwDg9gTgLgBAbzgVwM4FMDKMCGN1wC%2BcAZlBCHAEQACAVqgB4C0ANsPgPQDG06VAbgBQQ9I0iw4AE3QkcyVvBLIAdtxjAIKuABV0qGAGEKkFehUwAFAEpEQuHF4qDcA3gIBeFBmzvLCQlsHOBEHKHQYZChtS3tghwAeKWAANwA%2BOPiHADIAYgBGAAZigFZM4ITOZPS462FCISA

Could not prettify 
Object { string: "<template>\n  <div >\n    &#10005\n  </div>\n</template>\n<script>\n  \n\n\n\n\n  export default {\n    \n    \n\n    \n    \n\n    \n    \n  }\n</script>" }
 SyntaxError: Unexpected character "
" (3:12)
  1 | <template>
  2 |   <div >
> 3 |     &#10005
    |            ^
  4 |   </div>
  5 | </template>
  6 | <script>
    kt https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:117490
    ds https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:117602
    e https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:117602
    parse https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:117602
    parse https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:100507
    Xi https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:100507
    Yi https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:100507
    formatWithCursor https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:100507
    Px https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:100507
    format https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:100507
    componentToVue https://jsx-lite.builder.io/static/js/main.836493ea.chunk.js:2856
    updateOutput https://jsx-lite.builder.io/static/js/main.836493ea.chunk.js:6552
    executeAction https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:57106
    res https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:57090
    Fiddle https://jsx-lite.builder.io/static/js/main.836493ea.chunk.js:6554
    executeAction https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:57106
    res https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:57090
    reactionRunner https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58637
    r https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58618
    runReaction_ https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58303
    runReactionsHelper https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58445
    reactionScheduler https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58420
    reactionScheduler https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58458
    Wj https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266729
    reactionScheduler https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58457
    runReactions https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58426
    schedule_ https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58282
    reaction https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:58641
    useReaction https://jsx-lite.builder.io/static/js/main.836493ea.chunk.js:6449
    fk https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266747
    unstable_runWithPriority https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266819
    gg https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266607
    Oj https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266746
    Lj https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266728
    jg https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266608
    unstable_runWithPriority https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266819
    gg https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266607
    jg https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266608
    ig https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266607
    Xj https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266729
    tk https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266774
    render https://jsx-lite.builder.io/static/js/4.bc68c593.chunk.js:266781
    1876 https://jsx-lite.builder.io/static/js/main.836493ea.chunk.js:6562
    c https://jsx-lite.builder.io/?outputTab=vue&code=import+{+useState+}+from+"%40jsx-lite%2Fcore"%3B export+default+function+TestComponent()+{ ++const+state+%3D+useState({})++++ ++return+( ++++++<div> ++++++++%26%2310005 ++++++<%2Fdiv> ++)%3B } :1
    r https://jsx-lite.builder.io/?outputTab=vue&code=import+{+useState+}+from+"%40jsx-lite%2Fcore"%3B export+default+function+TestComponent()+{ ++const+state+%3D+useState({})++++ ++return+( ++++++<div> ++++++++%26%2310005 ++++++<%2Fdiv> ++)%3B } :1
    t https://jsx-lite.builder.io/?outputTab=vue&code=import+{+useState+}+from+"%40jsx-lite%2Fcore"%3B export+default+function+TestComponent()+{ ++const+state+%3D+useState({})++++ ++return+( ++++++<div> ++++++++%26%2310005 ++++++<%2Fdiv> ++)%3B } :1
    <anonymous> https://jsx-lite.builder.io/static/js/main.836493ea.chunk.js:1

For consideration: Compile to Alpine.js

Alpine.js offers you the reactive and declarative nature of big frameworks like Vue or React at a much lower cost.

You get to keep your DOM, and sprinkle in behavior as you see fit.

Think of it like Tailwind for JavaScript.

Note: This tool's syntax is almost entirely borrowed from Vue (and by extension Angular). I am forever grateful for the gift they are to the web.

A small preview (taken for the README):

Dropdown/Modal

<div x-data="{ open: false }">
    <button @click="open = true">Open Dropdown</button>

    <ul
        x-show="open"
        @click.away="open = false"
    >
        Dropdown Body
    </ul>
</div>

Tabs

<div x-data="{ tab: 'foo' }">
    <button :class="{ 'active': tab === 'foo' }" @click="tab = 'foo'">Foo</button>
    <button :class="{ 'active': tab === 'bar' }" @click="tab = 'bar'">Bar</button>

    <div x-show="tab === 'foo'">Tab Foo</div>
    <div x-show="tab === 'bar'">Tab Bar</div>
</div>

Export out of figma puts all the content way to the left

Hi!

First off: Awesome project! Excited to see where this goes.
I've tried some exports but have only mixed results so far, anything nested puts my content somewhere way off to the side

When I try to export this button for instance:
image

With this css
image

I get this output:

{
  "data": {
    "blocks": [
      {
        "@type": "@builder.io/sdk:Element",
        "id": "builder-26987015574467677",
        "responsiveStyles": {
          "large": {
            "position": "absolute",
            "top": "0px",
            "left": "0px",
            "width": "329px",
            "height": "65px",
            "backgroundColor": "rgba(89, 130, 232, 1)"
          }
        },
        "layerName": "",
        "meta": { "figmaLayerId": "4167:12549" },
        "children": [
          {
            "@type": "@builder.io/sdk:Element",
            "id": "builder-17196040205189211",
            "responsiveStyles": {
              "large": {
                "position": "absolute",
                "top": "-1553px",
                "left": "-8px",
                "width": "302px",
                "height": "24px",
                "color": "rgba(255, 255, 255, 1)",
                "fontSize": "12px",
                "lineHeight": "24px",
                "letterSpacing": "0px",
                "textAlign": "left",
                "fontFamily": "Montserrat"
              }
            },
            "layerName": "Ik ben geรฏnteresserd en wil me...",
            "meta": { "figmaLayerId": "4167:12551" },
            "component": {
              "name": "Text",
              "options": { "text": "Ik ben geรฏnteresserd en wil meer info." }
            }
          },
          {
            "@type": "@builder.io/sdk:Element",
            "id": "builder-6077962971287214",
            "responsiveStyles": {
              "large": {
                "position": "absolute",
                "top": "-1574px",
                "left": "-8px",
                "width": "136px",
                "height": "21px",
                "color": "rgba(255, 255, 255, 1)",
                "fontSize": "17px",
                "lineHeight": "125%",
                "letterSpacing": "0%",
                "textAlign": "left",
                "fontFamily": "Montserrat"
              }
            },
            "layerName": "",
            "meta": { "figmaLayerId": "4167:12550" },
            "component": {
              "name": "Text",
              "options": { "text": "Contacteer ons" }
            }
          }
        ]
      }
    ]
  }
}

Could this have something to do with the relative position of the layer in the figma document?
Many thanks! I hope to contribute to the project as a developer too in the future!

There isn't on-change method in Svelte and $: don't need a function

This is almost perfect, you only need to remove the unnecessary import and it's done.

<script>
 // You only need to remove this line
  import onChange from "on-change";
  
  // To create a prop you need to export de variable
  export let showInput;

  let name = "Steve";
</script>

In Computed

<script>
// You only need to remove this line
  import onChange from "on-change";
  let showInput;

 // Don't need a function
  $: lowerCaseName = () => {
    return name.toLowerCase();
  };

// Use this way
$: lowerCaseName = name.toLowerCase();

  let name = "Steve";
</script>

Eslint rules

Mitosis needs a decent amount of constraints given the amount of targets it needs to support. This can make for a very clunky DX if you don't get real time feedback on what is allowed vs not

We have started on an eslint plugin here but it could use a lot more checks in it

[fiddle] + dark mode

Neat tool!

The lack of dark mode is a bit of A11y issue for me; too much white screens can aggravate my concussion. I had to install a "Dark Mode" browser exertion; the fiddle actually looks better with it on to me! (I'd only make the line numbers more transparent/less bright) Unfortunately this doesn't work in VSCode.
image

(Side note; I'm not totally motion sensitive, but FPS are a no-no now :/ Some motion is fine when I expect it, but constantly animating something like a slider or pulsing menu highlight is a bit more frustrating now.)

Also, I find there isn't enough contrast &/or line thickness for your current white mode.

onUnMount is not defined

When using Edit content JS + CSS in builder, onMount work well but getting an onUnMount error when trying to do clean-ups.

let sub;
let categoriesSub;

onMount(() => {

    if (typeof Sellox === 'undefined') return;
    Sellox.loadFirestore().then((_) => {
        // get data
        sub = Sellox
            .Shop
            .getProducts()
            .subscribe(products => {
                state.products = products.map(item => {
                    item.image = getThumbnail(item)
                    return item;
                });
            });

        categoriesSub = Sellox
            .Shop
            .getCategories()
            .subscribe(
                categories => state.categories = categories
            )
    })
})
onUnMount(() => {
    sub && sub.unsubscribe();
    categoriesSub && categoriesSub.unsubscribe()
})

1

Tailwind Template not running

Seems the TailWind template in the builder website is missing a '}', so the template won't build and run.

This issue is related to the de2c766 commit.

import { useState } from "react";

export default function MyComponent(props) {
  const [name, setName] = useState("Steve");

  return (
    <div
      css={{
        padding: "10px",
      }}
    >
      <link
        href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css"
        rel="stylesheet"
      />

      <input
        className="shadow-md rounded w-full px-4 py-2"
        placeholder="What is your name?"
        value={name}
        onChange={(event) => setName(event.target.value)}
      />

      <h1
        className="text-lg"
        css={{
          marginTop: "10px",
        }}
      >
        Hello,
        {name}!
      </h1>
    </div>
  );

Props removed when compiling to Solid

When compiling to solid js, the props argument from the function seems to get removed.

This can be easily reproduced in the jsx-lite playground itself:

export default function MyComponent(props) {
  return (
    <div css={{ padding: '10px' }}>
      <h1>{props.title}</h1>
    </div>
  );
}

Ouput to Solid:

export default function MyComponent() {
  const state = createMutable({});

  return (
    <div class={css({ padding: "10px" })}>
      <h1 css={{}}>{props.title}</h1>
    </div>
  );
}

As you can see, props are removed from the arguments in the output.

Custom classes are rewritten

I'm testing out the builder at builder.io/fiddle and tried the "Import from:" function.

I imported from: https://getbootstrap.com/docs/5.0/examples/album/

Looking at the HTML/CSS/JS in the "Get Code" viewer, builder.io seems to have replaced all the classes with random div names.

e.g. div class="container" has been changed to div class="div-2", and all the p class tags are also divs.

I also noticed this/a similiar problem with the HTML and CSS when dragging columns into the empty builder.

  <div class="builder-columns div-2">
    <div class="builder-column div-3">
      <div class="div-4">
        <div class="div-5">

I'm pretty new to HTML and CSS, but I'm used to seeing class names like 'container', 'column', etc., and seeing a few classes be reused on multiple divs, as opposed to what the Builder seems to be producing, which is multiple divs each with their own individual class.

uploading figma json

It's currently not uploading. I got html to figma extension, downloaded a sites json and then attempted to upload the "page.builder.json" to no avail.

`react_devtools_backend.js:2430 Format error for file: export default function MyComponent(props) {

return (

)

} {
"@type": "@jsx-lite/component",
"imports": [],
"meta": {},
"state": {},
"children": [],
"hooks": {},
"name": "MyComponent"
}
overrideMethod @ react_devtools_backend.js:2430
push.687.exports.componentToJsxLite @ main.36112113.chunk.js:7784
_callee2$ @ main.36112113.chunk.js:6668
tryCatch @ 4.d40dd466.chunk.js:266901
invoke @ 4.d40dd466.chunk.js:267131
(anonymous) @ 4.d40dd466.chunk.js:266956
asyncGeneratorStep @ 4.d40dd466.chunk.js:116118
_next @ 4.d40dd466.chunk.js:116140
Promise.then (async)
asyncGeneratorStep @ 4.d40dd466.chunk.js:116128
_next @ 4.d40dd466.chunk.js:116140
Promise.then (async)
asyncGeneratorStep @ 4.d40dd466.chunk.js:116128
_next @ 4.d40dd466.chunk.js:116140
(anonymous) @ 4.d40dd466.chunk.js:116147
(anonymous) @ 4.d40dd466.chunk.js:116136
Rb @ 4.d40dd466.chunk.js:266535
Xb @ 4.d40dd466.chunk.js:266535
Yb @ 4.d40dd466.chunk.js:266536
Ze @ 4.d40dd466.chunk.js:266583
se @ 4.d40dd466.chunk.js:266584
(anonymous) @ 4.d40dd466.chunk.js:266596
Jb @ 4.d40dd466.chunk.js:266775
Nb @ 4.d40dd466.chunk.js:266533
jd @ 4.d40dd466.chunk.js:266588
yc @ 4.d40dd466.chunk.js:266558
hd @ 4.d40dd466.chunk.js:266557
push.exports.unstable_runWithPriority @ 4.d40dd466.chunk.js:266817
gg @ 4.d40dd466.chunk.js:266605
Hb @ 4.d40dd466.chunk.js:266775
gd @ 4.d40dd466.chunk.js:266556
`

`Uncaught (in promise) SyntaxError: Expression expected. (11:5)
9 | return (
10 |

11 | )
| ^
12 | }
at e (4.d40dd466.chunk.js:111868)
at Object.parse (4.d40dd466.chunk.js:111881)
at Object.parse (4.d40dd466.chunk.js:100463)
at Xi (4.d40dd466.chunk.js:100463)
at Yi (4.d40dd466.chunk.js:100463)
at formatWithCursor (4.d40dd466.chunk.js:100463)
at 4.d40dd466.chunk.js:100463
at Object.format (4.d40dd466.chunk.js:100463)
at push.687.exports.componentToJsxLite (main.36112113.chunk.js:7776)
at _callee2$ (main.36112113.chunk.js:6668)`

mitosis fiddle/CLI/local-dev not available in any way

I'd really like to play with mitosis, but can't find a way to make it work...

  1. interactive fiddle is down for the past week.
  2. CLI is not working, getting:
 $ mitosis compile --to=vue my-file.lite.jsx

results in:

Error: Cannot find module 'prettier/parser-html'
  1. and the last resort - cloning the project and attempting to install, bootstrap and build fail on different reasons (missing files, file://.. deps that do not exists, etc.).

any plans on making one of the above options available for external users (and potential fans ๐Ÿ˜‰ )?

Project Compiling CLI

Today, we only compile one file at a time. What would be most useful for most peoples setups, though, would be to compile a project, for instance

package.json
src/
   my-component.lite.tsx
   my-dependency.ts

could compile to a fully installable package per framework, like

dist/
  package.json
  react/
    my-component.js # compiled to react JS
    my-dependency.js
  vue/
    my-component.js # compiled to Vue
    my-dependency.js

where you can do like

import { MyComponent } from 'project-name/react'

or

import { MyComponent } from 'project-name/vue'

we have begun exploring this direction. a few things we've noticed

  • vue2 vs vue3 have different ways of compiling. and nuxt2 doesn't want precompiled components. so even per framework we might want different outputs in different folders. like vue2/, vue3/, nuxt2/, etc
  • some frameworks, like react native, need overrides. so we started experimenting with an overrides/ folder convention where you can override any file per-output, and it just compiles and copies over to the dist/output dir

Reverse-Mitosis

Greetings.

Does anyone know of a good way to go from "framework" code back to mitosis ๐Ÿ˜

any plan to support compiling jsx to customElements class of web components?

jsx-lite example

import { useState } from '@jsx-lite/core';

export default function MyComponent(props) {
  const state = useState({
    name: 'Steve'
  });

  return (
    <div>
      <Show when={props.showInput}>
        <input
          css={{ color: 'red' }}
          value={state.name}
          onChange={(event) => (state.name = event.target.value)}
        />
      </Show>
      Hello! I can run in React, Vue, Solid, or Liquid!
    </div>
  );
}

may be compiled to something like this

class MyComponent extends HTMLElement {
  constructor() {
    super();
	this.state = {
	name: 'Steve'
	}
  }

 connectedCallback() {
    this.innerHTML = `<div> <show> </show></div>;
  }

}

customElements.define('my-component', MyComponent});

web components is the official standard.
It's becoming more and more popular for big companies, like google polymer, microsoft fast,salesforce lwc, SAP ui5...

implementation ideas may be inspired by project react-to-webcomponent

Error with Context Map and Web Component Target

If you use this JSX Lite code:

import { useState, For } from "@jsx-lite/core";

export default function MyComponent(props) {
  const state = useState({
    name: "Steve",
    products: [{ title: "Blue suede shoes" }],
  });

  return (
    <div>
      <h2>
        Welcome,
        {name}
      </h2>
      <For each={state.products}>
        {(product, index) => <div>{product.title}</div>}
      </For>
    </div>
  );
}

it creates some web component code where in the constructor it is running

contextMap = new WeakMap();

And contextMap is referenced in the methods of the web component class. Was it meant to be this.contextMap?

How do I run this project on my local machine?

When I try yarn install in root path - It throughs an error

error Package "" refers to a non-existing file '"/xxx/xxx/Documents/codesmith-ptri3/core"'. info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command. Error: Package "eslint-plugin-mitosis" refers to a non-existing file '"/xxx/xxx/Documents/codesmith-ptri3/eslint-plugin"'. at MessageError.ExtendableBuiltin (/xxx/xxx/.nvm/versions/node/v14.15.3/lib/node_modules/yarn/lib/cli.js:721:66) at new MessageError (/xxx/xxx/.nvm/versions/node/v14.15.3/lib/node_modules/yarn/lib/cli.js:750:123) at FileResolver.<anonymous> (/xxx/xxx/.nvm/versions/node/v14.15.3/lib/node_modules/yarn/lib/cli.js:50230:15) at Generator.next (<anonymous>) at step (/xxx/xxx/.nvm/versions/node/v14.15.3/lib/node_modules/yarn/lib/cli.js:310:30) at /xxx/xxx/.nvm/versions/node/v14.15.3/lib/node_modules/yarn/lib/cli.js:321:13

ENV:
yarn -v: 1.22.10
MacOS Big Sur

Please let me know if there is more info I can provide to troubleshoot. TY

Samples with SASS

Hi folks, that you for very interesting library.

Is there any way to make it works with sass? I'm looking for way to embed css into solid/vue/react/customElement compoments

License

This repo does not look to have a license

@emotion/react: Builder JSON conversion to React + Next.js

I'm trying to use a React generated Component in a Next.js application, generated from a Builder JSON object that was created through Figma + BuilderIO Plugin.

My conversion command:

jsx-lite compile --to=react --from=builder --out-dir=dist/ figma/MyComponent.json

This generates a React component that uses the @emotion/react library.

/** @jsx jsx */
import { jsx } from "@emotion/react";

export default function MyComponent(props) {
  return (...)
};

However, the generated react component uses some components like Image, Columns or Column objects and next.js isn't able to find them.

From the emotionjs docs it says Next.js is supported out of the box without any changes required:

For @emotion v10 and above, SSR just works in Next.js.

Should I manually edit the generated MyComponent.jsx file and correcly apply the imports or is there a configuration I'm missing in next.config.js or webpack configuration?

I've successfully changed the imports to look like this and fixed most of the issues, however I'm still having issues finding the correct import declarations for Columns and Column components:

/** @jsx jsx */ /** @jsxRuntime classic */
import { jsx } from '@emotion/react';
import Image from '@emotion/styled';
import React from 'react';

export default function MyComponent(props) {
  return (...)
};

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main resolved in C:\Users\GT-N02\AppData\Roaming\npm\node_modules@jsx-lite\cli\node_modules@jsx-lite\core\package.json

os: win10
node: 12.18.2 15.11.0

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main resolved in C:\Users\GT-N02\AppData\Roaming\npm\node_modules@jsx-lite\cli\node_modules@jsx-lite\core\package.json

os: win10
node: 12.18.2 15.11.0

Migrate Mitosis to latest Qwik format

Currently, Mitosis generates the original prototype version of Qwik. Update the mitosis to generate the latest qHook syntax.

  • Idea is that this will be compatible with the optimizer. (QwikDev/qwik#60)
  • But should run without optimizer as well.

Mitosis

  • Incorrectly treats css binding as on:s
  • Incorrectly binds css instead of style

Builder

  • Loading @builder.io/qwik for each request. Should be moved to shared for performance.
  • Unable to load relative requests.
  • Fix underine => underline

Example with correct TS lib

How to configure TS? When creating <div css={{}} /> I get an error:
Type '{ children: Element[]; css: { padding: string; }; }' is not assignable to type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'. Property 'css' does not exist on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'.

I tried for example importing this with no effect:

/// <reference types="@builder.io/mitosis/dist/src/jsx-types" />

Maybe I'm missing something. Thx in advance ๐Ÿ˜…

Docs

More docs around how to get started, the mental model to have, workflows, and constraints to be mindful of will go a long way to helping people adopt and use this project

Allow choosing state libraries for React and Svelte

E.g. for react, svelte - allow useState (react) and variable assignment (svelte) as an output option for those who want to not use any libraries and are aware they will need to make all top level state mutations immutable (aka they can't do state.foo.bar = 'baz' but in jsx lite will need to do state.foo = {...state.foo, bar: 'baz' }

we can also support mobx for react too

Svelte Syntax Error


<script>
  let showInput;
  let state = { name: "Steve" };
</script>

<style>
  .input-1 {
    color: red;
  }
</style>

<div>
  {#if showInput}
    <input class="input-1" bind:value={state.name} />
  {/if}

  Hello! I can run in React, Vue, Solid, or Liquid!
</div>

Storybook integration

It would be great to integrate Mitosis with Storybook to have a great development environment for viewing components, and ideally be able to preview components across outputs to make sure all is working as expected for each target (React, Vue, etc) you would like to support

props not outputted with componentJson

Currently component props don't appear to be outputting in the component json.
So a component like this with explicit props.

export default function Home (title, body) {
  return ( 
     <div>
          <h1>{title}</h1>
          <div>{body}</div>
     </div>
)

Isn't returned in this.

{
  '@type': '@jsx-lite/component',
  imports: [],
  meta: {},
  state: {},
  children: [
    {
      '@type': '@jsx-lite/node',
      name: 'html',
      meta: {},
      properties: {},
      bindings: {},
      children: [Array]
    }
  ],
  hooks: {},
  context: { get: {}, set: {} },
  name: 'Home',
  subComponents: []
} 

At least as far as I have found.

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.