当前位置:首页>javascript>Nuxt SSR 构建中的 ESM 依赖兼容问题排查

Nuxt SSR 构建中的 ESM 依赖兼容问题排查

1970-01-01 8 javascript

问题一:Element Plus 无法导入 placements

运行 Nuxt SSR 产物时出现:

SyntaxError: The requested module '@popperjs/core' does not provide an export named 'placements'

原因

element-plus@2.14.3 使用的并非原版 @popperjs/core,而是包别名:

"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.8"

项目根目录直接安装原版 @popperjs/core 后,Nitro 在运行时解析到了错误的包,因此缺少 placements 导出。

手动配置以下 alias 也无法解决:

'@popperjs/core': '@sxzz/popperjs-es'

pnpm 将 @sxzz/popperjs-es 安装为 Element Plus 的嵌套依赖,项目根目录没有对应路径,Vite 会报 ENOENT。

解决方案

移除手工 alias,让 pnpm 按 Element Plus 的依赖关系解析,并在 SSR 构建时内联相关依赖:

export default defineNuxtConfig({  nitro: {    externals: {      inline: ['element-plus', '@element-plus/icons-vue'],    },  },  vite: {    ssr: {      noExternal: ['element-plus', '@popperjs/core'],    },  }, })

问题二:vue-countup-v3 缺少默认导出

修复 Element Plus 后,SSR 又出现:

SyntaxError: The requested module 'vue-countup-v3' does not provide an export named 'default'

原因

vue-countup-v3@1.4.2 同时提供两个入口:

{  "main": "dist/vue-countup-v3.umd.js",  "module": "dist/vue-countup-v3.es.js" }

ESM 文件包含默认导出,但 Nitro 外置依赖后使用了 UMD 入口,导致 Node.js 无法取得默认导出。

解决方案

将该依赖同时加入 Nitro 和 Vite 的 SSR 内联列表:

export default defineNuxtConfig({  nitro: {    externals: {      inline: [        'element-plus',        '@element-plus/icons-vue',        'vue-countup-v3',      ],    },  },  vite: {    ssr: {      noExternal: [        'element-plus',        '@popperjs/core',        'vue-countup-v3',      ],    },  }, })

总结

此类错误通常不是业务代码的导入语法有误,而是依赖在 SSR 环境中被外置后,Node.js 加载了错误的模块入口。

处理原则:

  1. 检查依赖的 main、module 和 exports 配置。
  2. 注意 pnpm 的包别名和嵌套依赖结构。
  3. 不要随意添加同名原版依赖覆盖包别名。
  4. 对 ESM/UMD 入口不兼容的依赖使用 vite.ssr.noExternal 和 nitro.externals.inline。

该文章已关闭评论