From f173a4eac7f63c5324412f656bf7a738a0f3370c Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Wed, 6 Nov 2024 16:40:43 +0100 Subject: [PATCH] chore(web): reduce bundle size and add regression checks when packaging CLOUDP-278538 (#6452) * chore(schema): replace moment usage with Date * chore(webpack-config): make sure lg testing tools are not bundled with the app * chore(web): add a local polyfill for tr46; add bundle size checks --- configs/webpack-config-compass/src/index.ts | 4 +++ package-lock.json | 2 -- packages/compass-schema/package.json | 1 - packages/compass-schema/src/modules/date.js | 13 ++++++--- packages/compass-web/.mocharc.js | 7 ++++- .../compass-web/polyfills/tr46/index.spec.ts | 27 +++++++++++++++++++ packages/compass-web/polyfills/tr46/index.ts | 17 ++++++++++++ packages/compass-web/webpack.config.js | 20 +++++++++++--- 8 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 packages/compass-web/polyfills/tr46/index.spec.ts create mode 100644 packages/compass-web/polyfills/tr46/index.ts diff --git a/configs/webpack-config-compass/src/index.ts b/configs/webpack-config-compass/src/index.ts index 2211b985f74..1b01bd891b4 100644 --- a/configs/webpack-config-compass/src/index.ts +++ b/configs/webpack-config-compass/src/index.ts @@ -107,6 +107,10 @@ const sharedResolveOptions = ( // This is an optional dependency of the AWS SDK that doesn't look like // an optional dependency to webpack because it's not wrapped in try/catch. '@aws-sdk/client-sso-oidc': false, + + // Some lg test helpers that are getting bundled due to re-exporting from + // the actual component packages, never needed in the webpack bundles + '@lg-tools/test-harnesses': false, }, }; }; diff --git a/package-lock.json b/package-lock.json index e51763a1c15..599183a7731 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45727,7 +45727,6 @@ "leaflet-defaulticon-compatibility": "^0.1.1", "leaflet-draw": "^1.0.4", "lodash": "^4.17.21", - "moment": "^2.29.4", "mongodb": "^6.9.0", "mongodb-query-util": "^2.2.9", "mongodb-schema": "^12.2.0", @@ -56709,7 +56708,6 @@ "leaflet-draw": "^1.0.4", "lodash": "^4.17.21", "mocha": "^10.2.0", - "moment": "^2.29.4", "mongodb": "^6.9.0", "mongodb-query-util": "^2.2.9", "mongodb-schema": "^12.2.0", diff --git a/packages/compass-schema/package.json b/packages/compass-schema/package.json index 12aafda2adb..a9d40c5c4f2 100644 --- a/packages/compass-schema/package.json +++ b/packages/compass-schema/package.json @@ -89,7 +89,6 @@ "leaflet-defaulticon-compatibility": "^0.1.1", "leaflet-draw": "^1.0.4", "lodash": "^4.17.21", - "moment": "^2.29.4", "mongodb": "^6.9.0", "mongodb-query-util": "^2.2.9", "mongodb-schema": "^12.2.0", diff --git a/packages/compass-schema/src/modules/date.js b/packages/compass-schema/src/modules/date.js index 5aed500473e..2a18fbe5547 100644 --- a/packages/compass-schema/src/modules/date.js +++ b/packages/compass-schema/src/modules/date.js @@ -1,7 +1,6 @@ /* eslint-disable no-use-before-define */ import d3 from 'd3'; import { isEqual, range, minBy, maxBy, sortBy, groupBy, map } from 'lodash'; -import moment from 'moment'; import { inValueRange } from 'mongodb-query-util'; import { palette, spacing } from '@mongodb-js/compass-components'; @@ -33,7 +32,15 @@ const minicharts_d3fns_date = (changeQueryFn) => { const options = {}; const subcharts = []; - const weekdayLabels = moment.weekdays(); + const weekdayLabels = [ + 'Sunday', + 'Monday', + 'Tuesday', + 'Wednesday', + 'Thursday', + 'Friday', + 'Saturday', + ]; // A formatter for dates const format = d3.time.format.utc('%Y-%m-%d %H:%M:%S'); @@ -215,7 +222,7 @@ const minicharts_d3fns_date = (changeQueryFn) => { // group by weekdays const w = groupBy(values, function (d) { - return moment(d.ts).weekday(); + return new Date(d.ts).getDay(); }); const wd = { ...generateDefaults(7), ...w }; const weekdays = map(wd, function (d, i) { diff --git a/packages/compass-web/.mocharc.js b/packages/compass-web/.mocharc.js index 61091edba73..101c4b4629a 100644 --- a/packages/compass-web/.mocharc.js +++ b/packages/compass-web/.mocharc.js @@ -1,2 +1,7 @@ 'use strict'; -module.exports = require('@mongodb-js/mocha-config-compass/compass-plugin'); +const config = require('@mongodb-js/mocha-config-compass/compass-plugin'); + +module.exports = { + ...config, + spec: [...config.spec, 'polyfills/**/*.spec.*', 'polyfills/**/*.test.*'], +}; diff --git a/packages/compass-web/polyfills/tr46/index.spec.ts b/packages/compass-web/polyfills/tr46/index.spec.ts new file mode 100644 index 00000000000..21deb017114 --- /dev/null +++ b/packages/compass-web/polyfills/tr46/index.spec.ts @@ -0,0 +1,27 @@ +import { expect } from 'chai'; +import { toASCII } from './index'; + +// Keep in sync with https://github.com/jsdom/tr46/blob/main/scripts/getLatestTests.js when updating whatwg-url +const wptSHA = '72b915d4b3754f081ef5899bf6a777efe71b2fc5'; + +describe('tr46 polyfill', function () { + describe('toASCII', function () { + let tests: { input: string; output: string }[] = []; + + before(async function () { + tests = await fetch( + `https://raw.githubusercontent.com/web-platform-tests/wpt/${wptSHA}/url/resources/toascii.json` + ).then((res) => res.json()); + }); + + it('should pass wpt specs', function () { + for (const test of tests) { + // String items are just comments in the test data + if (typeof test === 'string') { + return; + } + expect(toASCII(test.input)).to.eq(test.output); + } + }); + }); +}); diff --git a/packages/compass-web/polyfills/tr46/index.ts b/packages/compass-web/polyfills/tr46/index.ts new file mode 100644 index 00000000000..97a39f947d4 --- /dev/null +++ b/packages/compass-web/polyfills/tr46/index.ts @@ -0,0 +1,17 @@ +/** + * This is a dependency of whatwg-url package, we can't fully replace it with + * the globalThis.URL due to subtle differences in packages behavior, but we can + * substitue one of the biggest chunks of the package (tr46) with a browser + * implementation. + */ +export function toASCII(domain: string) { + try { + return new window.URL(`http://${domain}`).hostname; + } catch { + return null; + } +} + +export function toUnicode() { + throw new Error('Not implemented'); +} diff --git a/packages/compass-web/webpack.config.js b/packages/compass-web/webpack.config.js index 5a614982eb7..f339ccd703d 100644 --- a/packages/compass-web/webpack.config.js +++ b/packages/compass-web/webpack.config.js @@ -15,6 +15,13 @@ function localPolyfill(name) { return path.resolve(__dirname, 'polyfills', ...name.split('/'), 'index.ts'); } +/** + * Atlas Cloud uses in-flight compression that doesn't compress anything that is + * bigger than 10MB, we want to make sure that compass-web assets stay under the + * limit so that they are compressed when served + */ +const MAX_COMPRESSION_FILE_SIZE = 10_000_000; + module.exports = (env, args) => { const serve = isServe({ env }); @@ -28,7 +35,6 @@ module.exports = (env, args) => { config = merge(config, { context: __dirname, - resolve: { alias: { // Dependencies for the unsupported connection types in data-service @@ -90,12 +96,13 @@ module.exports = (env, args) => { vm: require.resolve('vm-browserify'), // TODO(NODE-5408): requires a polyfill to be able to parse connection - // string correctly at the moment, but we should also omit some - // depdendencies that might not be required for this to work in the - // browser + // string correctly at the moment url: require.resolve('whatwg-url'), // Make sure we're not getting multiple versions included 'whatwg-url': require.resolve('whatwg-url'), + // Heavy dependency of whatwg-url that we can replace in the browser + // environment + tr46: localPolyfill('tr46'), // Polyfills that are required for the driver to function in browser // environment @@ -140,6 +147,11 @@ module.exports = (env, args) => { process: [localPolyfill('process'), 'process'], }), ], + performance: { + hints: serve ? 'warning' : 'error', + maxEntrypointSize: MAX_COMPRESSION_FILE_SIZE, + maxAssetSize: MAX_COMPRESSION_FILE_SIZE, + }, }); if (serve) {