gnat / surreal

🗿 Mini jQuery alternative. Dependency-free animations. Locality of Behavior. Use one element or arrays transparently. Pairs with htmx. Vanilla querySelector() but better!
https://gnat.github.io/surreal/example.html
MIT License
1.2k stars 24 forks source link

usage with astro #8

Closed shriharip closed 11 months ago

shriharip commented 11 months ago

Really love the simplicity. I tried using this inside Astro and was having some issues getting things to work. I am hitting an error with

globalsAdd() {
        console.log(`Surreal: adding convenience globals to window`)
        restricted = ['$', 'sugar']

restricted is not defined at Object.globalsAdd (surreal.js:214:14) at surreal.js:286:3

Any insights would be helpful

BTW, i am using it inside a header tag to set attribute

<header> 
<div>
<script is:inline>
        me().attribute('data-open' , false)
    </script>
</div>
<div>
...
...
</header>
cfuendev commented 11 months ago

I'm having the same problem while working with a Vite Lit app, so this might be a Vite thing.

Uncaught ReferenceError: restricted is not defined
    at Object.globalsAdd (index-ba3b68a9.js:1:4141)
    at index-ba3b68a9.js:1:5519

I'm importing through the html head:

  <script type="module" src="/src/assets/surreal.js"></script>

Sidenote: If I don't load as module, surreal.js won't work

gnat commented 11 months ago

Thank you for the kind words!

Does var restricted = ['$', 'sugar'] help?

I'm open to supporting individual build systems if the changes are small enough-- but Surreal is designed to be run directly inside your web browser without a build system, and is only tested on web browsers (Chrome, Firefox, Safari, Edge, mobile versions of these..).

Could this also be a documentation issue? Perhaps there's a build flag missing to turn off some of these opinionated errors and support "browser javascript" features in Vite?

cfuendev commented 11 months ago

Perhaps there's a build flag missing to turn off some of these opinionated errors and support "browser javascript" features in Vite?

I'll address my observations about this first, since I already found a solution for my case.

By default Vite bundles for browsers with native ES Modules, native ESM dynamic import, and import.meta support (source: Vite Docs), so I don't really understand what goes wrong during Vite build that causes this.

Plus, I am using surreal on a PyWebview app, which leverages the Webview2 Runtime a.k.a Edge on Windows, so it's definitively a Vite problem. The build step messes up the script in some way that it can't be loaded properly on a browser without working around the variables not defined through use of var, let or const.

However, after loading surreal from the CDN instead of as a local script, no errors occured. I guess bottom line is don't download surreal.js directly to your project as a static file on a Vite project / Vite-powered framework project so that surreal doesn't discombobulate during the build step.

I'm not sure if this is the case for @shriharip, but if you're also adding surreal as a script, simply importing surreal through the CDN on your template's head should fix it. In the case of Astro, I guess you should make a layout where you import surreal from the CDN in the head then import it wherever you're using surreal.

Now...

Does var restricted = ['$', 'sugar'] help?

That does indeed fix the issue with restricted

Now the only error I got while importing surreal as a local script, which seems to be the only one left:

Uncaught ReferenceError: addOnload is not defined

I fixed it by doing

var add_onload; var addOnload;
const onload_add = add_onload = addOnload = onloadAdd // Aliases

I know, pretty ugly. I don't know if there's a more elegant way to approach this, but that did fix it.

However, just using the CDN in Vite projects seems reasonable, unless it's being used on a 100% offline webview desktop app that happens to be using Vite. In that case excluding the file from Vite build might work (?)

shriharip commented 11 months ago

Will check this and get back. Sorry I am with limited internet access and will let you know my findings with the suggestions listed.

shriharip commented 11 months ago

Ok, few inputs.

  1. On Astro, I was indeed importing in the layout section. That is inside the head tag as an inline script. According to the docs, inline scripts are not processed by the astro vite plugin and is rendered as is.
  2. I had to declare 2 things for surreal to not console errors. these are
    <script is:inline >
            var restricted = ['$', 'sugar'] 
            var me;
        </script>
  3. Inside my component I had this small div.
    <div>I change color every second.
    <script is:inline>
    me().on("click", async ev => {
     console.log("clicked")
    })
    </script>
    </div>

    However, astro takes out the script tag and moves it to the bottom of the body tag. So this mean LOB is lost and the click is not captured. So, maybe it might not work for this framework. :(

cfuendev commented 11 months ago

Aaah! I see. Thanks for the explanation, that clears it out.

maybe it might not work for this framework. :(

I'm very sad to hear that, surreal.js is fun. To me it seems like an Astro integration/port could be made by the Astro community to tackle this dilemma. It could be either:

  1. A way to halt the default "pushing to the bottom of the body" behavior or..
  2. Some sort of syntax sugar that makes the DX feel like LOB but compiles down to your usual document.querySelector() and element.addEventListener() stuff.

Good job on figuring out the quirks preventing surreal from working and I hope you or someone else on the Astro ecosystem can figure out a way to make surreal work correctly with Astro.