From 8c98f579b95992072474f02fe39865fda825379d Mon Sep 17 00:00:00 2001 From: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> Date: Tue, 16 Apr 2024 12:53:39 -0700 Subject: [PATCH] feat: migrate to preact/compat (#190) * fix: add chunk hashes to all assets except sw * test: update verify-dist tests * chore: remove unused component * tmp * feat: basic router implemented * fix: redirect page loads on subdomain * chore: cleaned up code * feat: minimal assets loaded on subdomain first-hit * chore: remove runtimeChunk from webpack * chore: remove unused deps * feat: migrate to preact/compat * chore: replace react with preact explicitly * chore: remove implicit type definitions * test: remove check css content thats in another chunk * chore: fix tests after merging code from #182 * chore: apply suggestions from code review * test: remove dist check for vendor-react asset --- .aegir.js | 2 +- package-lock.json | 80 ++++--------------------- package.json | 4 +- src/app.tsx | 4 +- src/components/Form.tsx | 6 +- src/components/Header.tsx | 4 +- src/components/collapsible.tsx | 4 +- src/components/input-validator.tsx | 8 +-- src/components/local-storage-input.tsx | 6 +- src/components/local-storage-toggle.tsx | 4 +- src/components/sw-ready-button.tsx | 6 +- src/context/config-context.tsx | 4 +- src/context/router-context.tsx | 6 +- src/context/service-worker-context.tsx | 4 +- src/index.tsx | 17 ++++-- src/pages/config.tsx | 4 +- src/pages/helper-ui.tsx | 4 +- src/pages/redirect-page.tsx | 6 +- test/node.ts | 1 - webpack.config.js | 11 +++- 20 files changed, 68 insertions(+), 117 deletions(-) diff --git a/.aegir.js b/.aegir.js index 9d08e54c..4824408d 100644 --- a/.aegir.js +++ b/.aegir.js @@ -14,7 +14,7 @@ export default { dependencyCheck: { ignore: [ // .jsx files aren't checked properly. - 'react-dom', + 'preact', // required by webpack 'webpack-cli', diff --git a/package-lock.json b/package-lock.json index 8632649d..73d5da4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,8 +16,7 @@ "@sgtpooki/file-type": "^1.0.1", "debug": "^4.3.4", "multiformats": "^13.1.0", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "preact": "^10.20.2" }, "devDependencies": { "@babel/core": "^7.24.3", @@ -25,7 +24,6 @@ "@babel/preset-react": "^7.24.1", "@babel/preset-typescript": "^7.24.1", "@playwright/test": "^1.42.1", - "@types/react": "^18.2.74", "aegir": "^42.2.5", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^12.0.2", @@ -5247,12 +5245,6 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", "dev": true }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true - }, "node_modules/@types/qs": { "version": "6.9.14", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", @@ -5265,16 +5257,6 @@ "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "dev": true }, - "node_modules/@types/react": { - "version": "18.2.74", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.74.tgz", - "integrity": "sha512-9AEqNZZyBx8OdZpxzQlaFEVCSFUM2YXJH46yPOiOpm078k6ZLOCcuAzGum/zK8YBwY+dbahVNbHrbgrAwIRlqw==", - "dev": true, - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, "node_modules/@types/responselike": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", @@ -8988,12 +8970,6 @@ "node": ">=4" } }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true - }, "node_modules/cycle": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", @@ -15924,7 +15900,8 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "4.1.0", @@ -16801,17 +16778,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", @@ -24835,6 +24801,15 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/preact": { + "version": "10.20.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.20.2.tgz", + "integrity": "sha512-S1d1ernz3KQ+Y2awUxKakpfOg2CEmJmwOP+6igPx6dgr6pgDvenqYviyokWso2rhHvGtTlWWnJDa7RaPbQerTg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -25222,29 +25197,6 @@ "node": ">=0.10.0" } }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, "node_modules/react-native-fetch-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/react-native-fetch-api/-/react-native-fetch-api-3.0.0.tgz", @@ -26774,14 +26726,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "devOptional": true }, - "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, "node_modules/schema-utils": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", diff --git a/package.json b/package.json index f2a47a44..0c90b2c7 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,7 @@ "@sgtpooki/file-type": "^1.0.1", "debug": "^4.3.4", "multiformats": "^13.1.0", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "preact": "^10.20.2" }, "devDependencies": { "@babel/core": "^7.24.3", @@ -57,7 +56,6 @@ "@babel/preset-react": "^7.24.1", "@babel/preset-typescript": "^7.24.1", "@playwright/test": "^1.42.1", - "@types/react": "^18.2.74", "aegir": "^42.2.5", "babel-loader": "^9.1.3", "copy-webpack-plugin": "^12.0.2", diff --git a/src/app.tsx b/src/app.tsx index 7f1515d8..3d4109e3 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,8 +1,8 @@ -import React, { Suspense } from 'react' +import React, { Suspense } from 'preact/compat' import { RouteContext } from './context/router-context.jsx' import './app.css' -function App (): JSX.Element { +function App (): React.JSX.Element { const { currentRoute } = React.useContext(RouteContext) return ( Loading...}> diff --git a/src/components/Form.tsx b/src/components/Form.tsx index 7abc168c..07fe250e 100644 --- a/src/components/Form.tsx +++ b/src/components/Form.tsx @@ -1,6 +1,6 @@ -import React from 'react' +import React from 'preact/compat' -export default ({ handleSubmit, requestPath, setRequestPath }): JSX.Element => ( +export default ({ handleSubmit, requestPath, setRequestPath }): React.JSX.Element => (
( type='text' placeholder='/ipfs/bafk.../path/to/file' required - value={requestPath} onChange={(e) => setRequestPath(e.target.value)} + value={requestPath} onChange={(e) => setRequestPath(e.currentTarget.value)} />
) diff --git a/src/components/Header.tsx b/src/components/Header.tsx index defac852..efe61024 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,9 +1,9 @@ -import React from 'react' +import React from 'preact/compat' import { RouteContext } from '../context/router-context.jsx' import gearIcon from '../gear-icon.svg' import ipfsLogo from '../ipfs-logo.svg' -export default function Header (): JSX.Element { +export default function Header (): React.JSX.Element { const { gotoPage } = React.useContext(RouteContext) return (
diff --git a/src/components/collapsible.tsx b/src/components/collapsible.tsx index 72203ca3..317c747e 100644 --- a/src/components/collapsible.tsx +++ b/src/components/collapsible.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useState } from 'preact/compat' export interface CollapsibleProps { children: React.ReactNode @@ -7,7 +7,7 @@ export interface CollapsibleProps { collapsed: boolean } -export function Collapsible ({ children, collapsedLabel, expandedLabel, collapsed }: CollapsibleProps): JSX.Element { +export function Collapsible ({ children, collapsedLabel, expandedLabel, collapsed }: CollapsibleProps): React.JSX.Element { const [cId] = useState(Math.random().toString(36).substring(7)) const [isCollapsed, setCollapsed] = useState(collapsed) diff --git a/src/components/input-validator.tsx b/src/components/input-validator.tsx index 4357901f..d91f90fa 100644 --- a/src/components/input-validator.tsx +++ b/src/components/input-validator.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ import { CID } from 'multiformats/cid' -import React from 'react' +import React from 'preact/compat' /** * Test files: @@ -22,8 +22,8 @@ import React from 'react' * */ -function ValidationMessage ({ cid, requestPath, pathNamespacePrefix, children }): JSX.Element { - let errorElement: JSX.Element | null = null +function ValidationMessage ({ cid, requestPath, pathNamespacePrefix, children }): React.JSX.Element { + let errorElement: React.JSX.Element | null = null if (requestPath == null || requestPath === '') { errorElement = Nothing to render yet. Enter an IPFS Path // bafkreiezuss4xkt5gu256vjccx7vocoksxk77vwmdrpwoumfbbxcy2zowq } else if (pathNamespacePrefix !== 'ipfs' && pathNamespacePrefix !== 'ipns') { @@ -49,7 +49,7 @@ function ValidationMessage ({ cid, requestPath, pathNamespacePrefix, children }) } -export default function InputValidator ({ requestPath }: { requestPath: string }): JSX.Element { +export default function InputValidator ({ requestPath }: { requestPath: string }): React.JSX.Element { /** * requestPath may be any of the following formats: * diff --git a/src/components/local-storage-input.tsx b/src/components/local-storage-input.tsx index 47379584..5909df1e 100644 --- a/src/components/local-storage-input.tsx +++ b/src/components/local-storage-input.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useState } from 'preact/compat' export interface LocalStorageInputProps extends React.DetailedHTMLProps, HTMLDivElement> { localStorageKey: string @@ -16,7 +16,7 @@ const defaultValidationFunction = (value: string): Error | null => { return err as Error } } -export default ({ localStorageKey, label, placeholder, validationFn, defaultValue, ...props }: LocalStorageInputProps): JSX.Element => { +export default ({ localStorageKey, label, placeholder, validationFn, defaultValue, ...props }: LocalStorageInputProps): React.JSX.Element => { const [value, setValue] = useState(localStorage.getItem(localStorageKey) ?? defaultValue) const [error, setError] = useState(null) @@ -47,7 +47,7 @@ export default ({ localStorageKey, label, placeholder, validationFn, defaultValu type='text' placeholder={placeholder} value={value} - onChange={(e) => { setValue(e.target.value) }} + onChange={(e) => { setValue(e.currentTarget.value) }} /> {error != null && {error.message}} diff --git a/src/components/local-storage-toggle.tsx b/src/components/local-storage-toggle.tsx index f2927b1d..6dfe26f9 100644 --- a/src/components/local-storage-toggle.tsx +++ b/src/components/local-storage-toggle.tsx @@ -1,7 +1,7 @@ /** Inspiration from https://dev.to/codebubb/create-a-simple-on-off-slide-toggle-with-css-db8 */ -import React, { useState } from 'react' +import React, { useState } from 'preact/compat' import './local-storage-toggle.css' interface LocalStorageToggleProps extends React.DetailedHTMLProps, HTMLDivElement> { @@ -17,7 +17,7 @@ export const LocalStorageToggle: React.FC = ({ localSto }) const handleChange = (event: React.ChangeEvent): void => { - const newValue = event.target.checked + const newValue = event.currentTarget.checked setIsChecked(newValue) localStorage.setItem(localStorageKey, String(newValue)) } diff --git a/src/components/sw-ready-button.tsx b/src/components/sw-ready-button.tsx index c74f824e..91f2ba92 100644 --- a/src/components/sw-ready-button.tsx +++ b/src/components/sw-ready-button.tsx @@ -1,13 +1,13 @@ -import React, { useContext, useMemo } from 'react' +import React, { useContext, useMemo } from 'preact/compat' import { ServiceWorkerContext } from '../context/service-worker-context.jsx' -type ButtonProps = JSX.IntrinsicElements['button'] +type ButtonProps = React.JSX.IntrinsicElements['button'] interface ServiceWorkerReadyButtonProps extends ButtonProps { label: string waitingLabel?: string } -export const ServiceWorkerReadyButton = ({ className, label, waitingLabel, ...props }: ServiceWorkerReadyButtonProps): JSX.Element => { +export const ServiceWorkerReadyButton = ({ className, label, waitingLabel, ...props }: ServiceWorkerReadyButtonProps): React.JSX.Element => { const { isServiceWorkerRegistered } = useContext(ServiceWorkerContext) const buttonClasses = new Set(['button-reset', 'pv3', 'tc', 'bn', 'white', 'w-100', 'cursor-disabled', 'bg-gray']) diff --git a/src/context/config-context.tsx b/src/context/config-context.tsx index 2cfa5788..aab46496 100644 --- a/src/context/config-context.tsx +++ b/src/context/config-context.tsx @@ -1,4 +1,4 @@ -import React, { createContext, useState } from 'react' +import React, { createContext, useState } from 'preact/compat' import { isConfigPage } from '../lib/is-config-page.js' const isLoadedInIframe = window.self !== window.top @@ -8,7 +8,7 @@ export const ConfigContext = createContext({ setConfigExpanded: (value: boolean) => {} }) -export const ConfigProvider = ({ children }: { children: JSX.Element[] | JSX.Element, expanded?: boolean }): JSX.Element => { +export const ConfigProvider = ({ children }: { children: React.JSX.Element[] | React.JSX.Element, expanded?: boolean }): React.JSX.Element => { const [isConfigExpanded, setConfigExpanded] = useState(isConfigPage(window.location.hash)) const isExplicitlyLoadedConfigPage = isConfigPage(window.location.hash) diff --git a/src/context/router-context.tsx b/src/context/router-context.tsx index 9c3cc423..17715ba8 100644 --- a/src/context/router-context.tsx +++ b/src/context/router-context.tsx @@ -1,10 +1,10 @@ -import React, { useCallback, useEffect } from 'react' +import React, { useCallback, useEffect } from 'preact/compat' export interface Route { default?: boolean path?: string shouldRender?(): Promise - component: React.LazyExoticComponent<(...args: any[]) => React.JSX.Element | null> + component(...args: any[]): React.JSX.Element | null } export const RouteContext = React.createContext<{ @@ -13,7 +13,7 @@ export const RouteContext = React.createContext<{ gotoPage(route?: string): void }>({ currentRoute: undefined, gotoPage: () => {} }) -export const RouterProvider = ({ children, routes }: { children: React.ReactNode, routes: Route[] }): JSX.Element => { +export const RouterProvider = ({ children, routes }: { children: React.ReactNode, routes: Route[] }): React.JSX.Element => { const [currentRoute, setCurrentRoute] = React.useState(undefined) /** * The default route is the first route in the list of routes, diff --git a/src/context/service-worker-context.tsx b/src/context/service-worker-context.tsx index 176f4a34..e8e55bef 100644 --- a/src/context/service-worker-context.tsx +++ b/src/context/service-worker-context.tsx @@ -12,7 +12,7 @@ * After the service worker is loaded. Usually any react code isn't loaded, but some edge cases are: * 1. The page being loaded using some /ip[fn]s/ url, but subdomain isolation is supported, so we need to redirect to the isolated origin */ -import React, { createContext, useEffect, useState } from 'react' +import React, { createContext, useEffect, useState } from 'preact/compat' import { getRedirectUrl, isDeregisterRequest } from '../lib/deregister-request.js' import { translateIpfsRedirectUrl } from '../lib/ipfs-hosted-redirect-utils.js' import { error, trace } from '../lib/logger.js' @@ -23,7 +23,7 @@ export const ServiceWorkerContext = createContext({ isServiceWorkerRegistered: false }) -export const ServiceWorkerProvider = ({ children }): JSX.Element => { +export const ServiceWorkerProvider = ({ children }): React.JSX.Element => { const [isServiceWorkerRegistered, setIsServiceWorkerRegistered] = useState(false) const windowLocation = translateIpfsRedirectUrl(window.location.href) diff --git a/src/index.tsx b/src/index.tsx index df8b4d84..e27d6c9d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,5 @@ -import React from 'react' -import ReactDOMClient from 'react-dom/client' +import 'preact/debug' +import React, { render } from 'preact/compat' import App from './app.jsx' import { ConfigProvider } from './context/config-context.jsx' import { RouterProvider, type Route } from './context/router-context.jsx' @@ -7,8 +7,12 @@ import { ServiceWorkerProvider } from './context/service-worker-context.jsx' // SW did not trigger for this request const container = document.getElementById('root') - -const root = ReactDOMClient.createRoot(container) +if (container == null) { + /** + * Should never happen, but preact types are not perfect + */ + throw new Error('could not find root container') +} const LazyConfig = React.lazy(async () => import('./pages/config.jsx')) const LazyHelperUi = React.lazy(async () => import('./pages/helper-ui.jsx')) @@ -20,7 +24,7 @@ const routes: Route[] = [ { shouldRender: async () => (await import('./lib/routing-render-checks')).shouldRenderRedirectPage(), component: LazyRedirectPage } ] -root.render( +render( @@ -29,5 +33,6 @@ root.render( - + , + container ) diff --git a/src/pages/config.tsx b/src/pages/config.tsx index 9ba67bb0..c08b0d64 100644 --- a/src/pages/config.tsx +++ b/src/pages/config.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from 'react' +import React, { useCallback, useEffect, useState } from 'preact/compat' import { Collapsible } from '../components/collapsible.jsx' import LocalStorageInput from '../components/local-storage-input.jsx' import { LocalStorageToggle } from '../components/local-storage-toggle.jsx' @@ -34,7 +34,7 @@ const stringValidationFn = (value: string): Error | null => { return null } -export default (): JSX.Element | null => { +export default (): React.JSX.Element | null => { const { gotoPage } = React.useContext(RouteContext) const [error, setError] = useState(null) diff --git a/src/pages/helper-ui.tsx b/src/pages/helper-ui.tsx index a579e8f0..94abf823 100644 --- a/src/pages/helper-ui.tsx +++ b/src/pages/helper-ui.tsx @@ -1,10 +1,10 @@ -import React, { useState, useEffect } from 'react' +import React, { useState, useEffect } from 'preact/compat' import Form from '../components/Form.jsx' import Header from '../components/Header.jsx' import CidRenderer from '../components/input-validator.jsx' import { LOCAL_STORAGE_KEYS } from '../lib/local-storage.js' -export default function (): JSX.Element { +export default function (): React.JSX.Element { const [requestPath, setRequestPath] = useState(localStorage.getItem(LOCAL_STORAGE_KEYS.forms.requestPath) ?? '') useEffect(() => { diff --git a/src/pages/redirect-page.tsx b/src/pages/redirect-page.tsx index 86e18682..bba3c0e1 100644 --- a/src/pages/redirect-page.tsx +++ b/src/pages/redirect-page.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useEffect, useMemo, useState } from 'react' +import React, { useContext, useEffect, useMemo, useState } from 'preact/compat' import { ServiceWorkerReadyButton } from '../components/sw-ready-button.jsx' import { ServiceWorkerContext } from '../context/service-worker-context.jsx' import { HeliaServiceWorkerCommsChannel } from '../lib/channel.js' @@ -7,7 +7,7 @@ import { getSubdomainParts } from '../lib/get-subdomain-parts.js' import { isConfigPage } from '../lib/is-config-page.js' import { error, trace } from '../lib/logger.js' -const ConfigIframe = (): JSX.Element => { +const ConfigIframe = (): React.JSX.Element => { const { parentDomain } = getSubdomainParts(window.location.href) const portString = window.location.port === '' ? '' : `:${window.location.port}` @@ -20,7 +20,7 @@ const ConfigIframe = (): JSX.Element => { const channel = new HeliaServiceWorkerCommsChannel('WINDOW') -export default function RedirectPage ({ showConfigIframe = true }: { showConfigIframe?: boolean }): JSX.Element { +export default function RedirectPage ({ showConfigIframe = true }: { showConfigIframe?: boolean }): React.JSX.Element { const [isAutoReloadEnabled, setIsAutoReloadEnabled] = useState(false) const { isServiceWorkerRegistered } = useContext(ServiceWorkerContext) diff --git a/test/node.ts b/test/node.ts index f0ebb0eb..e9bd7902 100755 --- a/test/node.ts +++ b/test/node.ts @@ -46,7 +46,6 @@ describe(`verify-dist at ${distRoot}`, () => { /ipfs-sw-styles-.*\.css/, /ipfs-sw-styles-.*\.js/, /ipfs-sw-main-.*\.js/, - /ipfs-sw-vendor-react-.*\.js/, 'id="root"' ] }, diff --git a/webpack.config.js b/webpack.config.js index 6b088f63..4d13b03d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -27,9 +27,9 @@ const splitChunks = { priority: 100, // anything the sw needs should be in the sw chunk chunks: 'async' }, - reactVendor: { - test: /[\\/]node_modules[\\/](react|react-dom|react-router-dom)[\\/]/, - name: 'vendor-react', + preactVendor: { + test: /[\\/]node_modules[\\/](preact)[\\/]/, + name: 'vendor-preact', chunks: 'initial' } } @@ -107,6 +107,11 @@ const prod = { }) ], splitChunks + }, + externalsType: 'window', + externals: { + // remove preact debug on production builds + 'preact/debug': '' } }