diff options
Diffstat (limited to 'server/sonar-web/src/main/js')
8 files changed, 124 insertions, 68 deletions
diff --git a/server/sonar-web/src/main/js/app/components/PageTracker.tsx b/server/sonar-web/src/main/js/app/components/PageTracker.tsx index 0af0e6bec16..0ce7f93111b 100644 --- a/server/sonar-web/src/main/js/app/components/PageTracker.tsx +++ b/server/sonar-web/src/main/js/app/components/PageTracker.tsx @@ -22,7 +22,8 @@ import { connect } from 'react-redux'; import Helmet from 'react-helmet'; import { Location, withRouter } from '../../components/hoc/withRouter'; import { gtm } from '../../helpers/analytics'; -import { installScript, getWebAnalyticsPageHandlerFromCache } from '../../helpers/extensions'; +import { installScript } from '../../helpers/extensions'; +import { getWebAnalyticsPageHandlerFromCache } from '../../helpers/extensionsHandler'; import { getInstance } from '../../helpers/system'; import { getGlobalSettingValue, Store, getAppState } from '../../store/rootReducer'; diff --git a/server/sonar-web/src/main/js/app/components/__tests__/PageTracker-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/PageTracker-test.tsx index 59f6fe13655..36d40db9a93 100644 --- a/server/sonar-web/src/main/js/app/components/__tests__/PageTracker-test.tsx +++ b/server/sonar-web/src/main/js/app/components/__tests__/PageTracker-test.tsx @@ -23,10 +23,14 @@ import { shallow } from 'enzyme'; import { PageTracker } from '../PageTracker'; import { gtm } from '../../../helpers/analytics'; import { mockLocation } from '../../../helpers/testMocks'; -import { installScript, getWebAnalyticsPageHandlerFromCache } from '../../../helpers/extensions'; +import { installScript } from '../../../helpers/extensions'; +import { getWebAnalyticsPageHandlerFromCache } from '../../../helpers/extensionsHandler'; jest.mock('../../../helpers/extensions', () => ({ - installScript: jest.fn().mockResolvedValue({}), + installScript: jest.fn().mockResolvedValue({}) +})); + +jest.mock('../../../helpers/extensionsHandler', () => ({ getWebAnalyticsPageHandlerFromCache: jest.fn().mockReturnValue(undefined) })); diff --git a/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx b/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx index 2e66aa797d3..c0eb4175997 100644 --- a/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx +++ b/server/sonar-web/src/main/js/app/components/extensions/Extension.tsx @@ -22,11 +22,11 @@ import Helmet from 'react-helmet'; import { injectIntl, InjectedIntlProps } from 'react-intl'; import { connect } from 'react-redux'; import getStore from '../../utils/getStore'; +import { Location, Router, withRouter } from '../../../components/hoc/withRouter'; import { getExtensionStart } from '../../../helpers/extensions'; import { addGlobalErrorMessage } from '../../../store/globalMessages'; import { translate } from '../../../helpers/l10n'; import { Store, getCurrentUser } from '../../../store/rootReducer'; -import { Location, Router, withRouter } from '../../../components/hoc/withRouter'; interface Props extends InjectedIntlProps { currentUser: T.CurrentUser; diff --git a/server/sonar-web/src/main/js/app/index.ts b/server/sonar-web/src/main/js/app/index.ts index 8fd4bc68a9d..fd3639bcc05 100644 --- a/server/sonar-web/src/main/js/app/index.ts +++ b/server/sonar-web/src/main/js/app/index.ts @@ -18,7 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { installGlobal, DEFAULT_LANGUAGE, requestMessages } from '../helpers/l10n'; -import { installExtensionsHandler, installWebAnalyticsHandler } from '../helpers/extensions'; +import { installExtensionsHandler, installWebAnalyticsHandler } from '../helpers/extensionsHandler'; import { request, parseJSON } from '../helpers/request'; import { getSystemStatus } from '../helpers/system'; import './styles/sonar.css'; diff --git a/server/sonar-web/src/main/js/helpers/__tests__/extensions-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/extensions-test.ts index 72ece2f775b..182fa0e54d6 100644 --- a/server/sonar-web/src/main/js/helpers/__tests__/extensions-test.ts +++ b/server/sonar-web/src/main/js/helpers/__tests__/extensions-test.ts @@ -17,14 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { - getExtensionFromCache, - getWebAnalyticsPageHandlerFromCache, - getExtensionStart, - installExtensionsHandler, - installScript, - installWebAnalyticsHandler -} from '../extensions'; +import { getExtensionStart, installScript } from '../extensions'; +import { installExtensionsHandler } from '../extensionsHandler'; import exposeLibraries from '../../app/components/extensions/exposeLibraries'; jest.mock('../../app/components/extensions/exposeLibraries', () => ({ @@ -35,30 +29,6 @@ beforeEach(() => { jest.clearAllMocks(); }); -describe('installExtensionsHandler & extensions.getExtensionFromCache', () => { - it('should register the global "registerExtension" function and retrieve extension', () => { - expect((window as any).registerExtension).toBeUndefined(); - installExtensionsHandler(); - expect((window as any).registerExtension).toEqual(expect.any(Function)); - - const start = jest.fn(); - (window as any).registerExtension('foo', start); - expect(getExtensionFromCache('foo')).toBe(start); - }); -}); - -describe('setWebAnalyticsPageChangeHandler & getWebAnalyticsPageHandlerFromCache', () => { - it('should register the global "setWebAnalyticsPageChangeHandler" function and retrieve analytics extension', () => { - expect((window as any).setWebAnalyticsPageChangeHandler).toBeUndefined(); - installWebAnalyticsHandler(); - expect((window as any).setWebAnalyticsPageChangeHandler).toEqual(expect.any(Function)); - - const pageChange = jest.fn(); - (window as any).setWebAnalyticsPageChangeHandler(pageChange); - expect(getWebAnalyticsPageHandlerFromCache()).toBe(pageChange); - }); -}); - describe('installScript', () => { it('should add the given script in the dom', () => { installScript('custom_script.js'); @@ -67,17 +37,19 @@ describe('installScript', () => { }); describe('getExtensionStart', () => { - it('should install the extension in the to dom', () => { + it('should install the extension in the to dom', async () => { const start = jest.fn(); const scriptTag = document.createElement('script'); document.createElement = jest.fn().mockReturnValue(scriptTag); installExtensionsHandler(); const result = getExtensionStart('bar'); - (window as any).registerExtension('bar', start); - (scriptTag.onload as Function)(); + await new Promise(setImmediate); expect(exposeLibraries).toBeCalled(); + + (window as any).registerExtension('bar', start); + (scriptTag.onload as Function)(); return expect(result).resolves.toBe(start); }); diff --git a/server/sonar-web/src/main/js/helpers/__tests__/extensionsHandler-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/extensionsHandler-test.ts new file mode 100644 index 00000000000..a2a23379e32 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/__tests__/extensionsHandler-test.ts @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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 { + getExtensionFromCache, + getWebAnalyticsPageHandlerFromCache, + installExtensionsHandler, + installWebAnalyticsHandler +} from '../extensionsHandler'; + +describe('installExtensionsHandler & extensions.getExtensionFromCache', () => { + it('should register the global "registerExtension" function and retrieve extension', () => { + expect((window as any).registerExtension).toBeUndefined(); + installExtensionsHandler(); + expect((window as any).registerExtension).toEqual(expect.any(Function)); + + const start = jest.fn(); + (window as any).registerExtension('foo', start); + expect(getExtensionFromCache('foo')).toBe(start); + }); +}); + +describe('setWebAnalyticsPageChangeHandler & getWebAnalyticsPageHandlerFromCache', () => { + it('should register the global "setWebAnalyticsPageChangeHandler" function and retrieve analytics extension', () => { + expect((window as any).setWebAnalyticsPageChangeHandler).toBeUndefined(); + installWebAnalyticsHandler(); + expect((window as any).setWebAnalyticsPageChangeHandler).toEqual(expect.any(Function)); + + const pageChange = jest.fn(); + (window as any).setWebAnalyticsPageChangeHandler(pageChange); + expect(getWebAnalyticsPageHandlerFromCache()).toBe(pageChange); + }); +}); diff --git a/server/sonar-web/src/main/js/helpers/extensions.ts b/server/sonar-web/src/main/js/helpers/extensions.ts index 66a56cf3ed0..6d40d843625 100644 --- a/server/sonar-web/src/main/js/helpers/extensions.ts +++ b/server/sonar-web/src/main/js/helpers/extensions.ts @@ -18,34 +18,9 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { getBaseUrl } from './urls'; -import exposeLibraries from '../app/components/extensions/exposeLibraries'; +import { getExtensionFromCache } from './extensionsHandler'; -const WEB_ANALYTICS_EXTENSION = 'sq-web-analytics'; -const extensions: T.Dict<Function> = {}; - -function registerExtension(key: string, start: Function) { - extensions[key] = start; -} - -function setWebAnalyticsPageChangeHandler(pageHandler: (pathname: string) => void) { - registerExtension(WEB_ANALYTICS_EXTENSION, pageHandler); -} - -export function installExtensionsHandler() { - (window as any).registerExtension = registerExtension; -} - -export function installWebAnalyticsHandler() { - (window as any).setWebAnalyticsPageChangeHandler = setWebAnalyticsPageChangeHandler; -} - -export function getExtensionFromCache(key: string): Function | undefined { - return extensions[key]; -} - -export function getWebAnalyticsPageHandlerFromCache(): Function | undefined { - return extensions[WEB_ANALYTICS_EXTENSION]; -} +let librariesExposed = false; export function installScript(url: string, target: 'body' | 'head' = 'body'): Promise<any> { return new Promise(resolve => { @@ -62,7 +37,13 @@ export async function getExtensionStart(key: string) { return Promise.resolve(fromCache); } - exposeLibraries(); + if (!librariesExposed) { + // Async import allows to reduce initial vendor bundle size + const exposeLibraries = (await import('../app/components/extensions/exposeLibraries')).default; + exposeLibraries(); + librariesExposed = true; + } + await installScript(`/static/${key}.js`); const start = getExtensionFromCache(key); diff --git a/server/sonar-web/src/main/js/helpers/extensionsHandler.ts b/server/sonar-web/src/main/js/helpers/extensionsHandler.ts new file mode 100644 index 00000000000..e414b2fdbbd --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/extensionsHandler.ts @@ -0,0 +1,49 @@ +/* + * SonarQube + * Copyright (C) 2009-2019 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. + */ + +// Do not import dependencies in this helper, to keep initial bundle load as small as possible + +const WEB_ANALYTICS_EXTENSION = 'sq-web-analytics'; + +const extensions: T.Dict<Function> = {}; + +function registerExtension(key: string, start: Function) { + extensions[key] = start; +} + +function setWebAnalyticsPageChangeHandler(pageHandler: (pathname: string) => void) { + registerExtension(WEB_ANALYTICS_EXTENSION, pageHandler); +} + +export function installExtensionsHandler() { + (window as any).registerExtension = registerExtension; +} + +export function installWebAnalyticsHandler() { + (window as any).setWebAnalyticsPageChangeHandler = setWebAnalyticsPageChangeHandler; +} + +export function getExtensionFromCache(key: string): Function | undefined { + return extensions[key]; +} + +export function getWebAnalyticsPageHandlerFromCache(): Function | undefined { + return extensions[WEB_ANALYTICS_EXTENSION]; +} |