Skip to content

TCA-505 reduce js bundle size #335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,36 @@ These routes then need to be added to the routes file for the parent tools/utils
Simply adding the routes to one of thes files above will register the tool/util
with the application and will display the new component.

### Lazy loading and code splitting

When loading a route component, please use the `lazyLoad()` method defined in the application lib.

| param | description|
| ----- | ---------- |
| `moduleImport: () => Promise<any>` | Function which imports the desired module |
| `namedExport?: string` | The name of the exported module (if the module has named exports) |

Eg:
```
// Lazy load the WelcomePage component
const WelcomePage: LazyLoadedComponent = lazyLoad(() => import('./welcome'), 'WelcomePage')
...
// Use the component as route element
export const learnRoutes: Array<PlatformRoute> = [
{
children: [
{
children: [],
element: <WelcomePage />,
...
},
...
]
}
]
```


### Platform Route

The PlatformRoute model has several useful options:
Expand Down
1 change: 1 addition & 0 deletions src-ts/lib/route-provider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './platform-route.model'
export * from './route-context-data.model'
export { default as routeContext } from './route.context'
export * from './route.provider'
export * from './router.utils'
10 changes: 7 additions & 3 deletions src-ts/lib/route-provider/route.provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import {
ReactElement,
ReactNode,
SetStateAction,
Suspense,
useContext,
useEffect,
useState,
} from 'react'
import { Location, Route, useLocation } from 'react-router-dom'

import { authUrlLogin } from '../functions'
import { LoadingSpinner } from '../loading-spinner'
import { profileContext, ProfileContextData } from '../profile-provider'

import { PlatformRoute } from './platform-route.model'
Expand Down Expand Up @@ -154,9 +156,11 @@ export const RouteProvider: FC<RouteProviderProps> = (props: RouteProviderProps)
])

return (
<routeContext.Provider value={routeContextData}>
{props.children}
</routeContext.Provider>
<Suspense fallback={<LoadingSpinner />}>
<routeContext.Provider value={routeContextData}>
{props.children}
</routeContext.Provider>
</Suspense>
)
}

Expand Down
18 changes: 18 additions & 0 deletions src-ts/lib/route-provider/router.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { get } from 'lodash'
import { ComponentType, lazy, LazyExoticComponent } from 'react'

export type LazyLoadedComponent = LazyExoticComponent<ComponentType<any>>

export type LazyLoadType = (
moduleImport: () => Promise<any>,
namedExport?: string
) => LazyLoadedComponent

/**
* Utility wrapper around react's `lazy` method,
* it allows importing default and named exports from modules using the same unique method
* (while react's `lazy` method only allows to import default exports)
*/
export const lazyLoad: LazyLoadType = (moduleImport: () => Promise<any>, namedExport: string = 'default') => (
lazy(() => moduleImport().then(m => ({default: get(m, namedExport)})))
)
2 changes: 1 addition & 1 deletion src-ts/tools/dev-center/DevCenter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
RouteContextData,
} from '../../lib'

export const toolTitle: string = 'Dev Center'
import { toolTitle } from './dev-center.routes'

const DevCenter: FC<{}> = () => {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Breadcrumb, BreadcrumbItemModel, ContentLayout } from '../../../../../l
import useMarkdown from '../../../dev-center-lib/hooks/useMarkdown'
import MarkdownDoc from '../../../dev-center-lib/MarkdownDoc'
import LayoutDocHeader from '../../../dev-center-lib/MarkdownDoc/LayoutDocHeader'
import { toolTitle } from '../../../DevCenter'
import { toolTitle } from '../../../dev-center.routes'

import gettingStartedGuide from './GettingStartedGuide.md'
import styles from './GettingStartedGuide.module.scss'
Expand Down
10 changes: 6 additions & 4 deletions src-ts/tools/dev-center/dev-center.routes.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { PlatformRoute } from '../../lib'
import { lazyLoad, LazyLoadedComponent, PlatformRoute } from '../../lib'

import GettingStartedGuide from './dev-center-pages/community-app/getting-started/GettingStartedGuide'
import DevCenterLandingPage from './dev-center-pages/community-app/landing-page/DevCenterLandingPage'
import DevCenter, { toolTitle } from './DevCenter'
const GettingStartedGuide: LazyLoadedComponent = lazyLoad(() => import('./dev-center-pages/community-app/getting-started/GettingStartedGuide'))
const DevCenterLandingPage: LazyLoadedComponent = lazyLoad(() => import('./dev-center-pages/community-app/landing-page/DevCenterLandingPage'))
const DevCenter: LazyLoadedComponent = lazyLoad(() => import('./DevCenter'))

export const toolTitle: string = 'Dev Center'

export const devCenterRoutes: Array<PlatformRoute> = [
{
Expand Down
12 changes: 7 additions & 5 deletions src-ts/tools/gamification-admin/gamification-admin.routes.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { PlatformRoute, UserRole } from '../../lib'
import { lazyLoad, LazyLoadedComponent, PlatformRoute, UserRole } from '../../lib'

import GamificationAdmin, { toolTitle } from './GamificationAdmin'
import BadgeDetailPage from './pages/badge-detail/BadgeDetailPage'
import BadgeListingPage from './pages/badge-listing/BadgeListingPage'
import CreateBadgePage from './pages/create-badge/CreateBadgePage'
import { toolTitle } from './GamificationAdmin'

const GamificationAdmin: LazyLoadedComponent = lazyLoad(() => import('./GamificationAdmin'))
const BadgeDetailPage: LazyLoadedComponent = lazyLoad(() => import('./pages/badge-detail/BadgeDetailPage'))
const BadgeListingPage: LazyLoadedComponent = lazyLoad(() => import('./pages/badge-listing/BadgeListingPage'))
const CreateBadgePage: LazyLoadedComponent = lazyLoad(() => import('./pages/create-badge/CreateBadgePage'))

export const baseDetailPath: string = '/badge-detail'
export const createBadgePath: string = '/create-badge'
Expand Down
21 changes: 12 additions & 9 deletions src-ts/tools/learn/learn.routes.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { authUrlLogin, PlatformRoute } from '../../lib'
import { authUrlLogin, lazyLoad, LazyLoadedComponent, PlatformRoute } from '../../lib'

import { MyCertificate, UserCertificate } from './course-certificate'
import { CourseCompletedPage } from './course-completed'
import { CourseDetailsPage } from './course-details'
import { FreeCodeCamp } from './free-code-camp'
import { default as Learn, toolTitle } from './Learn'
import { toolTitle } from './Learn'
import { LearnConfig } from './learn-config'
import { MyLearning } from './my-learning'
import { WelcomePage } from './welcome'

const WelcomePage: LazyLoadedComponent = lazyLoad(() => import('./welcome'), 'WelcomePage')
const CourseDetailsPage: LazyLoadedComponent = lazyLoad(() => import('./course-details'), 'CourseDetailsPage')
const CourseCompletedPage: LazyLoadedComponent = lazyLoad(() => import('./course-completed/'), 'CourseCompletedPage')
const MyCertificate: LazyLoadedComponent = lazyLoad(() => import('./course-certificate'), 'MyCertificate')
const UserCertificate: LazyLoadedComponent = lazyLoad(() => import('./course-certificate'), 'UserCertificate')
const FreeCodeCamp: LazyLoadedComponent = lazyLoad(() => import('./free-code-camp'), 'FreeCodeCamp')
const MyLearning: LazyLoadedComponent = lazyLoad(() => import('./my-learning'), 'MyLearning')
const LandingLearn: LazyLoadedComponent = lazyLoad(() => import('./Learn'))

export enum LEARN_PATHS {
certificate = '/certificate',
Expand Down Expand Up @@ -112,7 +115,7 @@ export const learnRoutes: Array<PlatformRoute> = [
title: 'My Learning',
},
],
element: <Learn />,
element: <LandingLearn />,
memberOnly: true,
route: rootRoute,
title: toolTitle,
Expand Down
26 changes: 13 additions & 13 deletions src-ts/tools/work/work.routes.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
import { Navigate } from 'react-router-dom'

import { contactSupportPath, PlatformRoute } from '../../lib'
import { contactSupportPath, lazyLoad, LazyLoadedComponent, PlatformRoute } from '../../lib'

import { dashboardTitle, default as WorkComponent, toolTitle } from './Work'
import { dashboardTitle, toolTitle } from './Work'
import { Work, WorkIntakeFormRoutes, WorkStatus, WorkType } from './work-lib'
import { WorkLoginPrompt } from './work-login-prompt'
import { WorkNotLoggedIn } from './work-not-logged-in'
import {
BugHuntIntakeForm,
IntakeForms,
intakeFormsTitle,
Review,
} from './work-self-service'
import SaveAfterLogin from './work-self-service/intake-forms/save-after-login/SaveAfterLogin'
import { WorkTable } from './work-table'
import { WorkThankYou } from './work-thank-you'
import { intakeFormsTitle } from './work-self-service'

const WorkComponent: LazyLoadedComponent = lazyLoad(() => import('./Work'))
const WorkNotLoggedIn: LazyLoadedComponent = lazyLoad(() => import('./work-not-logged-in'), 'WorkNotLoggedIn')
const BugHuntIntakeForm: LazyLoadedComponent = lazyLoad(() => import('./work-self-service'), 'BugHuntIntakeForm')
const IntakeForms: LazyLoadedComponent = lazyLoad(() => import('./work-self-service'), 'IntakeForms')
const Review: LazyLoadedComponent = lazyLoad(() => import('./work-self-service'), 'Review')
const SaveAfterLogin: LazyLoadedComponent = lazyLoad(() => import('./work-self-service/intake-forms/save-after-login/SaveAfterLogin'))
const WorkTable: LazyLoadedComponent = lazyLoad(() => import('./work-table'), 'WorkTable')
const WorkThankYou: LazyLoadedComponent = lazyLoad(() => import('./work-thank-you'), 'WorkThankYou')

export const rootRoute: string = '/work'
export const selfServiceRootRoute: string = '/self-service'
export const selfServiceStartRoute: string = `${selfServiceRootRoute}/wizard`
export const dashboardRoute: string = `${rootRoute}/dashboard`

export function workDashboardRoute(active: string): string {
return `${dashboardRoute}/${active}`
return `${dashboardRoute}/${active}`
}

export function workDetailOrDraftRoute(selectedWork: Work): string {
Expand Down
2 changes: 1 addition & 1 deletion src-ts/utils/contact-support/ContactSupport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
formOnReset
} from '../../lib'

export const toolTitle: string = 'Contact Support'
import { toolTitle } from './contact-support.routes'

const ContactSupport: FC<{}> = () => {

Expand Down
6 changes: 4 additions & 2 deletions src-ts/utils/contact-support/contact-support.routes.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { contactSupportPath, PlatformRoute } from '../../lib'
import { contactSupportPath, lazyLoad, LazyLoadedComponent, PlatformRoute } from '../../lib'

import { default as ContactSupport, toolTitle } from './ContactSupport'
export const toolTitle: string = 'Contact Support'

const ContactSupport: LazyLoadedComponent = lazyLoad(() => import('./ContactSupport'))

export const contactSupportRoutes: Array<PlatformRoute> = [
{
Expand Down
4 changes: 2 additions & 2 deletions src-ts/utils/home/home.routes.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PlatformRoute } from '../../lib'
import { lazyLoad, LazyLoadedComponent, PlatformRoute } from '../../lib'

import { default as Home } from './Home'
const Home: LazyLoadedComponent = lazyLoad(() => import('./Home'))

export const homeRoute: string = ''

Expand Down
6 changes: 3 additions & 3 deletions src-ts/utils/settings/settings.routes.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ToolTitle } from '../../config'
import { PlatformRoute } from '../../lib'
import { lazyLoad, LazyLoadedComponent, PlatformRoute } from '../../lib'

import { Account } from './account'
import Settings from './Settings'
const Account: LazyLoadedComponent = lazyLoad(() => import('./account'), 'Account')
const Settings: LazyLoadedComponent = lazyLoad(() => import('./Settings'))

export const settingsRoutes: Array<PlatformRoute> = [
{
Expand Down
31 changes: 18 additions & 13 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import "react-responsive-modal/styles.css";
import { profileContext } from "../src-ts";

import { UNDER_MAINTENANCE } from "./constants";
import IntakeForm from "./IntakeForm";
import WorkItem from "./routes/WorkItems";
import { ScrollToTop } from "./ScrollToTop";
import styles from "./styles/main.module.scss";
import UnderMaintenance from "./routes/UnderMaintenance";
import { lazyLoad, LoadingSpinner } from "../src-ts/lib";
import { Suspense } from "react";

const WorkItem = lazyLoad(() => import("./routes/WorkItems"));
const IntakeForm = lazyLoad(() => import("./IntakeForm"));
const UnderMaintenance = lazyLoad(() => import("./routes/UnderMaintenance"));


const App = () => {
Expand Down Expand Up @@ -40,16 +43,18 @@ const App = () => {
return (
<div className={styles["topcoder-platform-ui"]}>
<ScrollToTop path="/">
<Routes>
<Route
element={<IntakeForm />}
path="/self-service/*"
/>
<Route
element={<WorkItem />}
path="/self-service/work-items/:workItemId"
/>
</Routes>
<Suspense fallback={<LoadingSpinner />}>
<Routes>
<Route
element={<IntakeForm />}
path="/self-service/*"
/>
<Route
element={<WorkItem />}
path="/self-service/work-items/:workItemId"
/>
</Routes>
</Suspense>
</ScrollToTop>
</div >
);
Expand Down