Skip to content

Frontend Plan #17149

Closed
Closed
@wxiaoguang

Description

Background

The frontend needs a big refactor now.

  1. web_src/index.js is too big to add new code (or modify/debug).
  2. code doesn't do what it should do, eg: initVueApp/initVueComponents is quite misleading
  3. Vue/fomantic/jQuery are mixed together, and we may need JSX Enable JSX support in frontend #15293
  4. no easy way to pass complex data structure from backend to frontend. eg: code like var ActivityTopAuthors = {{Json .ActivityTopAuthors | SafeJS}}; is not a good idea.
  5. difficult to shared data between modules, eg: how can different frontend modules get current issue index?
    <!-- I know, there is probably a better way to do this -->
  6. the dependency and coupling are not clear, many frontend code work like if ( $('.xxx').length == 0) return; , we do not know what pages need this function, and these css class names may conflict. A little change may break something.
  7. many events are attached to document, they may conflict. Add namespace to global click event #16833
  8. some problems should be resolved by framework: Prevent double click new issue/pull/comment button #16157 , Click buttons quickly in some forms will submit repeated/duplicated requests #17111

Guideline

  1. Every feature should be put in separated files/directories.
  2. HTML id/css-class-name should use kebab-case.
  3. HTML id/css-class-name used by JavaScript top-level selector should be unique in whole project, and should contain feature related keywords.
  4. jQuery events across different features should use their own namespaces.

Plan

What frontend frameworks should be used?

  • fomantic will stay as long as possible. And MVC is SEO friendly.
  • jQuery is a part of fomantic.
  • Vue is already used, so we can continue to use it, but we should upgrade it to Vue3 and do a refactor. Vue3 is handy to implement complex UI.
  • JSX is nice to have and it works well with Vue3. But we do not choose it now (according to the discussions)
  • ReactJS or other MVVM? I think it doesn't make big difference from Vue3 in this project, however if we drop Vue then we must migrate many components, not worthy.

I prefer fomantic + Vue3

How to pass backend data to frontend?

  • For simple data, it can be put into HTML data-xxx tag during template rendering

  • For complex data like array/map, it can be put into window.config.pageData.xxx. We write some common code to render pageData into JSON automatically in base template:

<script>
window.config.pageData = {{ .PageData }}
</script>

Then backend work will be easy:

ctx.PageData["xxx"] = someMap

How to init frontend functions in a page?

We have two choices (I prefer keep and improve current mechanism)

Frontend functions depned on templates

It is the mechanism what we are using now. In index.js it calls every init function, every init function checks whehter current page has some DOM elements. If current page has the matched DOM elements, then the feature will be loaded.

Pros:

  • Simple, it doesn't change much with current mechanism

Cons:

  • init functions can not have arguments
  • There will be tens of init functions calls in index.js (maybe more than a hundred soon?)

Templates call frontend init functions

index.js exports init functions. Templates render scripts in HTML like this:

<script>
window.config.ready(function($gitea)) {
    $gitea.initIssueList();
    $gitea.initUserList(extraData);
}
</script>

When the page is loaded, index.js calls every function registered by window.config.ready.

Pros:

  • It saves init time because only necessary functions are called.
  • Flexible, template code can do more things when JavaScript modules are ready.

Cons:

  • Order/dependency problem?
  • Some init functions can only be called once while others are called many times?

Other suggestions?

TODO

Refactor Steps

  1. (DONE) Complete a formal frontend guideline document in docs/content/doc/developers/frontend.md. The guideline can come from this draft.

  2. (DONE) Split web_src/index.js into small files in web_src/features/. Add function calls to initXxx in index.js as before. This step can be done ASAP, and must be reviewed and approved quickly to prevent from further conflicts. Any new feature should be placed in web_src/features/ later.

  3. (DONE) Introduce a common mechanism to pass backend data to frontend. eg: window.config.pageData.

  4. (keep current mechanism) Introduce or improve a common mechanism to call page related init functions.

  5. [FUTURE] Upgrade Vue from 2 to 3.

  6. [DONE] If a change is made to legacy frontend code, the author should also follow the guideline to refactor related modules.

  7. [FUTURE] Implement common and reusable code to resolve legacy frontend issues.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    topic/ui-interactionChange the process how users use Gitea instead of the visual appearancetype/proposalThe new feature has not been accepted yet but needs to be discussed first.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions