Skip to content

Commit

Permalink
fix: SSR import in dev can't resolve default import (fix #5706) (#5923)
Browse files Browse the repository at this point in the history
  • Loading branch information
brillout authored Dec 2, 2021
1 parent 7edabb4 commit 21d79d7
Showing 1 changed file with 34 additions and 7 deletions.
41 changes: 34 additions & 7 deletions packages/vite/src/node/ssr/ssrModuleLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,23 +263,50 @@ async function nodeImport(

try {
const mod = await dynamicImport(url)
return proxyESM(id, mod)
return proxyESM(mod)
} finally {
unhookNodeResolve()
}
}

// rollup-style default import interop for cjs
function proxyESM(id: string, mod: any) {
const defaultExport = mod.__esModule
? mod.default
: mod.default
? mod.default
: mod
function proxyESM(mod: any) {
const defaultExport = getDefaultExport(mod)
return new Proxy(mod, {
get(mod, prop) {
if (prop === 'default') return defaultExport
return mod[prop] ?? defaultExport?.[prop]
}
})
}

function getDefaultExport(moduleExports: any) {
// `moduleExports` is one of the following:
// - `const moduleExports = require(file)`
// - `const moduleExports = await import(file)`
let defaultExport =
'default' in moduleExports ? moduleExports.default : moduleExports

// Node.js doesn't support `__esModule`, see https://github.com/nodejs/node/issues/40891
// This means we need to unwrap the `__esModule` wrapper ourselves.
//
// For example:
// ```ts
// export default 'hi'
// ```
//
// Which TypeScript transpiles to:
// ```js
// use strict";
// exports.__esModule = true;
// exports["default"] = 'hi';
// ```
//
// This means that `moduleExports.default` denotes `{ __esModule, default: 'hi }` thus the actual
// default lives in `moduleExports.default.default`.
if (defaultExport && '__esModule' in defaultExport) {
defaultExport = defaultExport.default
}

return defaultExport
}

0 comments on commit 21d79d7

Please sign in to comment.