tweaselORG / platform

Server for the tweasel.org platform, allowing users to analyse Android and iOS apps for data protection violations and send complaints about them to the data protection authorities.
MIT License
1 stars 0 forks source link

Which framework to use? #1

Closed baltpeter closed 5 months ago

baltpeter commented 6 months ago

We considered using Fresh or Qwik (City) as a framework and decided on Fresh.

baltpeter commented 5 months ago

Unfortunately, I have already run into quite an annoying problem with the first thing I tried. :/

I've wanted to import our styles from @datenanfragen/components.

Fresh itself doesn't have SASS support, but I've managed to implement that myself fairly easily using the following in fresh.config.ts[^hack]:

[^hack]: Bit of a hack, but fresh.config.ts is included from both dev.ts and main.ts and I wasn't sure whether I should modify those, since there is also an upgrade script that might change those? shrug

import { compileAsync as compileSass } from 'npm:sass@1';

const styles = await compileSass(new URL('styles/main.scss', import.meta.url).pathname);
await Deno.writeTextFile('static/styles.gen.css', styles.css);

That works fine so far. However, now I want to import the stylesheet from our components package. Usually, we would do that like this:

@import 'npm:@datenanfragen/components/dist/index.css';

That, perhaps unsurprisingly, doesn't work. The generated CSS is identical to the SCSS, the import statement is just copied over.

That is understandable. With Node, that file is in node_modules/@datenanfragen/components/dist/index.css relative to the package.json. With Deno, there is neither a package.json nor a node_modules folder, so how would it know where to find the file.

Instead, the imported NPM modules end up—globally—in ~/.cache/deno/npm/registry.npmjs.org.

First problem: There is no install step. Modules aren't installed if you just add them to the import map. They are only installed when they are first used. But of course, that is built with JS in mind—as far as I can tell, you would have to import something from the module for that to happen.
But let's gloss over that problem for now. That should be easy enough to work around.

I also tried importing the CSS file from JS (i.e. import css from 'npm:@datenanfragen/components@1.0.0/dist/index.css';).

That failed because @datenanfragen/components depends on a GitHub-version of a package:

error: Error in @datenanfragen/components@1.0.0 parsing version requirement for dependency: brutusin-json-forms@https://github.com/brutusin/json-forms

Invalid npm version requirement. Unexpected character.
  https://github.com/brutusin/json-forms
  ~

Caused by:
    0: Invalid npm version requirement. Unexpected character.
         https://github.com/brutusin/json-forms
         ~
    1: Unexpected character.
         https://github.com/brutusin/json-forms
         ~

I solved that problem by importing from 'https://esm.sh/@datenanfragen/components@1.0.0/dist/index.css' instead (esm.sh is a CDN specifically designed to transpile modules into a Deno-compatible format).

But that still didn't help, because Deno cannot currently import non-JS files:

error: Expected a JavaScript or TypeScript module, but identified a Unknown module. Importing these types of modules is currently not supported.
  Specifier: https://esm.sh/@datenanfragen/components@1.0.0/dist/index.css
    at file:///home/benni/coding/JS/tweasel/platform/fresh.config.ts:3:17

Next idea: The sass module has loadPaths option to tell it where to load imported file from. But how do we find the folder where the module is installed? I really don't want to manually construct the path based on the user's cache directory. That seems very prone to breaking.

By name, import.meta.resolve sounded useful, but alas that only returns what you have written in the import map (so, npm:@datenanfragen/components@1). Not helpful to us.

Unfortunately, I didn't find any remotely clean method of getting the location of index.css.

I also checked whether there are any examples for using Bootstrap from Fresh/Deno since that is also uses Sass. But everything I found either imported the transpiled CSS from a CDN (https://medium.com/frontendweb/how-to-use-bootstrap-with-a-fresh-framework-fc73b14ef7f9, https://github.com/Octo8080X/fresh-bootstrap/blob/main/src/plugins/plugin.ts) or vendored it (https://github.com/officialrajdeepsingh/fresh-bootstrap/blob/main/static/bootstrap.min.css).

baltpeter commented 5 months ago

I'm not sure how to continue from here, to be honest. For one, I'm kind of out of ideas as for how to solve this issue.

But that's not my main problem. Much more importantly, I am quite concerned that I ran into this annoying of a problem this quickly. We did of course expect some struggles using Deno in a project that has heavy prior Node.js baggage. But I've now wasted quite a lot of time unsuccessfully solving this problem and that was literally the very first non-trivial thing I tried to do at all. :(

I do still very much like many of the ideas and decisions behind Deno and Fresh, especially after now having had a proper read of their documentation. But I am very worried that this is going to be a huge time sink if we continue using Fresh. And I'm afraid, we really can't afford that right now.

baltpeter commented 5 months ago

If we did want to consider something else, I noticed that Astro also has islands: https://docs.astro.build/en/concepts/islands/

I haven't used that before and haven't evaluated it further, but I do think that is is quite mature and, well, Node-based…

zner0L commented 5 months ago

Yeah, lets go with Astro then. At a first glance it doesnt seem as convoluted as Qwick, but shares many concepts of fresh. But can we still use our preact-based Components with Astro? I am imagining there must be some slight API differences…

baltpeter commented 5 months ago

Preact is officially supported: https://docs.astro.build/en/guides/framework-components/#official-ui-framework-integrations

baltpeter commented 5 months ago

Well, getting the CSS to work was certainly a lot less painful in Astro.

baltpeter commented 5 months ago

I'll unfortunately have to make TypeScript a little less strict that I would like to until https://github.com/edgedb/edgedb-js/issues/1031 is fixed.