From: Stas Vilchik Date: Wed, 4 Jul 2018 11:38:11 +0000 (+0200) Subject: decrease initial amount of js (#462) X-Git-Tag: 7.5~872 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6ff576fb1e0f8081121e1e7279c846927f98d68f;p=sonarqube.git decrease initial amount of js (#462) --- diff --git a/server/sonar-web/.babelrc b/server/sonar-web/.babelrc index a14ae9bb095..2beb6e05efa 100644 --- a/server/sonar-web/.babelrc +++ b/server/sonar-web/.babelrc @@ -13,7 +13,60 @@ "IE 11" ] }, - "useBuiltIns": true + "useBuiltIns": true, + "exclude": [ + "es6.math.acosh", + "es6.math.asinh", + "es6.math.atanh", + "es6.math.cbrt", + "es6.math.clz32", + "es6.math.cosh", + "es6.math.expm1", + "es6.math.fround", + "es6.math.hypot", + "es6.math.imul", + "es6.math.log1p", + "es6.math.log10", + "es6.math.log2", + "es6.math.sign", + "es6.math.sinh", + "es6.math.tanh", + "es6.math.trunc", + + "es6.reflect.apply", + "es6.reflect.construct", + "es6.reflect.define-property", + "es6.reflect.delete-property", + "es6.reflect.get", + "es6.reflect.get-own-property-descriptor", + "es6.reflect.get-prototype-of", + "es6.reflect.has", + "es6.reflect.is-extensible", + "es6.reflect.own-keys", + "es6.reflect.prevent-extensions", + "es6.reflect.set", + "es6.reflect.set-prototype-of", + + "es6.set", + "es6.symbol", + + "es6.typed.array-buffer", + "es6.typed.data-view", + "es6.typed.int8-array", + "es6.typed.uint8-array", + "es6.typed.uint8-clamped-array", + "es6.typed.int16-array", + "es6.typed.uint16-array", + "es6.typed.int32-array", + "es6.typed.uint32-array", + "es6.typed.float32-array", + "es6.typed.float64-array", + + "es6.weak-map", + "es6.weak-set", + + "transform-regenerator" + ] } ], "react" diff --git a/server/sonar-web/config/webpack.config.js b/server/sonar-web/config/webpack.config.js index e62bb11f6b4..9030b4b41eb 100644 --- a/server/sonar-web/config/webpack.config.js +++ b/server/sonar-web/config/webpack.config.js @@ -153,8 +153,8 @@ module.exports = ({ production = true }) => ({ performance: production ? { hints: 'error', - maxEntrypointSize: 710000, // ~700kb, recommended: 250kb - maxAssetSize: 400000 // ~400kb, recommended: 250kb + maxEntrypointSize: 600000, // recommended: 250kb + maxAssetSize: 320000 // recommended: 250kb } : undefined }); diff --git a/server/sonar-web/src/main/js/app/components/StartupModal.tsx b/server/sonar-web/src/main/js/app/components/StartupModal.tsx index 914adc7b3ea..bbd6c574eec 100644 --- a/server/sonar-web/src/main/js/app/components/StartupModal.tsx +++ b/server/sonar-web/src/main/js/app/components/StartupModal.tsx @@ -20,11 +20,6 @@ import * as React from 'react'; import * as PropTypes from 'prop-types'; import { connect } from 'react-redux'; -import Onboarding from '../../apps/tutorials/Onboarding'; -import CreateOrganizationForm from '../../apps/account/organizations/CreateOrganizationForm'; -import LicensePromptModal from '../../apps/marketplace/components/LicensePromptModal'; -import ProjectOnboardingModal from '../../apps/tutorials/projectOnboarding/ProjectOnboardingModal'; -import TeamOnboardingModal from '../../apps/tutorials/teamOnboarding/TeamOnboardingModal'; import { CurrentUser, isLoggedIn, Organization } from '../types'; import { differenceInDays, parseDate, toShortNotSoISOString } from '../../helpers/dates'; import { EditionKey } from '../../apps/marketplace/utils'; @@ -35,6 +30,23 @@ import { hasMessage } from '../../helpers/l10n'; import { save, get } from '../../helpers/storage'; import { isSonarCloud } from '../../helpers/system'; import { skipOnboarding } from '../../api/users'; +import { lazyLoad } from '../../components/lazyLoad'; + +const CreateOrganizationForm = lazyLoad(() => + import('../../apps/account/organizations/CreateOrganizationForm') +); +const Onboarding = lazyLoad(() => import('../../apps/tutorials/Onboarding')); +const LicensePromptModal = lazyLoad( + () => import('../../apps/marketplace/components/LicensePromptModal'), + 'LicensePromptModal' +); +const ProjectOnboardingModal = lazyLoad( + () => import('../../apps/tutorials/projectOnboarding/ProjectOnboardingModal'), + 'ProjectOnboardingModal' +); +const TeamOnboardingModal = lazyLoad(() => + import('../../apps/tutorials/teamOnboarding/TeamOnboardingModal') +); interface StateProps { canAdmin: boolean; diff --git a/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx b/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx index 06b7bc02b02..f9671bc289e 100644 --- a/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx +++ b/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx @@ -18,11 +18,13 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import EmbedDocsPopup from './EmbedDocsPopup'; import { SuggestionLink } from './SuggestionsProvider'; import { CurrentUser } from '../../types'; import Toggler from '../../../components/controls/Toggler'; import HelpIcon from '../../../components/icons-components/HelpIcon'; +import { lazyLoad } from '../../../components/lazyLoad'; + +const EmbedDocsPopup = lazyLoad(() => import('./EmbedDocsPopup')); interface Props { currentUser: CurrentUser; diff --git a/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts b/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts new file mode 100644 index 00000000000..026979b1b58 --- /dev/null +++ b/server/sonar-web/src/main/js/app/components/extensions/exposeLibraries.ts @@ -0,0 +1,112 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as ReactRedux from 'react-redux'; +import * as ReactRouter from 'react-router'; +import throwGlobalError from '../../utils/throwGlobalError'; +import addGlobalSuccessMessage from '../../utils/addGlobalSuccessMessage'; +import Suggestions from '../../components/embed-docs-modal/Suggestions'; +import * as measures from '../../../helpers/measures'; +import * as request from '../../../helpers/request'; +import DateFromNow from '../../../components/intl/DateFromNow'; +import DateFormatter from '../../../components/intl/DateFormatter'; +import DateTimeFormatter from '../../../components/intl/DateTimeFormatter'; +import FavoriteContainer from '../../../components/controls/FavoriteContainer'; +import HomePageSelect from '../../../components/controls/HomePageSelect'; +import ListFooter from '../../../components/controls/ListFooter'; +import Modal from '../../../components/controls/Modal'; +import HelpTooltip from '../../../components/controls/HelpTooltip'; +import SearchBox from '../../../components/controls/SearchBox'; +import Select from '../../../components/controls/Select'; +import Tooltip from '../../../components/controls/Tooltip'; +import SelectList from '../../../components/SelectList/SelectList'; +import CoverageRating from '../../../components/ui/CoverageRating'; +import DuplicationsRating from '../../../components/ui/DuplicationsRating'; +import Level from '../../../components/ui/Level'; +import { EditButton, Button, SubmitButton, ResetButtonLink } from '../../../components/ui/buttons'; +import Checkbox from '../../../components/controls/Checkbox'; +import DeferredSpinner from '../../../components/common/DeferredSpinner'; +import Dropdown from '../../../components/controls/Dropdown'; +import ReloadButton from '../../../components/controls/ReloadButton'; +import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon'; +import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon'; +import AlertWarnIcon from '../../../components/icons-components/AlertWarnIcon'; +import CheckIcon from '../../../components/icons-components/CheckIcon'; +import ClearIcon from '../../../components/icons-components/ClearIcon'; +import DropdownIcon from '../../../components/icons-components/DropdownIcon'; +import HelpIcon from '../../../components/icons-components/HelpIcon'; +import LockIcon from '../../../components/icons-components/LockIcon'; +import QualifierIcon from '../../../components/icons-components/QualifierIcon'; +import Rating from '../../../components/ui/Rating'; +import BranchIcon from '../../../components/icons-components/BranchIcon'; +import LongLivingBranchIcon from '../../../components/icons-components/LongLivingBranchIcon'; +import PullRequestIcon from '../../../components/icons-components/PullRequestIcon'; +import ActionsDropdown, { ActionsDropdownItem } from '../../../components/controls/ActionsDropdown'; + +const exposeLibraries = () => { + const global = window as any; + + global.ReactRedux = ReactRedux; + global.ReactRouter = ReactRouter; + global.SonarMeasures = measures; + global.SonarRequest = { ...request, throwGlobalError, addGlobalSuccessMessage }; + global.SonarComponents = { + ActionsDropdown, + ActionsDropdownItem, + AlertErrorIcon, + AlertSuccessIcon, + AlertWarnIcon, + BranchIcon, + Button, + Checkbox, + CheckIcon, + ClearIcon, + CoverageRating, + DateFormatter, + DateFromNow, + DateTimeFormatter, + DeferredSpinner, + Dropdown, + DropdownIcon, + DuplicationsRating, + EditButton, + FavoriteContainer, + HelpIcon, + HelpTooltip, + HomePageSelect, + Level, + ListFooter, + LockIcon, + LongLivingBranchIcon, + Modal, + PullRequestIcon, + QualifierIcon, + Rating, + ReloadButton, + ResetButtonLink, + SearchBox, + Select, + SelectList, + SubmitButton, + Suggestions, + Tooltip + }; +}; + +export default exposeLibraries; diff --git a/server/sonar-web/src/main/js/app/components/extensions/utils.js b/server/sonar-web/src/main/js/app/components/extensions/utils.js index c62cb61ee4a..98600e25581 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/utils.js +++ b/server/sonar-web/src/main/js/app/components/extensions/utils.js @@ -18,10 +18,12 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // @flow +import exposeLibraries from './exposeLibraries'; import { getExtensionFromCache } from '../../utils/installExtensionsHandler'; function installScript(key /*: string */) { return new Promise(resolve => { + exposeLibraries(); const scriptTag = document.createElement('script'); scriptTag.src = `${window.baseUrl}/static/${key}.js`; scriptTag.onload = resolve; @@ -33,7 +35,8 @@ export function getExtensionStart(key /*: string */) { return new Promise((resolve, reject) => { const fromCache = getExtensionFromCache(key); if (fromCache) { - return resolve(fromCache); + resolve(fromCache); + return; } installScript(key).then(() => { @@ -43,6 +46,6 @@ export function getExtensionStart(key /*: string */) { } else { reject(); } - }); + }, reject); }); } diff --git a/server/sonar-web/src/main/js/app/components/search/Search.js b/server/sonar-web/src/main/js/app/components/search/Search.js index cd315cbfacf..db4a2b79494 100644 --- a/server/sonar-web/src/main/js/app/components/search/Search.js +++ b/server/sonar-web/src/main/js/app/components/search/Search.js @@ -23,21 +23,23 @@ import PropTypes from 'prop-types'; import key from 'keymaster'; import { debounce, keyBy, uniqBy } from 'lodash'; import { FormattedMessage } from 'react-intl'; -import SearchResults from './SearchResults'; -import SearchResult from './SearchResult'; import { sortQualifiers } from './utils'; /*:: import type { Component, More, Results } from './utils'; */ import RecentHistory from '../../components/RecentHistory'; import DeferredSpinner from '../../../components/common/DeferredSpinner'; +import { DropdownOverlay } from '../../../components/controls/Dropdown'; import ClockIcon from '../../../components/icons-components/ClockIcon'; import OutsideClickHandler from '../../../components/controls/OutsideClickHandler'; import SearchBox from '../../../components/controls/SearchBox'; +import { lazyLoad } from '../../../components/lazyLoad'; import { getSuggestions } from '../../../api/components'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { scrollToElement } from '../../../helpers/scrolling'; import { getProjectUrl } from '../../../helpers/urls'; import './Search.css'; -import { DropdownOverlay } from '../../../components/controls/Dropdown'; + +const SearchResults = lazyLoad(() => import('./SearchResults')); +const SearchResult = lazyLoad(() => import('./SearchResult')); /*:: type Props = {| diff --git a/server/sonar-web/src/main/js/app/index.js b/server/sonar-web/src/main/js/app/index.js index ee6cfb479d7..6fe8aa8dc40 100644 --- a/server/sonar-web/src/main/js/app/index.js +++ b/server/sonar-web/src/main/js/app/index.js @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import exposeLibraries from './utils/exposeLibraries'; import startReactApp from './utils/startReactApp'; import installExtensionsHandler from './utils/installExtensionsHandler'; import { installGlobal } from '../helpers/l10n'; @@ -26,5 +25,4 @@ import './styles/sonar.css'; installGlobal(); startReactApp(); -exposeLibraries(); installExtensionsHandler(); diff --git a/server/sonar-web/src/main/js/app/utils/exposeLibraries.ts b/server/sonar-web/src/main/js/app/utils/exposeLibraries.ts deleted file mode 100644 index 03bb25eac5b..00000000000 --- a/server/sonar-web/src/main/js/app/utils/exposeLibraries.ts +++ /dev/null @@ -1,112 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2018 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import * as ReactRedux from 'react-redux'; -import * as ReactRouter from 'react-router'; -import throwGlobalError from './throwGlobalError'; -import addGlobalSuccessMessage from './addGlobalSuccessMessage'; -import Suggestions from '../components/embed-docs-modal/Suggestions'; -import * as measures from '../../helpers/measures'; -import * as request from '../../helpers/request'; -import DateFromNow from '../../components/intl/DateFromNow'; -import DateFormatter from '../../components/intl/DateFormatter'; -import DateTimeFormatter from '../../components/intl/DateTimeFormatter'; -import FavoriteContainer from '../../components/controls/FavoriteContainer'; -import HomePageSelect from '../../components/controls/HomePageSelect'; -import ListFooter from '../../components/controls/ListFooter'; -import Modal from '../../components/controls/Modal'; -import HelpTooltip from '../../components/controls/HelpTooltip'; -import SearchBox from '../../components/controls/SearchBox'; -import Select from '../../components/controls/Select'; -import Tooltip from '../../components/controls/Tooltip'; -import SelectList from '../../components/SelectList/SelectList'; -import CoverageRating from '../../components/ui/CoverageRating'; -import DuplicationsRating from '../../components/ui/DuplicationsRating'; -import Level from '../../components/ui/Level'; -import { EditButton, Button, SubmitButton, ResetButtonLink } from '../../components/ui/buttons'; -import Checkbox from '../../components/controls/Checkbox'; -import DeferredSpinner from '../../components/common/DeferredSpinner'; -import Dropdown from '../../components/controls/Dropdown'; -import ReloadButton from '../../components/controls/ReloadButton'; -import AlertErrorIcon from '../../components/icons-components/AlertErrorIcon'; -import AlertSuccessIcon from '../../components/icons-components/AlertSuccessIcon'; -import AlertWarnIcon from '../../components/icons-components/AlertWarnIcon'; -import CheckIcon from '../../components/icons-components/CheckIcon'; -import ClearIcon from '../../components/icons-components/ClearIcon'; -import DropdownIcon from '../../components/icons-components/DropdownIcon'; -import HelpIcon from '../../components/icons-components/HelpIcon'; -import LockIcon from '../../components/icons-components/LockIcon'; -import QualifierIcon from '../../components/icons-components/QualifierIcon'; -import Rating from '../../components/ui/Rating'; -import BranchIcon from '../../components/icons-components/BranchIcon'; -import LongLivingBranchIcon from '../../components/icons-components/LongLivingBranchIcon'; -import PullRequestIcon from '../../components/icons-components/PullRequestIcon'; -import ActionsDropdown, { ActionsDropdownItem } from '../../components/controls/ActionsDropdown'; - -const exposeLibraries = () => { - const global = window as any; - - global.ReactRedux = ReactRedux; - global.ReactRouter = ReactRouter; - global.SonarMeasures = measures; - global.SonarRequest = { ...request, throwGlobalError, addGlobalSuccessMessage }; - global.SonarComponents = { - ActionsDropdown, - ActionsDropdownItem, - AlertErrorIcon, - AlertSuccessIcon, - AlertWarnIcon, - BranchIcon, - Button, - Checkbox, - CheckIcon, - ClearIcon, - CoverageRating, - DateFormatter, - DateFromNow, - DateTimeFormatter, - DeferredSpinner, - Dropdown, - DropdownIcon, - DuplicationsRating, - EditButton, - FavoriteContainer, - HelpIcon, - HelpTooltip, - HomePageSelect, - Level, - ListFooter, - LockIcon, - LongLivingBranchIcon, - Modal, - PullRequestIcon, - QualifierIcon, - Rating, - ReloadButton, - ResetButtonLink, - SearchBox, - Select, - SelectList, - SubmitButton, - Suggestions, - Tooltip - }; -}; - -export default exposeLibraries; diff --git a/server/sonar-web/src/main/js/components/lazyLoad.tsx b/server/sonar-web/src/main/js/components/lazyLoad.tsx index 7043b40f440..2b4268bf08a 100644 --- a/server/sonar-web/src/main/js/components/lazyLoad.tsx +++ b/server/sonar-web/src/main/js/components/lazyLoad.tsx @@ -29,7 +29,7 @@ interface Loader

{ export const LAST_FAILED_CHUNK_STORAGE_KEY = 'sonarqube.last_failed_chunk'; -export function lazyLoad

(loader: Loader

) { +export function lazyLoad

(loader: Loader

, displayName?: string) { interface ImportError { request?: string; } @@ -43,6 +43,7 @@ export function lazyLoad

(loader: Loader

) { // and let the child component decide if it needs to change return class LazyLoader extends React.Component { mounted = false; + static displayName = displayName; state: State = {}; componentDidMount() { diff --git a/server/sonar-web/src/main/js/components/workspace/Workspace.tsx b/server/sonar-web/src/main/js/components/workspace/Workspace.tsx index 65950494d58..ea0cc484b7f 100644 --- a/server/sonar-web/src/main/js/components/workspace/Workspace.tsx +++ b/server/sonar-web/src/main/js/components/workspace/Workspace.tsx @@ -21,13 +21,13 @@ import * as React from 'react'; import * as PropTypes from 'prop-types'; import { omit, uniqBy } from 'lodash'; import { WorkspaceContext, ComponentDescriptor, RuleDescriptor } from './context'; -import WorkspaceNav from './WorkspaceNav'; import WorkspacePortal from './WorkspacePortal'; import { get, save } from '../../helpers/storage'; import { lazyLoad } from '../lazyLoad'; import './styles.css'; const WORKSPACE = 'sonarqube-workspace'; +const WorkspaceNav = lazyLoad(() => import('./WorkspaceNav')); const WorkspaceRuleViewer = lazyLoad(() => import('./WorkspaceRuleViewer')); const WorkspaceComponentViewer = lazyLoad(() => import('./WorkspaceComponentViewer')); @@ -190,15 +190,17 @@ export default class Workspace extends React.PureComponent<{}, State> { <> {this.props.children} - + {(components.length > 0 || rules.length > 0) && ( + + )} {openComponent && (