ubiquity / ts-template

A template repository for all @ubiquity projects.
2 stars 24 forks source link

Use js frontend framework #67

Open rndquu opened 1 month ago

rndquu commented 1 month ago

This is the 4th or 5th time the topic is discussed. Right now we don't use any JS framework for our frontend applications. Although this approach is probably fine for small scale apps it doesn't stand against frontend apps with a large codebase.

Check https://github.com/ubiquity/pay.ubq.fi/tree/development/static for example, which already became kind of a mess because it's hard to distinguish separate pages, separate components, render methods, utils, etc... Not to mention that unit/snapshort/e2e testing is complicated in such codebase.

We need a JS framework with these features:

I've personally heard good reviews about:

Since I personally have more experience with react then, perhaps, https://preactjs.com/ worth a shot.

So as a part of this issue we should refactor https://github.com/ubiquity/ts-template to use a selected JS framework in a structured way:

rndquu commented 1 month ago

@ubiquity/software-development @zugdev RFC

0x4007 commented 1 month ago

The UIs should be single purpose and these frameworks add more work than save time for simple UIs. However I understand the concern for pay.ubq.fi because its the most mature UI we have.

I think it makes more sense to consider a framework specifically for that repository, not for every repository just starting out with this template.

gentlementlegen commented 1 month ago

To give my opinion, I surely love Next.js for how convenient, powerful, organized, speedy and all the ecosystem that Vercel built around. It can also produce static websites, and embeds SSR which would solve lots of our caching issues, and give instant rendering on the browser. Documentation is plentiful, all based on modern React, community is large, it's well maintained. Very easy to do network calls, invalidate, deploy, and has a very opinionated structure for the folders. I used it from small to large scale, and always found it easy to get used to. But of course it always comes down to personal preference, so this might be my frontend experience speaking.

I know that @0x4007 opinion is always bare TypeScript, which is fine for a one page website, but I must say that when you want to have plenty of collaborators helping as @rndquu said it is really hard to enforce rules. Also, like it happened last time with pay.ubq.fi, it was extremely complicated to change the rewards page because there is no reusable components. We also still have plenty of caching issues with work.ubq.fi that a framework would solve effortlessly.

Another advantage of a framework would be to reuse themes, components and pages across projects.

zugdev commented 1 month ago

I know I am not core team but I don't think TypeScript is the problem - let me add my opinion. The problem I've noticed with pay.ubq.fi and work.ubq.fi was a lack of a carefully laid foundation, in terms of generally good code practices: even the good abstractions that were made, were wrongly used. For instance the button controller in pay.ubq.fi which controls buttons visibility and checkRenderMakeClaimControl & checkRenderInvalidatePermitAdminControl were properly set, but other scripts were also trying to directly manage the buttons state. In work.ubq.fi there were 5 different files directly setting and getting from images cache, when the function fetchAvatars was the one designed to manage cache. Let's suppose work.ubq.fi is broken or slow, someone then goes in to fix it and adds another cache statement in another random function and it repeats the cycle. For real examples please check:

  1. https://github.com/ubiquity/pay.ubq.fi/pull/338/
  2. https://github.com/ubiquity/work.ubq.fi/pull/114
  3. https://github.com/ubiquity/work.ubq.fi/pull/106

Trust me when I say this is a problem react and next won't fix. I think frameworks can definitely help in terms of libraries, styles and development speed, but I disagree with the idea to transition if the reason is believing it will improve code quality. A lot can be done with native js and even more with ts, and to be honest all pages I've seen from Ubiquity are/should be very simple. I think the best "solution" is to lay a very good foundation and keep single responsibility in mind, also having someone specialized in each repo to do these quality reviews. I know managing and reviewing a ton of code bases at the same time is hard - and it is even harder to keep track of what function did what to avoid redundant code. Periodically creating tasks for trusted users to do deep refactors keeping it clean from time to time is also a good idea, after all, it's part of maintenance. There could perhaps be a workflow that counts the number of times each declared function is called.

I think a good addition to the template is having 2 files: on-load.ts and listeners.ts. The first one would be the build entry point (first script called on-load) for the repo, this way we can easily check across all repos what is done on page load, facilitating review. The same applies to the second file, which will contain all listeners and will facilitate understanding all state changing conditions. Let's say I want to hide button if logged in user is not the permit owner, I just need to add a listener for account change and compare user with permit owner. I also need to compare that when I load the page, therefore I write a function isUserPermitOwner(), call it on load and add a listener that calls it on account change.

zugdev commented 1 month ago

By the way, I am available to refactor pay.ubq.fi.

rndquu commented 1 month ago

By the way, I am available to refactor pay.ubq.fi.

I think it makes more sense to move "mint gift card" related features and functions to a separate repo

I think a good addition to the template is having 2 files: on-load.ts and listeners.ts

This is basically react reimplementing with a single root component.

Overall I see what you mean, perhaps it makes sense simply to properly structure https://github.com/ubiquity/ts-template, like:

And utilize a JS template engine https://github.com/janl/mustache.js.

But all of this is already implemented in https://nextjs.org/ :)

zugdev commented 1 month ago

But all of this is already implemented in https://nextjs.org/ :)

Im not against using a framework, I think it is a good idea, but not because it will make code perfect.

whilefoo commented 1 month ago

I agree that a simple static page like landings can be made in pure JS/TS, but once you have dynamic pages like pay.ubq.fi a framework helps a ton. Sure, you can still make it in TS but you will start implementing your own framework :) to manage state, global store, reusable components...

It's true that pay.ubq.fi has a bad foundation because when I had to implement minting card for ubuiquity dollars I had to untangle code, duplicate code, a lot of headaches in short. But even if I wanted to rebuild it with a good foundation I'd have to implement a basic framework to manage everything.

Personally I've done most work in React, some Vue but no Angular so I would vote for Preact, although with React you get the advantage of using React libs like Wagmi which abstracts a lot of things that we manually had to develop like connecting to wallet, managing network changes, managing wallet changes, type-safe ABI access

gentlementlegen commented 1 month ago

But all of this is already implemented in https://nextjs.org/ :)

Im not against using a framework, I think it is a good idea, but not because it will make code perfect.

Of course not, someone who wants to make a mess will always find a way. But that would set a strong guardrail (e.g. in Next if you misplace / misname an error is yielded right away).

The major issue I encountered when I tried to work in pay.ubq.fi was to understand the global structure, because the DOM is manipulated here and there, the eventListeners also get changed everywhere, or in ubq.fi finding out the structure of the URLs. These are things you understand at a glance with a framework because they would always be the same. Basically when you're one person doing the website it's clear in your head and you follow your own rules, but it is not so great for collaborating in my opinion, and it seems to be a general feeling given this conversation.

I'd also vote for something React based as it is the most popular, so with a higher chance to find devs with xp in it. Preact is nice and lightweight,Next would offer very convenient features for our case like being able to store our secrets directly in the frontend for permit generation with full access to Node at runtime (and file based routing rocks!), plus I am sure there are many other cool frameworks out there. It would also very likely simplify testing because elements could be virtualized individually, and plenty of other benefits. Cloudflare has support for these major frameworks so the deployment should be straightforward:

zugdev commented 1 month ago

Can rebuild all websites in a framework very fast tbh. Also I'd love to know if we are in fact getting a framework before I write DOM for uusd.ubq.fi. Currently I am laying the backend there.

0x4007 commented 1 month ago

I’ve been considering writing occasional team memos to highlight org priorities and clarify my stance on certain decisions.

We don’t have active partners using our system yet, which allows us to iterate quickly without worrying about backward compatibility, stability etc. My focus is on building tools and processes that maximize our development velocity in a sustainable way.

On frameworks: they should only be used if they’re widely popular to attract more contributors. But right now, we’re in an active R&D phase, so maintaining flexibility is key. Frameworks reduce flexibility in exchange for maintainability, which makes sense for mature projects like pay.ubq.fi, but not for new initiatives.

Instead, we should create almost like "disposable" UIs—one-offs with minimal boilerplate, each serving a specific purpose with its own repository. A single framework wouldn’t be optimal for every special-purpose tool.

I know @0x4007 prefers bare TypeScript, which works for small projects. But as @rndquu mentioned, managing rules with many contributors is difficult.

Rather than enforcing a framework, we should break new responsibilities into separate repositories that deploy automatically to unique subdomains, linked for a seamless user experience. As our tools mature, we can introduce frameworks and testing.

We still have caching issues with work.ubq.fi that a framework would fix.

These have been resolved after simplifying the data model to load devpool-issues.json.

We should keep single responsibility in mind and have someone dedicated to each repo to ensure quality.

This is challenging due to our ongoing R&D and the number of low-context contributors, but periodic refactors from trusted contributors (like you) would be useful. As a side note: in order to handle this in a more continuous, "UbiquityOS way": https://github.com/ubiquity-os/plugins-wishlist/issues/33

A good addition to the template could be on-load.ts and listeners.ts files for easier review and state management.

Interesting idea. I’d like to see a demo implementation to provide feedback.

Moving “mint gift card” features to a separate repo makes sense.

I agree. It doubled the complexity of the pay.ubq.fi codebase, so splitting it into card.ubq.fi is a good idea.

In conclusion, the only codebase that might need a framework now is pay.ubq.fi, which is our most mature project. Historically, enforcing React in uad.ubq.fi slowed development significantly. For new tools, breaking off into dedicated repos is preferable to adopting a UI framework too early.

zugdev commented 1 month ago

But right now, we’re in an active R&D phase, so maintaining flexibility is key. Frameworks reduce flexibility in exchange for maintainability, which makes sense for mature projects like pay.ubq.fi, but not for new initiatives.

This is right.

A good addition to the template could be on-load.ts and listeners.ts files for easier review and state management.

Interesting idea. I’d like to see a demo implementation to provide feedback.

I will do that in uusd.ubq.fi, so you can see it from a brand new repo.