jellyfin / jellyfin-web

Web Client for Jellyfin
https://jellyfin.org
GNU General Public License v2.0
2.27k stars 1.2k forks source link

Migrate to a new framework #889

Closed dkanada closed 3 years ago

dkanada commented 4 years ago

We plan on modernizing the code here, which involves choosing a new framework. The only hard requirement is supporting incremental migrations, since we don't plan on migrating the entire codebase at once.

If you have a suggestion, add a comment below containing only the name of the library. An upvote means you would enjoy moving to that framework and a downvote means you would hate the framework. If you have no opinion don't add anything, and please avoid any other reactions on the suggestions themselves. Comments about your opinions are welcome!

cromefire commented 4 years ago

Another big requirement we have is that we need to migrate everything in-place. I spent about 20 minutes searching Google for this for each of the three frameworks. I couldn't find anything about what that process would look like for Angular. All I can find are posts talking about moving from AngularJS to Angular, moving to TypeScript or upgrading your Angular version, but nothing about how to handle moving from straight JavaScript to Angular.

If anyone has good articles about migrating Angular in-place, feel free to send them, I'm interested.

It's rather hard, because of all the shell angular gives you. It defines pretty clear structures and best practices, which makes it pretty hard to migrate in place, because so may components are working hand-in-hand with other components. A point that could work would be the angular custom elements integration (that works both ways, so you can include custom elements and also provide it as a custom element).

Overall, I also notice in the stats that the Angular package is less used on NPM, has fewer stars, fewer forks and yet more open issues than React or Vue. This suggests bad issue triage, lower support, more problems, etc (I emphasize "suggests", because there's no real way to know for sure, but such a large difference is concerning).

The angular repo is a monorepo with a bunch of more components than just @angular/core. As far as I've experienced it they're quite fast at resolving issues. (It provides framework, compiler, router, testing, ...)

cromefire commented 4 years ago

Angular is more of a "do it once, do it right" (batteries included), than a kind of patchwork like react or vue.

heyhippari commented 4 years ago

Angular is more of a "do it once, do it right" (batteries included), than a kind of patchwork like react or vue.

But then that's another issue, in my opinion. Because what if "the Angular way" isn't what we want? Then we don't have the option of switching that part to something else.

Angular being monolithic makes me want to use it less, honestly.

cromefire commented 4 years ago

Well you can always do things differently as with almost any framework, but there's often just an easy solution included

frogcrush commented 4 years ago

What about Blazor client-side? Could benefit from code reuse as it uses C#, and you can serve it as static files (server not required to change).

ThibaultNocchi commented 4 years ago

@frogcrush I'm not too sure about the existence of any client relevant code in C#. Moreover, modern frameworks support distributing files without any server needed. Lastly, I'd argue that those working on the web client aren't the same as those on the server, thus not having the same knowledge of C# as JS & co (but that's just my naive opinion).

frogcrush commented 4 years ago

@frogcrush I'm not too sure about the existence of any client relevant code in C#. Moreover, modern frameworks support distributing files without any server needed. Lastly, I'd argue that those working on the web client aren't the same as those on the server, thus not having the same knowledge of C# as JS & co (but that's just my naive opinion).

Ohoho, there is indeed. For client-side Blazor, no server is required. You serve it as static files like any other PWA. You could (and people do) run it on Github Pages.

Alternatively, you can use server-side Blazor. This is what people use for things like Electron where you're already running a stack. The nice thing is you can do both without and code changes. Since they're both running a version of the dotnet standard.

Also, I don't really view the syntax as very different than something like React; I would argue that to write Blazor you don't have to know C#. You can still interop back and forth with JavaScript, but you have the power of full dotnet available as well.

heyhippari commented 4 years ago

Seems like it either requires a C# server or WebAssembly, which is a no go since we require support for some old and crusty browsers (Afaik, we support back to Chrome 27, due to Smart TVs).

Plus I'd rather refrain from making this spaghetti mess even more complex by adding yet another piece to the puzzle.

Not to mention that most of the contributors to this repository are JS devs first and foremost. We have a lack of C# devs for the server, compared to here and it feels like changing the language of the web client would drive a lot of contributors away.

ThibaultNocchi commented 4 years ago

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

frogcrush commented 4 years ago

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

Windows is more popular than Linux. Does that mean that everyone should just use Windows, since obviously Linux has no use cases where it could make sense?

cromefire commented 4 years ago

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

And are way more appealing for JS devs

ghost commented 4 years ago

I think we should consider to use https://www.nativescript.org/ to build iOS and Android from the same code that we will use for new web (maybe angular 9 or react)

ThibaultNocchi commented 4 years ago

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

Windows is more popular than Linux. Does that mean that everyone should just use Windows, since obviously Linux has no use cases where it could make sense?

Comparing web frameworks to operating systems is quite far-fetched. From a development point of view, the popularity of a tool among developers defines what type of support we can have, how many libraries we could use and how many knowledgeable contributors we could get.

Finally, I don't dismiss the fact that your framework has its qualities but I was just skeptical about the arguments you've made. You've said we could reuse C# code, and frankly I don't know that much about the project's structure, but if you could point me to where there is C# client code, I'd be appreciative. Also, you're free to clarify why is Blazor a more suitable framework (notably due to its PWA capabilities) and why would Jellyfin use PWA client applications.

cromefire commented 4 years ago

@frogcrush Again, Vue, Angular, React and others do support PWA and are way more popular than Blazor.

Windows is more popular than Linux. Does that mean that everyone should just use Windows, since obviously Linux has no use cases where it could make sense?

Comparing web frameworks to operating systems is quite far-fetched. From a development point of view, the popularity of a tool among developers defines what type of support we can have, how many libraries we could use and how many knowledgeable contributors we could get.

Finally, I don't dismiss the fact that your framework has its qualities but I was just skeptical about the arguments you've made. You've said we could reuse C# code, and frankly I don't know that much about the project's structure, but if you could point me to where there is C# client code, I'd be appreciative. Also, you're free to clarify why is Blazor a more suitable framework (notably due to its PWA capabilities) and why would Jellyfin use PWA client applications.

Well on the PWA part I'm on board, but as that also supported by all other frameworks, that not quite a selling point

ThibaultNocchi commented 4 years ago

If I correctly understand PWA, it should let us easily make a cross compatible app for web / iOS / Android / etc. ? And also I've seen it can help caching stuff on the device, maybe offline use of Jellyfin?

cromefire commented 4 years ago

Yes all of it, but it's of course more constrained than a native app. Also iOS support is really bad (although I heard I got improved in the latest update)

cromefire commented 4 years ago

And the caching part is relatively separate from the PWA, although some browsers require it to install the PWA. (It's called service workers)

ThibaultNocchi commented 4 years ago

Do you mean iOS support of PWA or simply local storage? In any case it's another thing to take into account when choosing between PWA, SPA or SSR (is there anything else by the way?).

cromefire commented 4 years ago

iOS just supports the PWA part poorly. I don't understand your second sentence, you're just throwing unrelated terms around.

swillis12 commented 4 years ago

Not sure if this was mentioned before, but looks promising if targeting web and mobile: https://flutter.dev/

cromefire commented 4 years ago

I think it's not mentioned here yet, but the problem with it is, it's not really a webframework, it renders the app frame by frame and paints it on a canvas. That not a really good web experience I think

ThibaultNocchi commented 4 years ago

iOS just supports the PWA part poorly. I don't understand your second sentence, you're just throwing unrelated terms around.

I'm not too knowledgeable about these, but I thought making an SPA application wasn't the same as a PWA? And SSR means Server Side Rendering, isn't it the opposite of a SPA?

Not sure if this was mentioned before, but looks promising if targeting web and mobile: https://flutter.dev/

Flutter is still pretty young and I've had problems using it on both mobile platforms due to its modules being sometimes not cross-compatible.

swillis12 commented 4 years ago

I'm not too knowledgeable about these, but I thought making an SPA application wasn't the same as a PWA? And SSR means Server Side Rendering, isn't it the opposite of a SPA?

Server-side rendering just means that the server renders the HTML and then sends it to the UI. The UI will then "hydrate" the server-rendered HTML with click-events and stuff. So it can be used in a single page app or other app with multiple HTML docs.

ThibaultNocchi commented 4 years ago

Ok then we can have SSR / SPA apps or SSR / no SPA apps. Thanks!

swillis12 commented 4 years ago

Ok then we can have SSR / SPA apps or SSR / no SPA apps. Thanks!

I think SSR could be something that is added later as an optimization.

cromefire commented 4 years ago

SSR is of relatively complex, but for our use case not really needed. SPA are all of these frameworks, even the current UI. I thinks it's an absolute must have. PWA is often not related with the code, but frameworks can provide integrations.

h1nk commented 4 years ago

Being able to statically serve the entire application is really important to me. SSR seems unnecessarily complex and inefficient for what this app is trying to do.

cromefire commented 4 years ago

Well you can usually still serve ssr apps statically, but it can be really complex because of js running on the server

jonaspm commented 4 years ago

Still using SSR you can cache the entire app in the browser

cromefire commented 4 years ago

SSR and caching is totally unrelated

jonaspm commented 4 years ago

Nope. First request will return the app, but new requests will return http status code 304

swillis12 commented 4 years ago

Not projecting any preference but want to speak from my own experience choosing between Angular and React at work.

I see mention of a want/need for flexibility. After using React full-time for 2.5yrs I can say that it definitely provides the flexibility. That being said, I recommend setting up the coding guidelines as well as guidelines for state-storage so the number of competing implementation patterns is minimized. Also be careful about reading articles that came out before React Hooks API.

Use hooks API (vs Class components and this.setState) since this is the standard way to write React components. It is very good and I've found that it actually makes it hard to write bugs if you learn and use it properly: https://reactjs.org/docs/hooks-intro.html.

There is also Concurrent Mode that is a huge deal since it adds non-blocking rendering. This can make an APP a lot faster. For the most part it should just require reading the docs and following best-practices to enable it: https://reactjs.org/docs/concurrent-mode-intro.html

Side-note: with any framework, but specifically with React, be careful about articles or suggestions from others to use things without a good reason. The most popular one is "Use redux because it's good", when in reality you can do everything it does with React out of the box (context API, since hooks came out. Also redux uses this under the hood). These articles are still useful to learn design patterns (especially with the intro of the useReducer hook in React).

Agree with @cromefire , SPA is the only way to go if writing a web-app.

cromefire commented 4 years ago

You should only use service workers anyway also SSR is still totally unrelated to any response code those are controller by the webserver and not by the technique you are using

h1nk commented 4 years ago

By statically served I mean dump some bundled app assets into the web root of an nginx and call it a day.

cromefire commented 4 years ago

Yes that's possible, that's just not prerendered then, at least that's my experience with angular and (p)react

cromefire commented 4 years ago

You usually have 2 builds one for the server one for the client

sparky8251 commented 4 years ago

Fine, since this is going crazy I vote for wasm but not Blazor. Fuck Blazor, fuck Microsoft, fuck C#.

I vote for Rust+wasm. Rust has the most widespread wasm support of any language and phenomenal tooling for regular and wasm development.

No GC, minimal runtime, insane performance, massive safety guarantees, more mature wasm landscape and tooling. Rust is def the way to go with wasm.

heyhippari commented 4 years ago

I think this has veered a bit off-topic.

While we appreciate the lively discussion this topic has generated, keep in mind that this is a discussion about the framework for the web client, which is in Javascript and plans to move to TypeScript at some point in the future, and it's not about replacing Cordova or adding an Electron layer in this repository (If you want to work on a desktop version of this client, we have a repository exactly for that, which needs some love: https://github.com/jellyfin/jellyfin-theater-electron)

After some internal discussion and tally of the vote results (focusing on the regular contributors of this repository), it seems like Vue is the direction we are going in.

The next step will be finding a small, ideally self-contained, part of the client that we can rewrite as a proof of concept and a way to get the Vue pipeline in.

sparky8251 commented 4 years ago

For small and self contained component I vote once again for volume controls.

There are 3 copies of it in the code, 2 perfectly identical 1 nearly identical (its just one layer closer to the manipulated vars). It's small, yet more functional than a drop down list or the like, and it gets used a lot without being a game breaker if borked thanks to external volume control options.

It's really perfect, since it covers all the major sticking points we will come across when turning the UI slowly into components (reducing duplicate code, small, functional in more than 1 way, has options if we break it, etc). Especially the almost identical part... Emby loved to copy/paste code rather than make it into a component after all.

cromefire commented 4 years ago

Fine, since this is going crazy I vote for wasm but not Blazor. Fuck Blazor, fuck Microsoft, fuck C#.

I vote for Rust+wasm. Rust has the most widespread wasm support of any language and phenomenal tooling for regular and wasm development.

No GC, minimal runtime, insane performance, massive safety guarantees, more mature wasm landscape and tooling. Rust is def the way to go with wasm.

Rust + WASM is awesome, but it has to has it's purpose of course. For UI and communication JS it better.

heyhippari commented 4 years ago

For small and self contained component I vote once again for volume controls.

There are 3 copies of it in the code, 2 perfectly identical 1 nearly identical (its just one layer closer to the manipulated vars). It's small, yet more functional than a drop down list or the like, and it gets used a lot without being a game breaker if borked thanks to external volume control options.

It's really perfect, since it covers all the major sticking points we will come across when turning the UI slowly into components (reducing duplicate code, small, functional in more than 1 way, has options if we break it, etc). Especially the almost identical part... Emby loved to copy/paste code rather than make it into a component after all.

Thinking a bit about it, wouldn't that depend on other components? (At least a slider component)

I was thinking that some kind of indicator might be best, as these don't really use anything else and are simply plopped onto the cards.

frogcrush commented 4 years ago

I agree we got off-topic for the PWA. Only reason I mentioned it was because of an above comment; I don't think Jellyfin should be a PWA. Just not a great experience.

I still say Blazor is a good choice because you can have SSR if you want it and CSR if you don't with absolutely no change to the code. Plus, it would allow creating a cross-platform single library and set of models that can be used everywhere. Then, only UI layers would have to change between platforms (think Windows, UWP/Xbox/RPi, Xamarin for Android and iOS, Electron.NET on Macos/Linux or for most of the platforms listed before).

Having to maintain all these different code bases in different languages is annoying for developers that want to come in and fix some bugs or add some new features.

Time permitting I might put together a demo of how this would work.

inb4 "but muh JavaScript is the best thing ever"

cromefire commented 4 years ago

Well aren't enough C# devs

dkanada commented 4 years ago

We definitely have more than enough help on the frontend right now :) so no need to worry about that.

frogcrush commented 4 years ago

Well aren't enough C# devs

Maybe due to the hostility towards C#?

However, my position is one of agreeing with the person above; those who are most actively contributing should be the ones making the final decision. I don't see any need to turn this into a flame war; but I think just asking the community for opinions on a JavaScript framework will always descend into one if we're being honest.

In the end, I wish you all luck :) Maybe I'll go make a (working) theatre client for Windows...

dkanada commented 4 years ago

Maybe due to the hostility towards C#?

I am absolutely in love with C# on the backend so I'm not sure what hostility you're referencing, it's one of my favorite languages.

cromefire commented 4 years ago

In the end, I wish you all luck :) Maybe I'll go make a (working) theatre client for Windows...

There's a UWP client that is being worked on. If you want to help look here: https://matrix.to/#/!YOoxJKhsHoXZiIHyBG:matrix.org/$3FghUG6VDKT8gH4hbG37LSmojJrZZ-cTS07zNOZyB-g The green ones are C# and those with red boxes are projects that definitely need more developers. (The others are also fine to work on though)

molszanski commented 4 years ago

SPA is amazing, but overcomplicated in code. SSR is great and fast but a more PIA to host vs dumb static webserver SPAs enjoy and less "embeddable"

Extarys commented 4 years ago

If you decide to use Vue, there is a framework called Nuxt that take a lot of the "burden" out and automate a lot of things.

heyhippari commented 4 years ago

I've been playing with Vue in the current codebase for the past hour or so. Here are my findings for now:

We'll need the ES6 move to be done for it to be manageable. Mainly this is to avoid making our build system even more of a mess than it already is.

By playing a bit, I arrived essentially at this, after loading Vue via the CDN by inserting a script tag in index.html:

site.js

// We need to ignore our current custom elements, as they'll trip up Vue
Vue.config.ignoredElements = ['emby-linkbutton', 'paper-icon-button-light', 'emby-tabs', 'emby-button'];

// To avoid messing with AMD modules for now, I'm registering the component as a global object inside window
window.helloVue = Vue.component('hello-vue', {
    template: '<p>Hello, Vue!</p>'
});

// Since we're already pretty much a SPA, loading Vue globally for the whole client works.
window.app = new Vue({
    el: '#vue-wrap',
    data: {
        message: 'Hello Vue!'
    }
});

hometab.js

// Right now, components have to be instancied, mounted and inserted into DOM manually.
var ComponentClass = Vue.extend(window.helloVue);
var instance = new ComponentClass();
instance.$mount();
view.appendChild(instance.$el);

image

I managed to insert that simple hello-vue component into the home page pretty easily. There's unfortunately some annoying code due to our current structure (the manual instantiation and DOM insertion bit), but as we move more and more to Vue, this should be gradually removed.

I think we can pretty much start on this as soon as all the ES6 migration is done (which should be during the 10.7 cycle I think, unless we release early.