{"id":"93ae144094696b8f","repo":"vitejs/vite","slug":"vite-named-export-lastbinding-not-found-th","errorCode":null,"errorMessage":"[vite] Named export '${lastBinding}' not found. The requested module '${rawId}' is a CommonJS module, which may not support all module.exports as named exports.\nCommonJS modules can always be imported via the default export, for example using:\n\nimport pkg from '${rawId}';\nconst {${missingBindings.join(', ')}} = pkg;\n","messagePattern":"\\[vite\\] Named export '(.+?)' not found\\. The requested module '(.+?)' is a CommonJS module, which may not support all module\\.exports as named exports\\.\nCommonJS modules can always be imported via the default export, for example using:\n\nimport pkg from '(.+?)';\nconst (.+?) = pkg;\n","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"packages/vite/src/shared/ssrTransform.ts","lineNumber":49,"sourceCode":"\n  // If the user named imports a specifier that can't be analyzed, error.\n  // If the module doesn't import anything explicitly, e.g. `import 'foo'` or\n  // `import * as foo from 'foo'`, we can skip.\n  if (metadata?.importedNames?.length) {\n    const missingBindings = metadata.importedNames.filter((s) => !(s in mod))\n    if (missingBindings.length) {\n      const lastBinding = missingBindings[missingBindings.length - 1]\n\n      // For invalid named exports only, similar to how Node.js errors for top-level imports.\n      // But since we transform as dynamic imports, we need to emulate the error manually.\n      if (moduleType === 'module') {\n        throw new SyntaxError(\n          `[vite] The requested module '${rawId}' does not provide an export named '${lastBinding}'`,\n        )\n      } else {\n        // For non-ESM, named imports is done via static analysis with cjs-module-lexer in Node.js.\n        // Copied from Node.js\n        throw new SyntaxError(`\\\n[vite] Named export '${lastBinding}' not found. The requested module '${rawId}' is a CommonJS module, which may not support all module.exports as named exports.\nCommonJS modules can always be imported via the default export, for example using:\n\nimport pkg from '${rawId}';\nconst {${missingBindings.join(', ')}} = pkg;\n`)\n      }\n    }\n  }\n}\n","sourceCodeStart":31,"sourceCodeEnd":60,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/shared/ssrTransform.ts#L31-L60","documentation":"The CommonJS counterpart to error 109: when SSR-importing named bindings from a CommonJS module, Vite relies on cjs-module-lexer-style static analysis to discover named exports. If a requested binding is not detected as a named export, Vite throws a SyntaxError (mirroring Node.js's CJS named-import error) advising the developer to use the default export and destructure from it, since CJS named-export detection is unreliable and may miss valid exports.","triggerScenarios":"An SSR import like `import { foo } from 'cjs-pkg'` where 'cjs-pkg' is a CommonJS module and 'foo' is not statically detected as a named export (even if module.exports.foo exists at runtime). Triggered by analyzeImportedModDifference for moduleType !== 'module'.","commonSituations":"Importing named exports from a CommonJS npm package in an SSR context where the export isn't statically analyzable (defined dynamically, via Object.assign, or conditionally). Packages that build to CJS but document named imports. Newer package versions that changed how they attach exports.","solutions":["Follow the error's suggestion: import the default export and destructure — `import pkg from 'cjs-pkg'; const { foo } = pkg`.","If the package ships an ESM build, configure resolve.mainFields/conditions or imports/exports to prefer the ESM entry so named imports work.","Verify the export actually exists at runtime via console.log(require('cjs-pkg')) to rule out a genuine missing export."],"exampleFix":"// before — named import from a CJS module not statically analyzable\nimport { foo } from 'cjs-pkg'\n\n// after — default import + destructure\nimport pkg from 'cjs-pkg'\nconst { foo } = pkg","handlingStrategy":"fallback","validationCode":"// Detect CJS modules and switch to default-import style proactively\nimport { isFilePathESM } from 'vite'\n\nconst isEsm = isFilePathESM(resolvedId, packageCache)\nif (!isEsm) {\n  // prefer default import + destructure for CJS\n  // import pkg from 'cjs-pkg'; const { foo } = pkg\n}","typeGuard":"// Check whether a binding is statically detectable on a CJS module's exports\nfunction hasCjsNamedExport(mod: any, name: string): boolean {\n  return mod != null && typeof mod === 'object' && name in mod\n}","tryCatchPattern":"try {\n  await ssrLoadModule(url)\n} catch (e) {\n  if (e instanceof SyntaxError && /CommonJS module/.test(e.message)) {\n    // switch to: import pkg from '<rawId>'; const { binding } = pkg\n  } else {\n    throw e\n  }\n}","preventionTips":["For CJS packages in SSR, prefer default import + destructure over named imports.","Configure resolve to prefer ESM entry points of packages that ship both builds.","After a package version bump, re-test named imports from CJS dependencies."],"tags":["ssr","commonjs","imports","named-exports","interop"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}