From e20e79174c054708552e537151cd021171086149 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Barr=C3=A9?= Date: Mon, 2 Jan 2023 23:59:46 +0100 Subject: [PATCH] feat: invalidate message and fix HMR for HOC, class component & styled component --- package.json | 2 +- packages/plugin-react/README.md | 8 + packages/plugin-react/package.json | 7 +- .../plugin-react/scripts/copyRefreshUtils.ts | 3 + packages/plugin-react/src/fast-refresh.ts | 68 +--- packages/plugin-react/src/refreshUtils.js | 57 ++++ packages/plugin-react/tsconfig.json | 2 +- playground/package.json | 1 - playground/react-emotion/App.jsx | 20 +- playground/react-emotion/Counter.jsx | 23 ++ .../react-emotion/__tests__/react.spec.ts | 11 +- playground/react-emotion/package.json | 1 + playground/react/__tests__/react.spec.ts | 4 +- playground/shims.d.ts | 5 - playground/test-utils.ts | 8 +- pnpm-lock.yaml | 307 ++++-------------- 16 files changed, 195 insertions(+), 332 deletions(-) create mode 100644 packages/plugin-react/scripts/copyRefreshUtils.ts create mode 100644 packages/plugin-react/src/refreshUtils.js create mode 100644 playground/react-emotion/Counter.jsx diff --git a/package.json b/package.json index 8e238618..29e438d9 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "tsx": "^3.12.2", "typescript": "^4.6.4", "unbuild": "^1.1.1", - "vite": "^4.0.4", + "vite": "^4.1.0-beta.0", "vitest": "^0.27.3" }, "simple-git-hooks": { diff --git a/packages/plugin-react/README.md b/packages/plugin-react/README.md index e772b2e4..ea2923d5 100644 --- a/packages/plugin-react/README.md +++ b/packages/plugin-react/README.md @@ -105,3 +105,11 @@ Otherwise, you'll probably get this error: ``` Uncaught Error: @vitejs/plugin-react can't detect preamble. Something is wrong. ``` + +## Consistent components exports + +For React refresh to work correctly, your file should only export React components. You can find a good explanation in the [Gatsby docs](https://www.gatsbyjs.com/docs/reference/local-development/fast-refresh/#how-it-works). + +If an incompatible change in exports is found, the module will be invalidated and HMR will propagate. To make it easier to export simple constants alongside your component, the module is only invalidated when their value changes. + +You can catch mistakes and get more detailed warning with this [eslint rule](https://github.com/ArnaudBarre/eslint-plugin-react-refresh). diff --git a/packages/plugin-react/package.json b/packages/plugin-react/package.json index eb0e7c99..52ab1b32 100644 --- a/packages/plugin-react/package.json +++ b/packages/plugin-react/package.json @@ -4,7 +4,8 @@ "license": "MIT", "author": "Evan You", "contributors": [ - "Alec Larson" + "Alec Larson", + "Arnaud Barré" ], "files": [ "dist" @@ -21,7 +22,7 @@ }, "scripts": { "dev": "unbuild --stub", - "build": "unbuild && pnpm run patch-cjs", + "build": "unbuild && pnpm run patch-cjs && tsx scripts/copyRefreshUtils.ts", "patch-cjs": "tsx ../../scripts/patchCJS.ts", "prepublishOnly": "npm run build" }, @@ -45,6 +46,6 @@ "react-refresh": "^0.14.0" }, "peerDependencies": { - "vite": "^4.0.0" + "vite": "^4.1.0-beta.0" } } diff --git a/packages/plugin-react/scripts/copyRefreshUtils.ts b/packages/plugin-react/scripts/copyRefreshUtils.ts new file mode 100644 index 00000000..977f6442 --- /dev/null +++ b/packages/plugin-react/scripts/copyRefreshUtils.ts @@ -0,0 +1,3 @@ +import { copyFileSync } from 'node:fs' + +copyFileSync('src/refreshUtils.js', 'dist/refreshUtils.js') diff --git a/packages/plugin-react/src/fast-refresh.ts b/packages/plugin-react/src/fast-refresh.ts index 9503d5ce..dd0d8089 100644 --- a/packages/plugin-react/src/fast-refresh.ts +++ b/packages/plugin-react/src/fast-refresh.ts @@ -16,14 +16,7 @@ const runtimeFilePath = path.join( export const runtimeCode = ` const exports = {} ${fs.readFileSync(runtimeFilePath, 'utf-8')} -function debounce(fn, delay) { - let handle - return () => { - clearTimeout(handle) - handle = setTimeout(fn, delay) - } -} -exports.performReactRefresh = debounce(exports.performReactRefresh, 16) +${fs.readFileSync(_require.resolve('./refreshUtils.js'), 'utf-8')} export default exports ` @@ -57,58 +50,25 @@ if (import.meta.hot) { window.$RefreshSig$ = RefreshRuntime.createSignatureFunctionForTransform; }`.replace(/\n+/g, '') -const timeout = ` - if (!window.__vite_plugin_react_timeout) { - window.__vite_plugin_react_timeout = setTimeout(() => { - window.__vite_plugin_react_timeout = 0; - RefreshRuntime.performReactRefresh(); - }, 30); - } -` - -const checkAndAccept = ` -function isReactRefreshBoundary(mod) { - if (mod == null || typeof mod !== 'object') { - return false; - } - let hasExports = false; - let areAllExportsComponents = true; - for (const exportName in mod) { - hasExports = true; - if (exportName === '__esModule') { - continue; - } - const desc = Object.getOwnPropertyDescriptor(mod, exportName); - if (desc && desc.get) { - // Don't invoke getters as they may have side effects. - return false; - } - const exportValue = mod[exportName]; - if (!RefreshRuntime.isLikelyComponentType(exportValue)) { - areAllExportsComponents = false; - } - } - return hasExports && areAllExportsComponents; -} - -import.meta.hot.accept(mod => { - if (!mod) return; - if (isReactRefreshBoundary(mod)) { - ${timeout} - } else { - import.meta.hot.invalidate(); - } -}); -` - const footer = ` if (import.meta.hot) { window.$RefreshReg$ = prevRefreshReg; window.$RefreshSig$ = prevRefreshSig; - ${checkAndAccept} + import(/* @vite-ignore */ import.meta.url).then((currentExports) => { + RefreshRuntime.registerExportsForReactRefresh(__SOURCE__, currentExports); + import.meta.hot.accept((nextExports) => { + if (!nextExports) return; + const invalidateMessage = RefreshRuntime.validateRefreshBoundaryAndEnqueueUpdate(currentExports, nextExports); + if (invalidateMessage) import.meta.hot.invalidate(invalidateMessage); + }); + }); }` export function addRefreshWrapper(code: string, id: string): string { - return header.replace('__SOURCE__', JSON.stringify(id)) + code + footer + return ( + header.replace('__SOURCE__', JSON.stringify(id)) + + code + + footer.replace('__SOURCE__', JSON.stringify(id)) + ) } diff --git a/packages/plugin-react/src/refreshUtils.js b/packages/plugin-react/src/refreshUtils.js new file mode 100644 index 00000000..2521181e --- /dev/null +++ b/packages/plugin-react/src/refreshUtils.js @@ -0,0 +1,57 @@ +function debounce(fn, delay) { + let handle + return () => { + clearTimeout(handle) + handle = setTimeout(fn, delay) + } +} + +const enqueueUpdate = debounce(exports.performReactRefresh, 16) + +// Taken from https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/lib/runtime/RefreshUtils.js#L141 +// This allows to resister components not detected by SWC like styled component +function registerExportsForReactRefresh(filename, moduleExports) { + for (const key in moduleExports) { + if (key === '__esModule') continue + const exportValue = moduleExports[key] + if (exports.isLikelyComponentType(exportValue)) { + exports.register(exportValue, filename + ' ' + key) + } + } +} + +function validateRefreshBoundaryAndEnqueueUpdate(prevExports, nextExports) { + if (!predicateOnExport(prevExports, (key) => !!nextExports[key])) { + return 'Could not Fast Refresh (export removed)' + } + + let hasExports = false + const allExportsAreComponentsOrUnchanged = predicateOnExport( + nextExports, + (key, value) => { + hasExports = true + if (exports.isLikelyComponentType(value)) return true + if (!prevExports[key]) return false + return prevExports[key] === nextExports[key] + }, + ) + if (hasExports && allExportsAreComponentsOrUnchanged) { + enqueueUpdate() + } else { + return 'Could not Fast Refresh. Learn more at https://github.com/vitejs/vite-plugin-react#consistent-components-exports' + } +} + +function predicateOnExport(moduleExports, predicate) { + for (const key in moduleExports) { + if (key === '__esModule') continue + const desc = Object.getOwnPropertyDescriptor(moduleExports, key) + if (desc && desc.get) return false + if (!predicate(key, moduleExports[key])) return false + } + return true +} + +exports.registerExportsForReactRefresh = registerExportsForReactRefresh +exports.validateRefreshBoundaryAndEnqueueUpdate = + validateRefreshBoundaryAndEnqueueUpdate diff --git a/packages/plugin-react/tsconfig.json b/packages/plugin-react/tsconfig.json index 3a3117f2..5785b0e7 100644 --- a/packages/plugin-react/tsconfig.json +++ b/packages/plugin-react/tsconfig.json @@ -1,5 +1,5 @@ { - "include": ["src"], + "include": ["src", "scripts"], "exclude": ["**/*.spec.ts"], "compilerOptions": { "outDir": "dist", diff --git a/playground/package.json b/playground/package.json index f0c5603e..799ac692 100644 --- a/playground/package.json +++ b/playground/package.json @@ -3,7 +3,6 @@ "private": true, "version": "1.0.0", "devDependencies": { - "css-color-names": "^1.0.1", "kill-port": "^1.6.1", "node-fetch": "^3.3.0" } diff --git a/playground/react-emotion/App.jsx b/playground/react-emotion/App.jsx index b3715369..b1d3f58e 100644 --- a/playground/react-emotion/App.jsx +++ b/playground/react-emotion/App.jsx @@ -1,24 +1,8 @@ import { useState } from 'react' -import { css } from '@emotion/react' - import _Switch from 'react-switch' +import { Counter, StyledCode } from './Counter' const Switch = _Switch.default || _Switch -export function Counter() { - const [count, setCount] = useState(0) - - return ( - - ) -} - function FragmentTest() { const [checked, setChecked] = useState(false) return ( @@ -38,7 +22,7 @@ function App() {

Hello Vite + React + @emotion/react

- Edit App.jsx and save to test HMR updates. + Edit App.jsx and save to test HMR updates.

setCount((count) => count + 1)} + > + count is: {count} + + ) +} diff --git a/playground/react-emotion/__tests__/react.spec.ts b/playground/react-emotion/__tests__/react.spec.ts index f4625daa..222c9a74 100644 --- a/playground/react-emotion/__tests__/react.spec.ts +++ b/playground/react-emotion/__tests__/react.spec.ts @@ -1,5 +1,5 @@ import { expect, test } from 'vitest' -import { editFile, page, untilUpdated } from '~utils' +import { editFile, getColor, page, untilUpdated } from '~utils' test('should render', async () => { expect(await page.textContent('h1')).toMatch( @@ -18,6 +18,13 @@ test('should hmr', async () => { code.replace('Vite + React + @emotion/react', 'Updated'), ) await untilUpdated(() => page.textContent('h1'), 'Hello Updated') + + editFile('Counter.jsx', (code) => + code.replace('color: #646cff;', 'color: #d26ac2;'), + ) + + await untilUpdated(() => getColor('code'), '#d26ac2') + // preserve state expect(await page.textContent('button')).toMatch('count is: 1') }) @@ -35,7 +42,7 @@ test('should update button style', async () => { expect(await getButtonBorderStyle()).toMatch('2px solid rgb(0, 0, 0)') - editFile('App.jsx', (code) => + editFile('Counter.jsx', (code) => code.replace('border: 2px solid #000', 'border: 4px solid red'), ) diff --git a/playground/react-emotion/package.json b/playground/react-emotion/package.json index 58f35cde..63eea0af 100644 --- a/playground/react-emotion/package.json +++ b/playground/react-emotion/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@emotion/react": "^11.10.5", + "@emotion/styled": "^11.10.5", "react": "^18.2.0", "react-dom": "^18.2.0", "react-switch": "^7.0.0" diff --git a/playground/react/__tests__/react.spec.ts b/playground/react/__tests__/react.spec.ts index d9b4d01e..120852ca 100644 --- a/playground/react/__tests__/react.spec.ts +++ b/playground/react/__tests__/react.spec.ts @@ -78,7 +78,7 @@ if (!isBuild) { code.replace('An Object', 'Updated'), ), [ - '[vite] invalidate /hmr/no-exported-comp.jsx', + '[vite] invalidate /hmr/no-exported-comp.jsx: Could not Fast Refresh. Learn more at https://github.com/vitejs/vite-plugin-react#consistent-components-exports', '[vite] hot updated: /hmr/no-exported-comp.jsx', '[vite] hot updated: /hmr/parent.jsx', 'Parent rendered', @@ -103,7 +103,7 @@ if (!isBuild) { code.replace('context provider', 'context provider updated'), ), [ - '[vite] invalidate /context/CountProvider.jsx', + '[vite] invalidate /context/CountProvider.jsx: Could not Fast Refresh. Learn more at https://github.com/vitejs/vite-plugin-react#consistent-components-exports', '[vite] hot updated: /context/CountProvider.jsx', '[vite] hot updated: /App.jsx', '[vite] hot updated: /context/ContextButton.jsx', diff --git a/playground/shims.d.ts b/playground/shims.d.ts index 8f1b2bde..fbc5dbe1 100644 --- a/playground/shims.d.ts +++ b/playground/shims.d.ts @@ -1,8 +1,3 @@ -declare module 'css-color-names' { - const colors: Record - export default colors -} - declare module 'kill-port' { const kill: (port: number) => Promise export default kill diff --git a/playground/test-utils.ts b/playground/test-utils.ts index 2c9de3fa..4b13bcfe 100644 --- a/playground/test-utils.ts +++ b/playground/test-utils.ts @@ -3,7 +3,6 @@ import fs from 'node:fs' import path from 'node:path' -import colors from 'css-color-names' import type { ConsoleMessage, ElementHandle } from 'playwright-chromium' import { expect } from 'vitest' import { isBuild, page, testDir } from './vitestSetup' @@ -18,11 +17,6 @@ export const hmrPorts = { 'ssr-react': 24685, } -const hexToNameMap: Record = {} -Object.keys(colors).forEach((color) => { - hexToNameMap[colors[color]] = color -}) - function componentToHex(c: number): string { const hex = c.toString(16) return hex.length === 1 ? '0' + hex : hex @@ -55,7 +49,7 @@ async function toEl(el: string | ElementHandle): Promise { export async function getColor(el: string | ElementHandle): Promise { el = await toEl(el) const rgb = await el.evaluate((el) => getComputedStyle(el as Element).color) - return hexToNameMap[rgbToHex(rgb)] ?? rgb + return rgbToHex(rgb) } export async function getBg(el: string | ElementHandle): Promise { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1ef5f353..26380853 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,7 +29,7 @@ importers: tsx: ^3.12.2 typescript: ^4.6.4 unbuild: ^1.1.1 - vite: ^4.0.4 + vite: ^4.1.0-beta.0 vitest: ^0.27.3 devDependencies: '@types/babel__core': 7.20.0 @@ -57,7 +57,7 @@ importers: tsx: 3.12.2 typescript: 4.9.3 unbuild: 1.1.1 - vite: 4.0.4_@types+node@18.11.18 + vite: 4.1.0-beta.0_@types+node@18.11.18 vitest: 0.27.3 packages/plugin-react: @@ -76,11 +76,9 @@ importers: playground: specifiers: - css-color-names: ^1.0.1 kill-port: ^1.6.1 node-fetch: ^3.3.0 devDependencies: - css-color-names: 1.0.1 kill-port: 1.6.1 node-fetch: 3.3.0 @@ -113,12 +111,14 @@ importers: '@babel/plugin-proposal-pipeline-operator': ^7.18.9 '@emotion/babel-plugin': ^11.10.5 '@emotion/react': ^11.10.5 + '@emotion/styled': ^11.10.5 '@vitejs/plugin-react': workspace:* react: ^18.2.0 react-dom: ^18.2.0 react-switch: ^7.0.0 dependencies: '@emotion/react': 11.10.5_react@18.2.0 + '@emotion/styled': 11.10.5_hp5f5nkljdiwilp4rgxyefcplu react: 18.2.0 react-dom: 18.2.0_react@18.2.0 react-switch: 7.0.0_biqbaboplfbrettd7655fr4n2y @@ -446,6 +446,12 @@ packages: /@emotion/hash/0.9.0: resolution: {integrity: sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==} + /@emotion/is-prop-valid/1.2.0: + resolution: {integrity: sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==} + dependencies: + '@emotion/memoize': 0.8.0 + dev: false + /@emotion/memoize/0.8.0: resolution: {integrity: sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==} @@ -485,6 +491,29 @@ packages: resolution: {integrity: sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==} dev: false + /@emotion/styled/11.10.5_hp5f5nkljdiwilp4rgxyefcplu: + resolution: {integrity: sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw==} + peerDependencies: + '@babel/core': ^7.0.0 + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@babel/core': + optional: true + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.20.6 + '@emotion/babel-plugin': 11.10.5 + '@emotion/is-prop-valid': 1.2.0 + '@emotion/react': 11.10.5_react@18.2.0 + '@emotion/serialize': 1.1.1 + '@emotion/use-insertion-effect-with-fallbacks': 1.0.0_react@18.2.0 + '@emotion/utils': 1.2.0 + react: 18.2.0 + dev: false + /@emotion/unitless/0.8.0: resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==} @@ -542,15 +571,6 @@ packages: dev: true optional: true - /@esbuild/android-arm/0.16.3: - resolution: {integrity: sha512-mueuEoh+s1eRbSJqq9KNBQwI4QhQV6sRXIfTyLXSHGMpyew61rOK4qY21uKbXl1iBoMb0AdL1deWFCQVlN2qHA==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-arm64/0.16.17: resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} engines: {node: '>=12'} @@ -560,15 +580,6 @@ packages: dev: true optional: true - /@esbuild/android-arm64/0.16.3: - resolution: {integrity: sha512-RolFVeinkeraDvN/OoRf1F/lP0KUfGNb5jxy/vkIMeRRChkrX/HTYN6TYZosRJs3a1+8wqpxAo5PI5hFmxyPRg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/android-x64/0.16.17: resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} engines: {node: '>=12'} @@ -578,15 +589,6 @@ packages: dev: true optional: true - /@esbuild/android-x64/0.16.3: - resolution: {integrity: sha512-SFpTUcIT1bIJuCCBMCQWq1bL2gPTjWoLZdjmIhjdcQHaUfV41OQfho6Ici5uvvkMmZRXIUGpM3GxysP/EU7ifQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true - optional: true - /@esbuild/darwin-arm64/0.16.17: resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} engines: {node: '>=12'} @@ -596,15 +598,6 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64/0.16.3: - resolution: {integrity: sha512-DO8WykMyB+N9mIDfI/Hug70Dk1KipavlGAecxS3jDUwAbTpDXj0Lcwzw9svkhxfpCagDmpaTMgxWK8/C/XcXvw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - /@esbuild/darwin-x64/0.16.17: resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} engines: {node: '>=12'} @@ -614,15 +607,6 @@ packages: dev: true optional: true - /@esbuild/darwin-x64/0.16.3: - resolution: {integrity: sha512-uEqZQ2omc6BvWqdCiyZ5+XmxuHEi1SPzpVxXCSSV2+Sh7sbXbpeNhHIeFrIpRjAs0lI1FmA1iIOxFozKBhKgRQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - /@esbuild/freebsd-arm64/0.16.17: resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} engines: {node: '>=12'} @@ -632,15 +616,6 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64/0.16.3: - resolution: {integrity: sha512-nJansp3sSXakNkOD5i5mIz2Is/HjzIhFs49b1tjrPrpCmwgBmH9SSzhC/Z1UqlkivqMYkhfPwMw1dGFUuwmXhw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/freebsd-x64/0.16.17: resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} engines: {node: '>=12'} @@ -650,15 +625,6 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64/0.16.3: - resolution: {integrity: sha512-TfoDzLw+QHfc4a8aKtGSQ96Wa+6eimljjkq9HKR0rHlU83vw8aldMOUSJTUDxbcUdcgnJzPaX8/vGWm7vyV7ug==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-arm/0.16.17: resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} engines: {node: '>=12'} @@ -668,15 +634,6 @@ packages: dev: true optional: true - /@esbuild/linux-arm/0.16.3: - resolution: {integrity: sha512-VwswmSYwVAAq6LysV59Fyqk3UIjbhuc6wb3vEcJ7HEJUtFuLK9uXWuFoH1lulEbE4+5GjtHi3MHX+w1gNHdOWQ==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-arm64/0.16.17: resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} engines: {node: '>=12'} @@ -686,15 +643,6 @@ packages: dev: true optional: true - /@esbuild/linux-arm64/0.16.3: - resolution: {integrity: sha512-7I3RlsnxEFCHVZNBLb2w7unamgZ5sVwO0/ikE2GaYvYuUQs9Qte/w7TqWcXHtCwxvZx/2+F97ndiUQAWs47ZfQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-ia32/0.16.17: resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} engines: {node: '>=12'} @@ -704,15 +652,6 @@ packages: dev: true optional: true - /@esbuild/linux-ia32/0.16.3: - resolution: {integrity: sha512-X8FDDxM9cqda2rJE+iblQhIMYY49LfvW4kaEjoFbTTQ4Go8G96Smj2w3BRTwA8IHGoi9dPOPGAX63dhuv19UqA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-loong64/0.15.18: resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} engines: {node: '>=12'} @@ -731,15 +670,6 @@ packages: dev: true optional: true - /@esbuild/linux-loong64/0.16.3: - resolution: {integrity: sha512-hIbeejCOyO0X9ujfIIOKjBjNAs9XD/YdJ9JXAy1lHA+8UXuOqbFe4ErMCqMr8dhlMGBuvcQYGF7+kO7waj2KHw==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-mips64el/0.16.17: resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} engines: {node: '>=12'} @@ -749,15 +679,6 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el/0.16.3: - resolution: {integrity: sha512-znFRzICT/V8VZQMt6rjb21MtAVJv/3dmKRMlohlShrbVXdBuOdDrGb+C2cZGQAR8RFyRe7HS6klmHq103WpmVw==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-ppc64/0.16.17: resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} engines: {node: '>=12'} @@ -767,15 +688,6 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64/0.16.3: - resolution: {integrity: sha512-EV7LuEybxhXrVTDpbqWF2yehYRNz5e5p+u3oQUS2+ZFpknyi1NXxr8URk4ykR8Efm7iu04//4sBg249yNOwy5Q==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-riscv64/0.16.17: resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} engines: {node: '>=12'} @@ -785,15 +697,6 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64/0.16.3: - resolution: {integrity: sha512-uDxqFOcLzFIJ+r/pkTTSE9lsCEaV/Y6rMlQjUI9BkzASEChYL/aSQjZjchtEmdnVxDKETnUAmsaZ4pqK1eE5BQ==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-s390x/0.16.17: resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} engines: {node: '>=12'} @@ -803,15 +706,6 @@ packages: dev: true optional: true - /@esbuild/linux-s390x/0.16.3: - resolution: {integrity: sha512-NbeREhzSxYwFhnCAQOQZmajsPYtX71Ufej3IQ8W2Gxskfz9DK58ENEju4SbpIj48VenktRASC52N5Fhyf/aliQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/linux-x64/0.16.17: resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} engines: {node: '>=12'} @@ -821,15 +715,6 @@ packages: dev: true optional: true - /@esbuild/linux-x64/0.16.3: - resolution: {integrity: sha512-SDiG0nCixYO9JgpehoKgScwic7vXXndfasjnD5DLbp1xltANzqZ425l7LSdHynt19UWOcDjG9wJJzSElsPvk0w==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - /@esbuild/netbsd-x64/0.16.17: resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} engines: {node: '>=12'} @@ -839,15 +724,6 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64/0.16.3: - resolution: {integrity: sha512-AzbsJqiHEq1I/tUvOfAzCY15h4/7Ivp3ff/o1GpP16n48JMNAtbW0qui2WCgoIZArEHD0SUQ95gvR0oSO7ZbdA==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/openbsd-x64/0.16.17: resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} engines: {node: '>=12'} @@ -857,15 +733,6 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64/0.16.3: - resolution: {integrity: sha512-gSABi8qHl8k3Cbi/4toAzHiykuBuWLZs43JomTcXkjMZVkp0gj3gg9mO+9HJW/8GB5H89RX/V0QP4JGL7YEEVg==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - /@esbuild/sunos-x64/0.16.17: resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} engines: {node: '>=12'} @@ -875,15 +742,6 @@ packages: dev: true optional: true - /@esbuild/sunos-x64/0.16.3: - resolution: {integrity: sha512-SF9Kch5Ete4reovvRO6yNjMxrvlfT0F0Flm+NPoUw5Z4Q3r1d23LFTgaLwm3Cp0iGbrU/MoUI+ZqwCv5XJijCw==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-arm64/0.16.17: resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} engines: {node: '>=12'} @@ -893,15 +751,6 @@ packages: dev: true optional: true - /@esbuild/win32-arm64/0.16.3: - resolution: {integrity: sha512-u5aBonZIyGopAZyOnoPAA6fGsDeHByZ9CnEzyML9NqntK6D/xl5jteZUKm/p6nD09+v3pTM6TuUIqSPcChk5gg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-ia32/0.16.17: resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} engines: {node: '>=12'} @@ -911,15 +760,6 @@ packages: dev: true optional: true - /@esbuild/win32-ia32/0.16.3: - resolution: {integrity: sha512-GlgVq1WpvOEhNioh74TKelwla9KDuAaLZrdxuuUgsP2vayxeLgVc+rbpIv0IYF4+tlIzq2vRhofV+KGLD+37EQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@esbuild/win32-x64/0.16.17: resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} engines: {node: '>=12'} @@ -929,15 +769,6 @@ packages: dev: true optional: true - /@esbuild/win32-x64/0.16.3: - resolution: {integrity: sha512-5/JuTd8OWW8UzEtyf19fbrtMJENza+C9JoPIkvItgTBQ1FO2ZLvjbPO6Xs54vk0s5JB5QsfieUEshRQfu7ZHow==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - /@eslint/eslintrc/1.4.1: resolution: {integrity: sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1993,10 +1824,6 @@ packages: which: 2.0.2 dev: true - /css-color-names/1.0.1: - resolution: {integrity: sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==} - dev: true - /csstype/3.1.1: resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} @@ -2440,36 +2267,6 @@ packages: '@esbuild/win32-x64': 0.16.17 dev: true - /esbuild/0.16.3: - resolution: {integrity: sha512-71f7EjPWTiSguen8X/kxEpkAS7BFHwtQKisCDDV3Y4GLGWBaoSCyD5uXkaUew6JDzA9FEN1W23mdnSwW9kqCeg==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/android-arm': 0.16.3 - '@esbuild/android-arm64': 0.16.3 - '@esbuild/android-x64': 0.16.3 - '@esbuild/darwin-arm64': 0.16.3 - '@esbuild/darwin-x64': 0.16.3 - '@esbuild/freebsd-arm64': 0.16.3 - '@esbuild/freebsd-x64': 0.16.3 - '@esbuild/linux-arm': 0.16.3 - '@esbuild/linux-arm64': 0.16.3 - '@esbuild/linux-ia32': 0.16.3 - '@esbuild/linux-loong64': 0.16.3 - '@esbuild/linux-mips64el': 0.16.3 - '@esbuild/linux-ppc64': 0.16.3 - '@esbuild/linux-riscv64': 0.16.3 - '@esbuild/linux-s390x': 0.16.3 - '@esbuild/linux-x64': 0.16.3 - '@esbuild/netbsd-x64': 0.16.3 - '@esbuild/openbsd-x64': 0.16.3 - '@esbuild/sunos-x64': 0.16.3 - '@esbuild/win32-arm64': 0.16.3 - '@esbuild/win32-ia32': 0.16.3 - '@esbuild/win32-x64': 0.16.3 - dev: true - /escalade/3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -5282,10 +5079,44 @@ packages: optional: true dependencies: '@types/node': 18.11.18 - esbuild: 0.16.3 + esbuild: 0.16.17 postcss: 8.4.20 resolve: 1.22.1 - rollup: 3.7.0 + rollup: 3.10.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vite/4.1.0-beta.0_@types+node@18.11.18: + resolution: {integrity: sha512-8ckl5OzA82YcZjAmnUzmLzK9FHluq7hMNrxeb8sMLE8znvBF9lcyR9A8s0q33Ebc+ZqgXcWSESUyycJhMZtgGw==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.11.18 + esbuild: 0.16.17 + postcss: 8.4.20 + resolve: 1.22.1 + rollup: 3.10.0 optionalDependencies: fsevents: 2.3.2 dev: true