ext {
release = project.hasProperty('release') && project.getProperty('release')
+ ci = project.hasProperty('ci') && project.getProperty('ci')
official = project.hasProperty('official') && project.getProperty('official')
}
inputs.property('official', official)
inputs.property('release', release)
+ inputs.property('ci', ci)
['config', 'public', 'scripts', 'src', '../sonar-docs/src'].each {
inputs.dir(it).withPathSensitivity(PathSensitivity.RELATIVE)
}
outputs.dir(webappDir)
outputs.cacheIf { true }
- args = [release ? 'build-release' : 'build']
+ args = [release || ci ? 'build-release' : 'build']
}
build.dependsOn(yarn_run)
"ts-loader": "5.3.3",
"typescript": "3.3.3333",
"webpack": "4.29.6",
- "webpack-bundle-analyzer": "3.1.0",
+ "webpack-bundle-analyzer": "3.3.2",
"webpack-dev-server": "3.2.1"
},
"scripts": {
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const getConfigs = require('../config/webpack.config');
-const configs = getConfigs({ production: true });
+const configs = getConfigs({ production: true, release: true });
const config = configs.find(config => config.name === 'modern');
+const analyzerPort = process.env.PORT || 8888;
-config.plugins.push(new BundleAnalyzerPlugin());
+config.plugins.push(new BundleAnalyzerPlugin({ analyzerPort }));
webpack(config, err => {
if (err) {
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';
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)
}));
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;
* 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';
* 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', () => ({
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');
});
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);
});
--- /dev/null
+/*
+ * 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);
+ });
+});
* 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 => {
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);
--- /dev/null
+/*
+ * 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];
+}
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==
-webpack-bundle-analyzer@3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.1.0.tgz#2f19cbb87bb6d4f3cb4e59cb67c837bd9436e89d"
- integrity sha512-nyDyWEs7C6DZlgvu1pR1zzJfIWSiGPbtaByZr8q+Fd2xp70FuM/8ngCJzj3Er1TYRLSFmp1F1OInbEm4DZH8NA==
+webpack-bundle-analyzer@3.3.2:
+ version "3.3.2"
+ resolved "https://repox.jfrog.io/repox/api/npm/npm/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.3.2.tgz#3da733a900f515914e729fcebcd4c40dde71fc6f"
+ integrity sha1-PaczqQD1FZFOcp/OvNTEDd5x/G8=
dependencies:
acorn "^6.0.7"
acorn-walk "^6.1.1"