Skip to content
This repository was archived by the owner on Oct 9, 2025. It is now read-only.

Commit b5d37ac

Browse files
nasatomegrdsdev
authored andcommitted
# Exports Field Order Issue - Webpack Resolution Priority Problem
## 🚨 Problem The current exports field configuration causes webpack to resolve the **CommonJS build** (`dist/main`) instead of the **ESM build** (`dist/module`), resulting in webpack warnings about dynamic imports during bundling. ## 🔍 Root Cause Analysis The issue stems from **condition resolution order** in the exports field. According to the **Node.js v24 documentation**: > *"Conditions are handled in the order they are specified"* > > Source: [Node.js v24 Package Entry Points Documentation](https://nodejs.org/api/packages.html#conditional-exports) And from the **official Node.js v24 CLI documentation**: > *"Node.js implements the following conditions, listed in order from most specific to least specific as conditions should be defined"* > > Source: [Node.js v24 CLI Documentation](https://nodejs.org/api/cli.html#-c-condition---conditionscondition) ### 📚 Historical Reference (Node.js v13 - Legacy Documentation) For additional confirmation, the original Node.js v13 ESM documentation stated: > *"Conditions are processed top-to-bottom"* and *"`node` should come after `import`/`require`"* > > Source: [Node.js v13 ESM Documentation](https://nodejs.org/download/rc/v13.12.0-rc.2/docs/api/esm.html) This principle has remained consistent across Node.js versions, establishing a **5+ year precedent** for proper condition ordering. ### Current Configuration (❌ Problematic): ```json "exports": { ".": { "deno": "./dist/main/index.js", "node": "./dist/main/index.js", // ⬅️ 2nd position - TOO EARLY "browser": "./dist/module/index.js", "import": "./dist/module/index.js", "require": "./dist/main/index.js", "default": "./dist/main/index.js" } } ``` **Problem**: Webpack (when targeting Node.js for SSR) sees `"node"` condition **before** `"import"` and stops resolution there, using the CommonJS build. ### Recommended Configuration (✅ Fixed): ```json "exports": { ".": { "types": "./dist/module/index.d.ts", // ⬅️ TypeScript first "import": "./dist/module/index.js", // ⬅️ ESM modules "browser": "./dist/module/index.js", // ⬅️ Browser environments "require": "./dist/main/index.js", // ⬅️ CommonJS fallback "node": "./dist/main/index.js", // ⬅️ Node.js specific (after import/require) "deno": "./dist/main/index.js", // ⬅️ Deno specific "default": "./dist/main/index.js" // ⬅️ Final fallback } } ``` ## 📋 Resolution Algorithm Per **Node.js specification** (consistent from v13 to v24), resolution follows these rules: 1. **Top-to-bottom evaluation**: Conditions are processed in the order they appear 2. **First match wins**: Resolution stops at the first matching condition 3. **Environment priority**: More specific conditions should come before generic ones **Current References**: - [Node.js v24 Conditional Exports](https://nodejs.org/api/packages.html#conditional-exports) - [Node.js v24 Package Resolution Algorithm](https://nodejs.org/api/packages.html#resolution-algorithm) **Historical Reference**: - [Node.js v13 ESM Documentation](https://nodejs.org/download/rc/v13.12.0-rc.2/docs/api/esm.html) - Original implementation ## 🛠️ Webpack Behavior When webpack bundles for **server-side rendering (SSR)**: - It targets the `"node"` environment - Default conditions include: `["node", "import", "require", "default"]` - With current order, `"node"` matches **first** → uses CommonJS build → triggers webpack warnings **Source**: [Node.js v24 Default Conditions](https://nodejs.org/api/packages.html#conditional-exports) ## ✅ Benefits of the Fix 1. **ESM-first resolution**: Modern bundlers get the ESM build with native `import()` support 2. **No webpack warnings**: ESM builds don't need TypeScript transforms that cause dynamic import issues 3. **Future compatibility**: Follows Node.js v24 recommended condition ordering 4. **Backward compatibility**: CJS consumers still get the working CommonJS build 5. **Historical consistency**: Aligns with **5+ years** of Node.js documented best practices ## 🔧 Implementation The fix maintains all existing functionality while optimizing for modern tooling: ```json { "exports": { ".": { "types": "./dist/module/index.d.ts", "import": "./dist/module/index.js", // Modern ESM-first "browser": "./dist/module/index.js", "require": "./dist/main/index.js", "node": "./dist/main/index.js", // Legacy Node.js "deno": "./dist/main/index.js", "default": "./dist/main/index.js" } } } ``` This ordering ensures: - **Modern tooling** (webpack, Vite, esbuild) → Gets ESM build (no warnings) - **Legacy Node.js CJS** → Gets CommonJS build (continues working) - **TypeScript** → Gets correct type definitions first ## 🎯 Why This Works The key insight from both **modern and legacy documentation** is that condition order determines resolution priority. By placing `"import"` before `"node"`, we ensure: - **ESM environments** match `"import"` first → get ES modules - **CJS environments** match `"require"` → get CommonJS - **Node.js specific cases** fall back to `"node"` → maintains compatibility This approach has been **the recommended pattern since Node.js v13** and remains the best practice in **Node.js v24**. --- **Updated with Node.js v24.1.0 documentation (December 2024)** **Cross-referenced with Node.js v13 ESM specification (Historical validation)** Related: 723652f
1 parent 918206e commit b5d37ac

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,18 @@
6565
},
6666
"exports": {
6767
".": {
68-
"deno": "./dist/main/index.js",
69-
"node": "./dist/main/index.js",
70-
"browser": "./dist/module/index.js",
68+
"types": "./dist/module/index.d.ts",
7169
"import": "./dist/module/index.js",
70+
"browser": "./dist/module/index.js",
7271
"require": "./dist/main/index.js",
73-
"types": "./dist/module/index.d.ts",
72+
"node": "./dist/main/index.js",
73+
"deno": "./dist/main/index.js",
7474
"default": "./dist/main/index.js"
7575
},
7676
"./websocket": {
77-
"node": "./dist/WebSocket.js",
78-
"browser": "./dist/WebSocket.native.js",
7977
"types": "./dist/WebSocket.d.ts",
78+
"browser": "./dist/WebSocket.native.js",
79+
"node": "./dist/WebSocket.js",
8080
"default": "./dist/WebSocket.native.js"
8181
}
8282
}

0 commit comments

Comments
 (0)