squint-cljs / cherry

Experimental ClojureScript to ES6 module compiler
https://squint-cljs.github.io/cherry
562 stars 22 forks source link

UMD build #101

Closed hatemhosny closed 1 year ago

hatemhosny commented 1 year ago

Great project! Thank you

Would you please provide a UMD build for the compiler published to npm?

I want to use the compiler in a web worker. Currently firefox does not support worker module.

I see you already have esbuild as a dependency.

This should be something like:

esbuild index.js --bundle --minify --format=iife --global-name=CherryCljs --outfile=lib/cherry.umd.js

thank you

borkdude commented 1 year ago

@hatemhosny Before I pursue this solution, can you maybe try this locally, or provide an example of how I could test this in a web worker? Note that the standard library of cherry is also compiled as an ES6 module, isn't this a problem?

hatemhosny commented 1 year ago

@borkdude

thank you for the response.

This is an example for the proposed build:

repo: https://github.com/live-codes/cherry-cljs-compiler

build cmd: https://github.com/live-codes/cherry-cljs-compiler/blob/main/package.json#L8

output: https://github.com/live-codes/cherry-cljs-compiler/blob/main/cherry.umd.js

which was published to npm to be hosted on: https://cdn.jsdelivr.net/npm/@live-codes/cherry-cljs-compiler@0.0.3/cherry.umd.js

and this is a basic usage example for module and classic workers:

https://hatemhosny.github.io/cherry-cljs/

please note that the module worker does not work by default in Firefox (only works after enabling a flag or in developer edition)

source code: https://github.com/hatemhosny/cherry-cljs

Note that the standard library of cherry is also compiled as an ES6 module, isn't this a problem?

I have no problem running the compiled code as a module. I just need the compiler to run in the web worker for performance reasons.

Note: I'm doing that to add ClojureScript support to https://livecodes.io/ (https://github.com/live-codes/livecodes) - documentations

your project is great and does exactly what I need

Thank you very much

borkdude commented 1 year ago

Would index.umd.js make more sense maybe, since we also have index.js? Should I change anything in package.json? Why not .cjs instead of .js?

hatemhosny commented 1 year ago

Would index.umd.js make more sense maybe, since we also have index.js?

May be. But I think of index.js as the default file. While the UMD will need to be specified by full URL: https://cdn.jsdelivr.net/npm/cherry-cljs@0.0.3/index.umd.js vs https://cdn.jsdelivr.net/npm/cherry-cljs@0.0.3/cherry.umd.js

That's just a stylistic opinion.

Should I change anything in package.json?

you may want to add these fields to package.json (more details)

{
  "type": "module",
  "main": "./index.js",
  "module": "./index.js",
  "types": "./index.d.ts",
  "exports": {
    ".": {
      "import": "./index.js",
      "require": "./index.cjs"  // <- only if you also want to provide a cjs build
    }
  }
}

also these would allow you to import from https://cdn.jsdelivr.net/npm/cherry-cljs@0.0.3 rather than https://cdn.jsdelivr.net/npm/cherry-cljs@0.0.3/index.js

I do not think there is a field where we specify UMD builds. They are usually loaded by the browser, which requires us to specify full path anyways.

Why not .cjs instead of .js?

That would be a third build format for commonjs.

For UMD builds, use iife

Also, since the API is very simple, it would be easy to add TypeScript support by adding this simple file:

index.d.ts

export declare const compileString: (code: string) => string;

and referring to it in types field in package.json (see above)

hatemhosny commented 1 year ago

@borkdude

I have added provisional support for ClojureScript in LiveCodes using your great library.

ClojureScript starter template (on the development build): https://dev.livecodes.io/?template=clojurescript

I have given credit to your project in the documentations: https://dev.livecodes.io/docs/languages/clojurescript

I'm currently temporarily using the UMD build I have published, till the official build is ready.

Thank you very much 🙏

borkdude commented 1 year ago

@hatemhosny Very cool! I'll just follow your suggestion and will make the .umd.js available shortly.

I think it'll be better to mention CLJS as "CLJS (cherry)" since this isn't the official CLJS compiler, so mentioning cherry (with a link to this project) will probably be best.

borkdude commented 1 year ago

It's published now. Please let me know the final link to livecodes.io, then I'll share it around :)

hatemhosny commented 1 year ago

@borkdude

I followed your suggestion adding (cherry) to the title of CLJS (https://dev.livecodes.io/?template=clojurescript)

Screenshot (462)

the language info screen does indeed link to your project

Screenshot (463)

Thank you for providing the umd build. I have updated LiveCodes to use your file, and archived my temporary repo with a deprecation notice.

These updates should be published with the next release of LiveCodes (hopefully soon).

Thanks a lot for offering to share it. Very grateful indeed. I will let you know when it is ready.

hatemhosny commented 1 year ago

Hi @borkdude

It's published now. Please let me know the final link to livecodes.io, then I'll share it around :)

LiveCodes is now publicly released. Please read the announcement post.

This is the link to cljs starter template: https://livecodes.io/?template=clojurescript

A quick link to start an empty project in cljs: https://livecodes.io/?cljs

Documentations for ClojureScript language support in LiveCodes (including React/JSX usage): https://livecodes.io/docs/languages/clojurescript/

Thank you for making that possible :)

borkdude commented 1 year ago

Awesome, I shared this news on Twitter, Mastodon and Bluesky :)

hatemhosny commented 1 year ago

Thank you, @borkdude ❤️

You may find this useful. This code can be used to embed a ClojureScript playground in any webpage:

<div id="container"></div>

<script type="module">
  import { createPlayground } from "https://unpkg.com/livecodes";

  const options = {
    params: {
      cljs: '(ns demo\n  ;; you can use npm modules\n  (:require ["canvas-confetti$default" :as confetti]))\n\n(let [el (js/document.getElementById "test")]\n  (.addEventListener el "click"\n    (fn []\n      (confetti)\n      (println "test"))))\n',
      html: '<button id="test">test</button>',
      console: "open",
    },
  };
  createPlayground("#container", options);
</script>

Preview

for details and more options, check the SDK documentations.