diff --git a/lru-cache-browser-issue.md b/lru-cache-browser-issue.md new file mode 100644 index 0000000..785b686 --- /dev/null +++ b/lru-cache-browser-issue.md @@ -0,0 +1,90 @@ +# Issue: Top-level await with `node:diagnostics_channel` breaks browser builds in Webpack 5 + +## Description + +The latest version of `lru-cache` (v11.x) uses top-level await to dynamically import `node:diagnostics_channel`: + +```javascript +var C={hasSubscribers:!1},[S,W]=await import("node:diagnostics_channel")... +``` + +This causes issues in browser environments when building with Webpack 5, as Webpack doesn't handle the `node:` protocol scheme by default. + +## Problem + +1. **Top-level await**: The use of top-level await makes the entire module asynchronous +2. **Node.js protocol**: `node:diagnostics_channel` is not supported in browser environments +3. **Webpack 5 compatibility**: When Webpack encounters this, it either: + - Throws an `UnhandledSchemeError` for the `node:` protocol, or + - Causes the module export to become a Promise instead of the expected object + +## Impact + +When using `lru-cache` v11.x in a React application built with Webpack 5 (via Create React App / craco): + +```javascript +// Expected behavior +import { LRUCache } from 'lru-cache'; +const cache = new LRUCache({ max: 100 }); // Works + +// Actual behavior +import * as LRUCacheModule from 'lru-cache'; +console.log(LRUCacheModule); // Promise { } instead of module exports +``` + +This breaks downstream packages that depend on `lru-cache`, such as when used in `@kne/react-enum`, causing the entire module to become a Promise. + +## Environment + +- Node.js: v20.x +- Webpack: 5.x (via react-scripts 5.0.1) +- Build tool: craco 7.1.0 +- Browser target: Modern browsers (Chrome, Firefox, Safari) + +## Current Workaround + +We can configure Webpack fallbacks, but this requires additional configuration: + +```javascript +// In webpack config +webpackConfig.resolve.fallback = { + "diagnostics_channel": false +}; + +// Or create a mock module +webpackConfig.resolve.alias = { + "node:diagnostics_channel": path.resolve(__dirname, "mock-diagnostics-channel.js") +}; +``` + +However, this doesn't solve the top-level await issue. + +## Suggested Solution + +Could you consider one of the following approaches: + +1. **Conditional import**: Check for browser environment before importing `diagnostics_channel`: + ```javascript + const hasDiagnostics = typeof process !== 'undefined' && process.versions?.node; + const diagnosticsChannel = hasDiagnostics ? + await import('node:diagnostics_channel') : + { channel: () => ({ hasSubscribers: false }) }; + ``` + +2. **Browser bundle**: Provide a separate browser entry point that doesn't include Node.js-specific features + +3. **Optional peer dependency**: Make `diagnostics_channel` an optional feature that can be safely omitted in browser builds + +4. **Use synchronous import**: Avoid top-level await to prevent making the module async + +## Version Info + +- lru-cache version: 11.3.2 +- Node.js: 20.x +- Webpack: 5.x + +## Additional Context + +This issue was discovered when upgrading from lru-cache v10.x to v11.x. Version 10.x works fine in browser environments because it doesn't use `node:diagnostics_channel` or top-level await. + +Thank you for considering this issue! Let me know if you need any additional information or if I can help test a potential fix. diff --git a/package.json b/package.json index 563c384..06d4e0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kne-components/components-core", - "version": "0.4.68", + "version": "0.4.69", "files": [ "build" ], @@ -31,7 +31,7 @@ "@kne/info-page": "^0.2.9", "@kne/is-empty": "^1.0.1", "@kne/phone-number-input": "^0.1.5", - "@kne/react-enum": "^0.1.12", + "@kne/react-enum": "^0.1.14", "@kne/react-fetch": "^1.5.5", "@kne/react-file": "^0.1.35", "@kne/react-file-type": "^1.0.5", @@ -51,7 +51,7 @@ "@kne/use-simulation-blur": "^0.1.2", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", - "axios": "^1.13.5", + "axios": "1.13.5", "classnames": "^2.3.2", "color": "^4.2.3", "cross-env": "^7.0.3", diff --git a/src/components/Navigation/index.js b/src/components/Navigation/index.js index 53ffa39..677e48d 100644 --- a/src/components/Navigation/index.js +++ b/src/components/Navigation/index.js @@ -76,9 +76,6 @@ const Navigation = withLocale(({ } } const windowResizeRef = useResize(callback); - useEffect(() => { - callback(windowResizeRef.current); - }, []); const pathModuleName = location.pathname .replace(new RegExp(`^${base}`), "") .split("/")[1]; @@ -162,9 +159,11 @@ const Navigation = withLocale(({ trigger={['click']} open={mobileMenuVisible} onOpenChange={setMobileMenuVisible} - dropdownRender={(menu) => (
+ dropdownRender={(menu) => (
{menu} - {rightOptions && (
+ {rightOptions && (
{rightOptions}
)}
)} @@ -200,7 +199,8 @@ const Navigation = withLocale(({ })], }} > -
+
@@ -231,7 +231,7 @@ const Navigation = withLocale(({ {nameLabel || formatMessage({id: 'overflowedIndicator'})} - + )} @@ -269,10 +269,12 @@ const Navigation = withLocale(({ }),]} /> )} - {isMobile && ( - {defaultTitle || formatMessage({id: 'defaultTitle'})} - )} - {!isMobile && {rightOptions}} + {isMobile && ( + + {defaultTitle || formatMessage({id: 'defaultTitle'})} + )} + {!isMobile && {rightOptions}}