Road to SPA
See original GitHub issueOverview
Currently, views are built with Template Engine (Swig), jQuery and React. I propose migrating to SPA based on component orientation to achieve better user experience and development experience.
Why
Because I want to eliminate the waste of communication with the back-end and rendering at the time of page transition for migrating to SPA as a modern front-end application that runs at high speed.
Implementation flow
Let rendering responsibilities come near the front-end
First, rewrite templates written in Swig to React components with appropriate granularity. If the target depends on jQuery, it also rewrites to React component. From now on, React components create in Functional Component, define types in TypeScript, and define styles in styled-components.
Front-end holds global state
Adopt Redux to manage global state at front-end. After being injected into HTML from back-end, the state managed by the Crowi instance, etc. will be managed by Redux at this point.
Recently, react-redux supported the hooks API in React v 7.1.0. Adopt react-redux@v7.1.0 to connect to Store using hooks.
https://github.com/reduxjs/react-redux/releases/tag/v7.1.0
Front-end responsible for page routing and rendering
Introduce React Router and route components on front-end. As a result, back-end has API, static file, fallback to SPA routing definitions only, and front-end is responsible for page routing.
In addition, global level state is not injected from back-end because the browser does not cause page transition. At this point, all Swig templates are not present in back-end, and front-end is responsible for rendering the page. Furthermore, almost all styles are migrated from SCSS to styled-components by componentizing even top-level elements.
Tasks
- Introduce and migrate to TypeScript (@lightnet328, @otofune) (https://github.com/crowi/crowi/pull/402, https://github.com/crowi/crowi/pull/486)
- Upgrade React to v16.8 (@lightnet328) (https://github.com/crowi/crowi/pull/420)
- To be able to use Hooks
- Introduce styled-components (@lightnet328) (https://github.com/crowi/crowi/pull/538)
- Make Swig templates to React components
- Page creation modal (@saitoeku3) (https://github.com/crowi/crowi/pull/606)
- Page deletion modal (@saitoeku3) (https://github.com/crowi/crowi/pull/650)
- Help modal
- Page name tips modal
- Portalization modal
- Page name change modal
- Unportalization modal
- Sign in / Sign up modal
- What is a portal (@okonomi) (https://github.com/crowi/crowi/pull/604)
- User page
- Installer page
- Presentation page
- Invitation page
- User settings page
- External share pages (@lightnet328)
- Admin pages (@lightnet328) (https://github.com/crowi/crowi/pull/423)
- Comments (@lightnet328) (https://github.com/crowi/crowi/pull/424)
- Page edit page (Editor) (@sotarok)
- Introduce
react-helmet
- Introduce react-redux@v7.1.0
- Migrate existing the global state to Redux
- Manage state related to auth
- Manage state related to search
- Introduce React Router
- Route on front-end
- User page
- List / Portal page
- Page
- Shared page
- Bookmark page
- Recent created page list page
- Search result page
- Installer page
- Presentation page
- Invitation page
- User settings page
- Sign in / Sign up page
- Admin pages
- Page edit page (Editor)
Contributing
I created this proposal to more people be able to participate in the discussion and implementation by writing down and publish the specification and implementation flow before implementing a architecture or function that requires bold changes.
Please provide review or feedback on this proposal in this Issue comment. I look forward to your contribution🙏
Japanese
概要
現在のCrowiのビューはTemplate Engine (Swig)とjQueryとReactで構築されています。 より良いユーザー体験と開発体験を実現するためにコンポーネント指向に基づいてSPAに移行することを提案します。
何故やるか
ページ遷移時の通信やレンダリングの無駄を無くし、高速に動作するモダンフロントエンドアプリケーションとして実装をSPAに移行していきたいから。
実装の流れ
レンダリングの責務をフロントエンドに寄せる
まず、Swig で書かれたテンプレートを適切な粒度でReact コンポーネントに書き換えます。 書き換えた対象がjQueryに依存されていた場合はjQueryのコードもReact コンポーネントに書き換えます。 これから作成するReact コンポーネントはFunctional Componentで作成し、型をTypeScriptで、スタイルをstyled-componentsで定義します。
フロントエンドがグローバルレベルの状態を保持する
フロントエンドでグローバルレベルの状態を管理するためにReduxを採用します。 バックエンドからHTMLに注入された後、Crowiインスタンスなどで管理されていた状態はこの時点でReduxで管理されるようになります。
最近、react-reduxはReactのv7.1.0でhooks APIをサポートしました。 hooksを使ってStoreに接続するために、react-redux@v7.1.0を採用します。
https://github.com/reduxjs/react-redux/releases/tag/v7.1.0
フロントエンドがページのルーティングとレンダリングの責務を持つ
React Routerを導入し、フロントエンドでコンポーネントのルーティングを行います。 結果として、バックエンドはAPI、静的ファイル、SPAへのフォールバックのルーティングのみの定義を持ち、、フロントエンドがページのルーティングの責務を持つようになります。
また、ブラウザによるページ遷移が発生しなくなるため、グローバルレベルのステートはバックエンドから注入されなくなります。 この時点で、全てのSwig テンプレートはバックエンドに存在しなくなり、フロントエンドがページのレンダリングの責任を持つようになります。 更に、トップレベルの要素までがコンポーネント化されることで、ほぼ全てのスタイルがSCSSからstyled-componentsに移行されます。
タスク
- TypeScript の導入と移行 (@lightnet328, @otofune) (https://github.com/crowi/crowi/pull/402, https://github.com/crowi/crowi/pull/486)
- React 16.8 の導入 (@lightnet328) (https://github.com/crowi/crowi/pull/420)
- Hooks を使用できるようにするため
- styled-components の導入 (@lightnet328) (https://github.com/crowi/crowi/pull/538)
- Swig テンプレートのReact コンポーネント化
- ページ作成モーダル (@saitoeku3) (https://github.com/crowi/crowi/pull/606)
- ページ削除モーダル
- ヘルプモーダル
- ページ名に関するヒント
- ポータル化モーダル
- ページ名変更モーダル
- ポータル解除モーダル
- ログイン/新規登録ページ
- ポータルとは (@okonomi) (https://github.com/crowi/crowi/pull/604)
- ユーザーページ
- インストーラー
- プレゼンテーション
- 招待ページ
- ユーザー設定ページ
- 外部共有ページ (@lightnet328)
- 管理者ページ (@lightnet328)
- ページ編集ページ (Editor)
- react-redux@v7.1.0の導入
- 既に持っているグローバルレベルの状態を Redux で管理する
- 認証の状態管理
- 検索の状態管理
- React Router の導入
- フロントエンドでルーティングする
- ユーザーページ
- リストページ・ポータル
- ページ
- 共有されたページ
- ブックマークページ
- 最近作成したページ
- 検索結果ページ
- インストーラー
- プレゼンテーションページ
- 招待ページ
- ユーザー設定ページ
- ログイン・新規登録ページ
- 管理ページ (@lightnet328) (https://github.com/crowi/crowi/pull/423)
- コメント (@lightnet328) (https://github.com/crowi/crowi/pull/424)
- ページ編集ページ (Editor) (@sotarok)
貢献する
大胆な変更を要する機構や機能を実装する前にその仕様と実装の流れを書き下してオープンにすることでより多くの人が議論や実装に加われるようにするために、この提案を作成しました。 この提案に対する意見をこのIssueのコメントで教えてください。あなたの貢献をお待ちしています🙏
Issue Analytics
- State:
- Created 4 years ago
- Reactions:10
- Comments:13 (13 by maintainers)
Top GitHub Comments
Implementation guideline for migrating to React components
Since not all of the existing codes are implemented with the same policy, I’d like to show you the basic policy here.
Basic policy
FYI
May I take
Page creation modal
?