From 075cca59913471a8e7520f14c50c97aeac095c49 Mon Sep 17 00:00:00 2001 From: Steve Repsher Date: Fri, 24 Nov 2023 09:57:21 -0500 Subject: [PATCH] Inject polyfills where used (#18719) --- .../babel-plugins/custom-polyfill-plugin.js | 56 +++++++++++++++++++ build-scripts/bundle.cjs | 13 +++-- package.json | 1 + .../data-table/sort-filter-worker.ts | 2 - src/entrypoints/app.ts | 2 + src/entrypoints/core.ts | 2 - src/html/_js_base.html.template | 1 - src/html/index.html.template | 9 +-- src/resources/compatibility.ts | 5 -- src/resources/markdown-worker.ts | 2 - yarn.lock | 3 +- 11 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 build-scripts/babel-plugins/custom-polyfill-plugin.js diff --git a/build-scripts/babel-plugins/custom-polyfill-plugin.js b/build-scripts/babel-plugins/custom-polyfill-plugin.js new file mode 100644 index 0000000000..83ce9235f7 --- /dev/null +++ b/build-scripts/babel-plugins/custom-polyfill-plugin.js @@ -0,0 +1,56 @@ +import defineProvider from "@babel/helper-define-polyfill-provider"; + +// List of polyfill keys with supported browser targets for the functionality +const PolyfillSupport = { + fetch: { + android: 42, + chrome: 42, + edge: 14, + firefox: 39, + ios: 10.3, + opera: 29, + opera_mobile: 29, + safari: 10.1, + samsung: 4.0, + }, + proxy: { + android: 49, + chrome: 49, + edge: 12, + firefox: 18, + ios: 10.0, + opera: 36, + opera_mobile: 36, + safari: 10.0, + samsung: 5.0, + }, +}; + +// Map of global variables and/or instance and static properties to the +// corresponding polyfill key and actual module to import +const polyfillMap = { + global: { + Proxy: { key: "proxy", module: "proxy-polyfill" }, + fetch: { key: "fetch", module: "unfetch/polyfill" }, + }, + instance: {}, + static: {}, +}; + +// Create plugin using the same factory as for CoreJS +export default defineProvider( + ({ createMetaResolver, debug, shouldInjectPolyfill }) => { + const resolvePolyfill = createMetaResolver(polyfillMap); + return { + name: "HA Custom", + polyfills: PolyfillSupport, + usageGlobal(meta, utils) { + const polyfill = resolvePolyfill(meta); + if (polyfill && shouldInjectPolyfill(polyfill.desc.key)) { + debug(polyfill.desc.key); + utils.injectGlobalImport(polyfill.desc.module); + } + }, + }; + } +); diff --git a/build-scripts/bundle.cjs b/build-scripts/bundle.cjs index 684e5aa45a..8ba8d57e43 100644 --- a/build-scripts/bundle.cjs +++ b/build-scripts/bundle.cjs @@ -31,8 +31,6 @@ module.exports.emptyPackages = ({ latestBuild, isHassioBuild }) => require.resolve( path.resolve(paths.polymer_dir, "src/resources/compatibility.ts") ), - // This polyfill is loaded in workers to support ES5, filter it out. - latestBuild && require.resolve("proxy-polyfill/src/index.js"), // Icons in supervisor conflict with icons in HA so we don't load. isHassioBuild && require.resolve( @@ -91,8 +89,8 @@ module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({ [ "@babel/preset-env", { - useBuiltIns: latestBuild ? false : "entry", - corejs: latestBuild ? false : { version: "3.33", proposals: true }, + useBuiltIns: latestBuild ? false : "usage", + corejs: latestBuild ? false : "3.33", bugfixes: true, shippedProposals: true, }, @@ -110,6 +108,13 @@ module.exports.babelOptions = ({ latestBuild, isProdBuild, isTestBuild }) => ({ ignoreModuleNotFound: true, }, ], + [ + path.resolve( + paths.polymer_dir, + "build-scripts/babel-plugins/custom-polyfill-plugin.js" + ), + { method: "usage-global" }, + ], // Minify template literals for production isProdBuild && [ "template-html-minifier", diff --git a/package.json b/package.json index a5c015dc75..6fac1f3ee4 100644 --- a/package.json +++ b/package.json @@ -156,6 +156,7 @@ }, "devDependencies": { "@babel/core": "7.23.3", + "@babel/helper-define-polyfill-provider": "0.4.3", "@babel/plugin-proposal-decorators": "7.23.3", "@babel/plugin-transform-runtime": "7.23.3", "@babel/preset-env": "7.23.3", diff --git a/src/components/data-table/sort-filter-worker.ts b/src/components/data-table/sort-filter-worker.ts index babb0120b6..7b6d840162 100644 --- a/src/components/data-table/sort-filter-worker.ts +++ b/src/components/data-table/sort-filter-worker.ts @@ -1,6 +1,4 @@ -// To use comlink under ES5 import { expose } from "comlink"; -import "proxy-polyfill"; import { stringCompare } from "../../common/string/compare"; import type { ClonedDataTableColumnData, diff --git a/src/entrypoints/app.ts b/src/entrypoints/app.ts index 21230d7cb6..d47257c91a 100644 --- a/src/entrypoints/app.ts +++ b/src/entrypoints/app.ts @@ -1,3 +1,5 @@ +// Compat needs to be first import +import "../resources/compatibility"; import "@webcomponents/scoped-custom-element-registry/scoped-custom-element-registry.min"; import "../layouts/home-assistant"; diff --git a/src/entrypoints/core.ts b/src/entrypoints/core.ts index a7b660afe6..6ca3c28053 100644 --- a/src/entrypoints/core.ts +++ b/src/entrypoints/core.ts @@ -1,5 +1,3 @@ -// Compat needs to be first import -import "../resources/compatibility"; import { Auth, Connection, diff --git a/src/html/_js_base.html.template b/src/html/_js_base.html.template index 9ad8a1c387..690cd0cd7a 100644 --- a/src/html/_js_base.html.template +++ b/src/html/_js_base.html.template @@ -2,7 +2,6 @@ function _ls(src, notCustom) { var script = document.createElement("script"); if (notCustom) { - script.async = false; script.crossOrigin = "use-credentials"; } script.src = src; diff --git a/src/html/index.html.template b/src/html/index.html.template index efcea2af68..e396cfadbd 100644 --- a/src/html/index.html.template +++ b/src/html/index.html.template @@ -77,14 +77,11 @@