From 0e3401bc1c24fc1f6d7e04e9d2394d71b53a1845 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Tue, 31 Oct 2023 11:55:13 +0100 Subject: [PATCH] Improve Babel configuration and automatically load polyfills (#27333) --- .env.test | 4 +- .../mastodon/polyfills/base_polyfills.ts | 30 ----------- .../mastodon/polyfills/extra_polyfills.ts | 1 - app/javascript/mastodon/polyfills/index.ts | 27 ++-------- babel.config.js | 50 +++++++++---------- config/webpack/rules/index.js | 2 - config/webpack/rules/node_modules.js | 27 ---------- config/webpack/tests.js | 9 ---- package.json | 1 - yarn.lock | 5 -- 10 files changed, 30 insertions(+), 126 deletions(-) delete mode 100644 app/javascript/mastodon/polyfills/base_polyfills.ts delete mode 100644 config/webpack/rules/node_modules.js delete mode 100644 config/webpack/tests.js diff --git a/.env.test b/.env.test index 761d0d92106..2f8c1afd6e2 100644 --- a/.env.test +++ b/.env.test @@ -1,5 +1,5 @@ -# Node.js -NODE_ENV=tests +# In test, compile the NodeJS code as if we are in production +NODE_ENV=production # Federation LOCAL_DOMAIN=cb6e6126.ngrok.io LOCAL_HTTPS=true diff --git a/app/javascript/mastodon/polyfills/base_polyfills.ts b/app/javascript/mastodon/polyfills/base_polyfills.ts deleted file mode 100644 index 71565236cd0..00000000000 --- a/app/javascript/mastodon/polyfills/base_polyfills.ts +++ /dev/null @@ -1,30 +0,0 @@ -import 'core-js/features/object/assign'; -import 'core-js/features/object/values'; -import 'core-js/features/symbol'; -import 'core-js/features/promise/finally'; -import { decode as decodeBase64 } from '../utils/base64'; - -if (!Object.hasOwn(HTMLCanvasElement.prototype, 'toBlob')) { - const BASE64_MARKER = ';base64,'; - - Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { - value: function ( - this: HTMLCanvasElement, - callback: BlobCallback, - type = 'image/png', - quality: unknown, - ) { - const dataURL: string = this.toDataURL(type, quality); - let data; - - if (dataURL.includes(BASE64_MARKER)) { - const [, base64] = dataURL.split(BASE64_MARKER); - data = decodeBase64(base64); - } else { - [, data] = dataURL.split(','); - } - - callback(new Blob([data], { type })); - }, - }); -} diff --git a/app/javascript/mastodon/polyfills/extra_polyfills.ts b/app/javascript/mastodon/polyfills/extra_polyfills.ts index e6c69de8b55..a8d5530c5fc 100644 --- a/app/javascript/mastodon/polyfills/extra_polyfills.ts +++ b/app/javascript/mastodon/polyfills/extra_polyfills.ts @@ -1,2 +1 @@ -import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'; import 'requestidlecallback'; diff --git a/app/javascript/mastodon/polyfills/index.ts b/app/javascript/mastodon/polyfills/index.ts index e166c09d0e8..431c5b0f30f 100644 --- a/app/javascript/mastodon/polyfills/index.ts +++ b/app/javascript/mastodon/polyfills/index.ts @@ -4,39 +4,18 @@ import { loadIntlPolyfills } from './intl'; -function importBasePolyfills() { - return import(/* webpackChunkName: "base_polyfills" */ './base_polyfills'); -} - function importExtraPolyfills() { return import(/* webpackChunkName: "extra_polyfills" */ './extra_polyfills'); } export function loadPolyfills() { - const needsBasePolyfills = !( - 'toBlob' in HTMLCanvasElement.prototype && - 'assign' in Object && - 'values' in Object && - 'Symbol' in window && - 'finally' in Promise.prototype - ); - - // Latest version of Firefox and Safari do not have IntersectionObserver. - // Edge does not have requestIdleCallback. + // Safari does not have requestIdleCallback. // This avoids shipping them all the polyfills. - /* eslint-disable @typescript-eslint/no-unnecessary-condition -- those properties might not exist in old browsers, even if they are always here in types */ - const needsExtraPolyfills = !( - window.AbortController && - window.IntersectionObserver && - window.IntersectionObserverEntry && - 'isIntersecting' in IntersectionObserverEntry.prototype && - window.requestIdleCallback - ); - /* eslint-enable @typescript-eslint/no-unnecessary-condition */ + const needsExtraPolyfills = !window.requestIdleCallback; return Promise.all([ loadIntlPolyfills(), - needsBasePolyfills && importBasePolyfills(), + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- those properties might not exist in old browsers, even if they are always here in types needsExtraPolyfills && importExtraPolyfills(), ]); } diff --git a/babel.config.js b/babel.config.js index f53e5918cbe..71e72d71383 100644 --- a/babel.config.js +++ b/babel.config.js @@ -7,8 +7,8 @@ module.exports = (api) => { }; const envOptions = { - loose: true, - modules: false, + useBuiltIns: "usage", + corejs: { version: "3.30" }, debug: false, include: [ 'transform-numeric-separator', @@ -18,29 +18,14 @@ module.exports = (api) => { ], }; - const config = { - presets: [ - '@babel/preset-typescript', - ['@babel/react', reactOptions], - ['@babel/env', envOptions], - ], - plugins: [ - ['formatjs'], - 'preval', - ], - overrides: [ - { - test: /tesseract\.js/, - presets: [ - ['@babel/env', { ...envOptions, modules: 'commonjs' }], - ], - }, - ], - }; + const plugins = [ + ['formatjs'], + 'preval', + ]; switch (env) { case 'production': - config.plugins.push(...[ + plugins.push(...[ 'lodash', [ 'transform-react-remove-prop-types', @@ -63,14 +48,29 @@ module.exports = (api) => { ], ]); break; + case 'development': reactOptions.development = true; envOptions.debug = true; break; - case 'test': - envOptions.modules = 'commonjs'; - break; } + const config = { + presets: [ + '@babel/preset-typescript', + ['@babel/react', reactOptions], + ['@babel/env', envOptions], + ], + plugins, + overrides: [ + { + test: /tesseract\.js/, + presets: [ + ['@babel/env', { ...envOptions, modules: 'commonjs' }], + ], + }, + ], + }; + return config; }; diff --git a/config/webpack/rules/index.js b/config/webpack/rules/index.js index b026857887e..4be59f1b642 100644 --- a/config/webpack/rules/index.js +++ b/config/webpack/rules/index.js @@ -2,7 +2,6 @@ const babel = require('./babel'); const css = require('./css'); const file = require('./file'); const materialIcons = require('./material_icons'); -const nodeModules = require('./node_modules'); const tesseract = require('./tesseract'); // Webpack loaders are processed in reverse order @@ -13,6 +12,5 @@ module.exports = { file, tesseract, css, - nodeModules, babel, }; diff --git a/config/webpack/rules/node_modules.js b/config/webpack/rules/node_modules.js deleted file mode 100644 index 89c9d422d3e..00000000000 --- a/config/webpack/rules/node_modules.js +++ /dev/null @@ -1,27 +0,0 @@ -const { join } = require('path'); - -const { settings, env } = require('../configuration'); - -module.exports = { - test: /\.(js|mjs)$/, - include: /node_modules/, - exclude: [ - /@babel(?:\/|\\{1,2})runtime/, - /tesseract.js/, - ], - use: [ - { - loader: 'babel-loader', - options: { - babelrc: false, - plugins: [ - 'transform-react-remove-prop-types', - ], - cacheDirectory: join(settings.cache_path, 'babel-loader-node-modules'), - cacheCompression: env.NODE_ENV === 'production', - compact: false, - sourceMaps: false, - }, - }, - ], -}; diff --git a/config/webpack/tests.js b/config/webpack/tests.js deleted file mode 100644 index e6a8f1c2a95..00000000000 --- a/config/webpack/tests.js +++ /dev/null @@ -1,9 +0,0 @@ -// Note: You must restart bin/webpack-dev-server for changes to take effect - -const { merge } = require('webpack-merge'); - -const sharedConfig = require('./shared'); - -module.exports = merge(sharedConfig, { - mode: 'production', -}); diff --git a/package.json b/package.json index 12219b40829..f7201abe900 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ "@reduxjs/toolkit": "^1.9.5", "@renchap/compression-webpack-plugin": "^6.1.4", "@svgr/webpack": "^5.5.0", - "abortcontroller-polyfill": "^1.7.5", "arrow-key-navigation": "^1.2.0", "async-mutex": "^0.4.0", "autoprefixer": "^10.4.14", diff --git a/yarn.lock b/yarn.lock index 7ca344e6dd0..ed8928d58ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2904,11 +2904,6 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -abortcontroller-polyfill@^1.7.5: - version "1.7.5" - resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" - integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"