aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/app
diff options
context:
space:
mode:
authorStas Vilchik <stas.vilchik@sonarsource.com>2018-05-29 17:00:54 +0200
committerSonarTech <sonartech@sonarsource.com>2018-05-29 20:20:47 +0200
commit95220229b1d52f0acd4f1c0d4358e9fed610c3ee (patch)
tree37ce44f787c6a22aca324047efbe8bcb41b38689 /server/sonar-web/src/main/js/app
parent9c10956d8a65e1e3a851691d69cee367ac4e0869 (diff)
downloadsonarqube-95220229b1d52f0acd4f1c0d4358e9fed610c3ee.tar.gz
sonarqube-95220229b1d52f0acd4f1c0d4358e9fed610c3ee.zip
SONAR-10675 Decrease JavaScript boot-up time (#283)
Diffstat (limited to 'server/sonar-web/src/main/js/app')
-rw-r--r--server/sonar-web/src/main/js/app/components/AdminContainer.tsx27
-rw-r--r--server/sonar-web/src/main/js/app/components/GlobalFooterSonarCloud.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/__tests__/GlobalFooterSonarCloud-test.tsx4
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx4
-rw-r--r--server/sonar-web/src/main/js/app/utils/startReactApp.js85
5 files changed, 78 insertions, 44 deletions
diff --git a/server/sonar-web/src/main/js/app/components/AdminContainer.tsx b/server/sonar-web/src/main/js/app/components/AdminContainer.tsx
index 20284555423..c81e450022d 100644
--- a/server/sonar-web/src/main/js/app/components/AdminContainer.tsx
+++ b/server/sonar-web/src/main/js/app/components/AdminContainer.tsx
@@ -41,23 +41,29 @@ import { Extension } from '../types';
import { PluginPendingResult } from '../../api/plugins';
import handleRequiredAuthorization from '../utils/handleRequiredAuthorization';
-interface Props {
+interface StateProps {
appState: {
adminPages: Extension[];
organizationsEnabled: boolean;
version: string;
};
- editionsUrl: string;
editionStatus?: EditionStatus;
+ editionsUrl: string;
+ pendingPlugins: PluginPendingResult;
+}
+
+interface DispatchProps {
fetchEditions: (url: string, version: string) => void;
fetchPendingPlugins: () => void;
- location: {};
- pendingPlugins: PluginPendingResult;
setAdminPages: (adminPages: Extension[]) => void;
setEditionStatus: (editionStatus: EditionStatus) => void;
}
-class AdminContainer extends React.PureComponent<Props> {
+interface OwnProps {
+ location: {};
+}
+
+class AdminContainer extends React.PureComponent<StateProps & DispatchProps & OwnProps> {
static contextTypes = {
canAdmin: PropTypes.bool.isRequired
};
@@ -105,13 +111,18 @@ class AdminContainer extends React.PureComponent<Props> {
}
}
-const mapStateToProps = (state: any) => ({
+const mapStateToProps = (state: any): StateProps => ({
appState: getAppState(state),
editionStatus: getMarketplaceEditionStatus(state),
editionsUrl: (getGlobalSettingValue(state, 'sonar.editions.jsonUrl') || {}).value,
pendingPlugins: getMarketplacePendingPlugins(state)
});
-const mapDispatchToProps = { setAdminPages, setEditionStatus, fetchEditions, fetchPendingPlugins };
+const mapDispatchToProps: DispatchProps = {
+ setAdminPages,
+ setEditionStatus,
+ fetchEditions,
+ fetchPendingPlugins
+};
-export default connect(mapStateToProps, mapDispatchToProps)(AdminContainer as any);
+export default connect(mapStateToProps, mapDispatchToProps)(AdminContainer);
diff --git a/server/sonar-web/src/main/js/app/components/GlobalFooterSonarCloud.tsx b/server/sonar-web/src/main/js/app/components/GlobalFooterSonarCloud.tsx
index 6dd0208f57a..ad0c7d3b84d 100644
--- a/server/sonar-web/src/main/js/app/components/GlobalFooterSonarCloud.tsx
+++ b/server/sonar-web/src/main/js/app/components/GlobalFooterSonarCloud.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { getYear } from 'date-fns';
+import * as getYear from 'date-fns/get_year';
import { translate } from '../../helpers/l10n';
export default function GlobalFooterSonarCloud() {
diff --git a/server/sonar-web/src/main/js/app/components/__tests__/GlobalFooterSonarCloud-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/GlobalFooterSonarCloud-test.tsx
index 27ba87d8e89..1583bd701c1 100644
--- a/server/sonar-web/src/main/js/app/components/__tests__/GlobalFooterSonarCloud-test.tsx
+++ b/server/sonar-web/src/main/js/app/components/__tests__/GlobalFooterSonarCloud-test.tsx
@@ -21,9 +21,7 @@ import * as React from 'react';
import { shallow } from 'enzyme';
import GlobalFooterSonarCloud from '../GlobalFooterSonarCloud';
-jest.mock('date-fns', () => ({
- getYear: jest.fn(() => 2018)
-}));
+jest.mock('date-fns/get_year', () => jest.fn(() => 2018));
it('should render correctly', () => {
expect(shallow(<GlobalFooterSonarCloud />)).toMatchSnapshot();
diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx
index 9e1eabf9be6..d7525d24054 100644
--- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx
+++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx
@@ -23,7 +23,6 @@ import GlobalNavBranding from './GlobalNavBranding';
import GlobalNavMenu from './GlobalNavMenu';
import GlobalNavExplore from './GlobalNavExplore';
import GlobalNavUserContainer from './GlobalNavUserContainer';
-import GlobalNavPlus from './GlobalNavPlus';
import Search from '../../search/Search';
import EmbedDocsPopupHelper from '../../embed-docs-modal/EmbedDocsPopupHelper';
import * as theme from '../../../theme';
@@ -31,12 +30,15 @@ import { isLoggedIn, CurrentUser, AppState } from '../../../types';
import OnboardingModal from '../../../../apps/tutorials/onboarding/OnboardingModal';
import NavBar from '../../../../components/nav/NavBar';
import Tooltip from '../../../../components/controls/Tooltip';
+import { lazyLoad } from '../../../../components/lazyLoad';
import { translate } from '../../../../helpers/l10n';
import { getCurrentUser, getAppState, getGlobalSettingValue } from '../../../../store/rootReducer';
import { skipOnboarding } from '../../../../store/users/actions';
import { SuggestionLink } from '../../embed-docs-modal/SuggestionsProvider';
import './GlobalNav.css';
+const GlobalNavPlus = lazyLoad(() => import('./GlobalNavPlus'));
+
interface StateProps {
appState: AppState;
currentUser: CurrentUser;
diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.js b/server/sonar-web/src/main/js/app/utils/startReactApp.js
index a013773e344..6d143225d4a 100644
--- a/server/sonar-web/src/main/js/app/utils/startReactApp.js
+++ b/server/sonar-web/src/main/js/app/utils/startReactApp.js
@@ -24,24 +24,10 @@ import { Router, Route, IndexRoute, Redirect } from 'react-router';
import { Provider } from 'react-redux';
import getStore from './getStore';
import getHistory from './getHistory';
-import AppContextContainer from '../components/AppContextContainer';
import LocalizationContainer from '../components/LocalizationContainer';
import MigrationContainer from '../components/MigrationContainer';
import App from '../components/App';
import GlobalContainer from '../components/GlobalContainer';
-import SimpleContainer from '../components/SimpleContainer';
-import SimpleSessionsContainer from '../components/SimpleSessionsContainer';
-import Landing from '../components/Landing';
-import ProjectAdminContainer from '../components/ProjectAdminContainer';
-import ProjectPageExtension from '../components/extensions/ProjectPageExtension';
-import ProjectAdminPageExtension from '../components/extensions/ProjectAdminPageExtension';
-import PortfoliosPage from '../components/extensions/PortfoliosPage';
-import AdminContainer from '../components/AdminContainer';
-import GlobalPageExtension from '../components/extensions/GlobalPageExtension';
-import GlobalAdminPageExtension from '../components/extensions/GlobalAdminPageExtension';
-import MarkdownHelp from '../components/MarkdownHelp';
-import NotFound from '../components/NotFound';
-import OnboardingPage from '../../apps/tutorials/onboarding/OnboardingPage';
import aboutRoutes from '../../apps/about/routes';
import accountRoutes from '../../apps/account/routes';
import backgroundTasksRoutes from '../../apps/background-tasks/routes';
@@ -63,7 +49,6 @@ import organizationsRoutes from '../../apps/organizations/routes';
import permissionTemplatesRoutes from '../../apps/permission-templates/routes';
import portfolioRoutes from '../../apps/portfolio/routes';
import projectActivityRoutes from '../../apps/projectActivity/routes';
-import projectAdminRoutes from '../../apps/project-admin/routes';
import projectBranchesRoutes from '../../apps/projectBranches/routes';
import projectQualityGateRoutes from '../../apps/projectQualityGate/routes';
import projectQualityProfilesRoutes from '../../apps/projectQualityProfiles/routes';
@@ -150,23 +135,26 @@ const startReactApp = () => {
<Redirect from="/view" to="/portfolio" />
<Redirect from="/users" to="/admin/users" />
- <Route path="markdown/help" component={MarkdownHelp} />
+ <Route
+ path="markdown/help"
+ component={lazyLoad(() => import('../components/MarkdownHelp'))}
+ />
<Route component={LocalizationContainer}>
- <Route component={SimpleContainer}>
+ <Route component={lazyLoad(() => import('../components/SimpleContainer'))}>
<Route path="maintenance">{maintenanceRoutes}</Route>
<Route path="setup">{setupRoutes}</Route>
</Route>
<Route component={MigrationContainer}>
- <Route component={AppContextContainer}>
- <Route component={SimpleSessionsContainer}>
+ <Route component={lazyLoad(() => import('../components/AppContextContainer'))}>
+ <Route component={lazyLoad(() => import('../components/SimpleSessionsContainer'))}>
<Route path="/sessions" childRoutes={sessionsRoutes} />
</Route>
</Route>
<Route path="/" component={App}>
- <IndexRoute component={Landing} />
+ <IndexRoute component={lazyLoad(() => import('../components/Landing'))} />
<Route component={GlobalContainer}>
<Route path="about" childRoutes={aboutRoutes} />
@@ -178,13 +166,24 @@ const startReactApp = () => {
<Route path="issues" component={ExploreIssues} />
<Route path="projects" component={ExploreProjects} />
</Route>
- <Route path="extension/:pluginKey/:extensionKey" component={GlobalPageExtension} />
+ <Route
+ path="extension/:pluginKey/:extensionKey"
+ component={lazyLoad(() => import('../components/extensions/GlobalPageExtension'))}
+ />
<Route path="issues" component={IssuesPageSelector} />
- <Route path="onboarding" component={OnboardingPage} />
+ <Route
+ path="onboarding"
+ component={lazyLoad(() =>
+ import('../../apps/tutorials/onboarding/OnboardingPage')
+ )}
+ />
<Route path="organizations" childRoutes={organizationsRoutes} />
<Route path="projects" childRoutes={projectsRoutes} />
<Route path="quality_gates" childRoutes={qualityGatesRoutes} />
- <Route path="portfolios" component={PortfoliosPage} />
+ <Route
+ path="portfolios"
+ component={lazyLoad(() => import('../components/extensions/PortfoliosPage'))}
+ />
<Route path="profiles" childRoutes={qualityProfilesRoutes} />
<Route path="web_api" childRoutes={webAPIRoutes} />
@@ -196,7 +195,9 @@ const startReactApp = () => {
<Route path="project/activity" childRoutes={projectActivityRoutes} />
<Route
path="project/extension/:pluginKey/:extensionKey"
- component={ProjectPageExtension}
+ component={lazyLoad(() =>
+ import('../components/extensions/ProjectPageExtension')
+ )}
/>
<Route path="project/issues" component={Issues} />
<Route path="project/quality_gate" childRoutes={projectQualityGateRoutes} />
@@ -204,25 +205,44 @@ const startReactApp = () => {
path="project/quality_profiles"
childRoutes={projectQualityProfilesRoutes}
/>
- <Route component={ProjectAdminContainer}>
+ <Route component={lazyLoad(() => import('../components/ProjectAdminContainer'))}>
<Route path="custom_measures" childRoutes={customMeasuresRoutes} />
<Route
path="project/admin/extension/:pluginKey/:extensionKey"
- component={ProjectAdminPageExtension}
+ component={lazyLoad(() =>
+ import('../components/extensions/ProjectAdminPageExtension')
+ )}
/>
<Route path="project/background_tasks" childRoutes={backgroundTasksRoutes} />
<Route path="project/branches" childRoutes={projectBranchesRoutes} />
<Route path="project/settings" childRoutes={settingsRoutes} />
<Route path="project_roles" childRoutes={projectPermissionsRoutes} />
<Route path="project/webhooks" childRoutes={webhooksRoutes} />
+ <Route
+ path="project/deletion"
+ component={lazyLoad(() =>
+ import('../../apps/project-admin/deletion/Deletion')
+ )}
+ />
+ <Route
+ path="project/links"
+ component={lazyLoad(() => import('../../apps/project-admin/links/Links'))}
+ />
+ <Route
+ path="project/key"
+ component={lazyLoad(() => import('../../apps/project-admin/key/Key'))}
+ />
</Route>
- {projectAdminRoutes}
</Route>
- <Route component={AdminContainer} path="admin">
+ <Route
+ component={lazyLoad(() => import('../components/AdminContainer'))}
+ path="admin">
<Route
path="extension/:pluginKey/:extensionKey"
- component={GlobalAdminPageExtension}
+ component={lazyLoad(() =>
+ import('../components/extensions/GlobalAdminPageExtension')
+ )}
/>
<Route path="background_tasks" childRoutes={backgroundTasksRoutes} />
<Route path="custom_metrics" childRoutes={customMetricsRoutes} />
@@ -238,8 +258,11 @@ const startReactApp = () => {
<Route path="webhooks" childRoutes={webhooksRoutes} />
</Route>
</Route>
- <Route path="not_found" component={NotFound} />
- <Route path="*" component={NotFound} />
+ <Route
+ path="not_found"
+ component={lazyLoad(() => import('../components/NotFound'))}
+ />
+ <Route path="*" component={lazyLoad(() => import('../components/NotFound'))} />
</Route>
</Route>
</Route>