]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12109 Fix initial vendor bundle size, and re-activate bundle size checking...
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>
Thu, 23 May 2019 11:59:45 +0000 (13:59 +0200)
committerSonarTech <sonartech@sonarsource.com>
Fri, 24 May 2019 18:21:09 +0000 (20:21 +0200)
13 files changed:
build.gradle
server/sonar-web/build.gradle
server/sonar-web/package.json
server/sonar-web/scripts/analyze.js
server/sonar-web/src/main/js/app/components/PageTracker.tsx
server/sonar-web/src/main/js/app/components/__tests__/PageTracker-test.tsx
server/sonar-web/src/main/js/app/components/extensions/Extension.tsx
server/sonar-web/src/main/js/app/index.ts
server/sonar-web/src/main/js/helpers/__tests__/extensions-test.ts
server/sonar-web/src/main/js/helpers/__tests__/extensionsHandler-test.ts [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/extensions.ts
server/sonar-web/src/main/js/helpers/extensionsHandler.ts [new file with mode: 0644]
server/sonar-web/yarn.lock

index 7d94be836e391a5d1f57bd1794658b65131b4d9b..c43c36b641a90511b9accf17c82103098b809dbc 100644 (file)
@@ -62,6 +62,7 @@ allprojects {
 
   ext {
     release = project.hasProperty('release') && project.getProperty('release')
+    ci = project.hasProperty('ci') && project.getProperty('ci')
     official = project.hasProperty('official') && project.getProperty('official')
   }
 
index 17ceecbd5dc65b3150f2acef3c64641502f81da1..7e99f19ef1df49abc11dd0e16cbb427a9405d70a 100644 (file)
@@ -27,6 +27,7 @@ yarn_run {
   
   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)
@@ -36,7 +37,7 @@ yarn_run {
   }
   outputs.dir(webappDir)
   outputs.cacheIf { true }
-  args = [release ? 'build-release' : 'build']
+  args = [release || ci ? 'build-release' : 'build']
 }
 build.dependsOn(yarn_run)
 
index cca4351ea0447548f3c4c9bc21af1d90607f05ed..4139065226d55fabe8aea2484f6e358baa8580a4 100644 (file)
     "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": {
index c41bedde127a72d4ca35efe7afea394e1787e1ff..b0c21ea1954aad74fd50dadf2691043700059451 100644 (file)
@@ -24,10 +24,11 @@ const webpack = require('webpack');
 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) {
index 0af0e6bec16702517e871f28c44c8092a1d52021..0ce7f93111b117d3d385aeb2e2eef289cc0f6291 100644 (file)
@@ -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';
 
index 59f6fe13655d5afd42e1ceb37ea505f68586060c..36d40db9a93dba90b6ac70cfccffc79994d51b2f 100644 (file)
@@ -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)
 }));
 
index 2e66aa797d33510f19eff897e051df0c5934d27f..c0eb4175997bd0ae604308908b5e5295960a7b73 100644 (file)
@@ -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;
index 8fd4bc68a9d5d448893eb7fc850c49b7fe4aa111..fd3639bcc056afd3205a927335cae197c7200ea5 100644 (file)
@@ -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';
index 72ece2f775bf55ff2eb63a590d5a3f8d1fdbe862..182fa0e54d6a594e310c54a3783bfa4fa1504e08 100644 (file)
  * 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 (file)
index 0000000..a2a2337
--- /dev/null
@@ -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);
+  });
+});
index 66a56cf3ed06f8590a9c8be3ce8913d3662c68e2..6d40d84362583dd6e63186dd2201953553b75c95 100644 (file)
  * 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 (file)
index 0000000..e414b2f
--- /dev/null
@@ -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];
+}
index fbb636f62db787f86d742ae22d5837e240693a56..f3cd22159f45637e6a92701c0738875d2ebe1605 100644 (file)
@@ -10247,10 +10247,10 @@ webidl-conversions@^4.0.2:
   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"