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

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

1970-01-01 61 javascript

问题一:Element Plus 无法导入 placements

报错信息

运行 Nuxt SSR 产物时出现以下错误:

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

原因分析

  1. element-plus@2.14.3 使用的并非原版 @popperjs/core,而是使用了 npm 包别名:
  2. 当项目根目录直接安装了原版 @popperjs/core 时,Nitro 在运行时解析到了错误的包,导致缺少 placements 导出。
  3. 手动配置以下 alias 仍无法解决: 原因:pnpm 将 @sxzz/popperjs-es 安装为 Element Plus 的嵌套依赖,项目根目录并没有对应路径,导致 Vite 报 ENOENT 错误。

解决方案

移除手动添加的 alias,让 pnpm 按照 Element Plus 的依赖关系正常解析,并在 SSR 构建时内联相关依赖:

TypeScript

// nuxt.config.ts
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 运行时出现以下错误:

Bash

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

原因分析

vue-countup-v3@1.4.2package.json 中同时提供了两个入口:

JSON

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

其 ESM 构建文件包含默认导出(export default),但 Nitro 在外置依赖(external)后,Node.js 运行时使用了 UMD 入口,导致 Node.js 无法获取到默认导出。

解决方案

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

TypeScript

// nuxt.config.ts
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 环境中被外置(externalized)后,Node.js 加载了不兼容的模块入口(如 UMD)或解析到了错误的嵌套依赖。

排查与处理原则

  1. 检查入口配置​:查看依赖包的 package.json 中的 mainmoduleexports 配置。
  2. 注意依赖结构​:关注 pnpm 的包别名(package alias)和嵌套依赖结构。
  3. 避免冲突​:不要随意在根目录添加同名原版依赖去覆盖包别名。
  4. 强制内联打包​:对 ESM/UMD 入口不兼容或存在包别名的依赖,统一使用 vite.ssr.noExternalnitro.externals.inline 进行强制打包/内联。

评论 (0)