element-plus icon indicating copy to clipboard operation
element-plus copied to clipboard

[Build] [All] nuxt3.0.0稳定版 打包时,无法将 @popperjs/core 打包进去

Open ryiot opened this issue 2 years ago • 30 comments

Bug Type: Build

Environment

  • Vue Version: 3.2.45
  • Element Plus Version: 2.2.26
  • Browser / OS: mac os 13.0.1
  • Build Tool: Nuxt

Reproduction

Related Component

  • All

Reproduction Link

Github Repo

Steps to reproduce

  • 在nuxt3中引入Element Plus后,可以正常运行 pnpm run dev
  • 运行 pnpm run build 后,可以正常运行 node ./.output/server/index.mjs
  • 此时一切正常
  • 将 .output 中的文件复制到其他空文件夹中后,执行 node ./.output/server/index.mjs ,然后在谷歌浏览器中打开,页面显示 500,命令行提示如下错误: Last login: Wed Dec 14 03:08:42 on ttys008 ➜ test node ./server/index.mjs Listening http://[::]:3000 [nuxt] [request error] [unhandled] [500] Cannot find package '@popperjs/core' imported from /Users/jack/Desktop/test/server/node_modules/element-plus/es/components/popper/src/content.mjs at new NodeError (node:internal/errors:371:5) at packageResolve (node:internal/modules/esm/resolve:932:9) at moduleResolve (node:internal/modules/esm/resolve:978:18) at defaultResolve (node:internal/modules/esm/resolve:1080:11) at ESMLoader.resolve (node:internal/modules/esm/loader:530:30) at ESMLoader.getModuleJob (node:internal/modules/esm/loader:251:18) at ModuleWrap. (node:internal/modules/esm/module_job:79:40) at link (node:internal/modules/esm/module_job:78:36) [nuxt] [request error] [unhandled] [500] Cannot find package '@popperjs/core' imported from /Users/jack/Desktop/test/server/node_modules/element-plus/es/components/popper/src/content.mjs at new NodeError (node:internal/errors:371:5) at packageResolve (node:internal/modules/esm/resolve:932:9) at moduleResolve (node:internal/modules/esm/resolve:978:18) at defaultResolve (node:internal/modules/esm/resolve:1080:11) at ESMLoader.resolve (node:internal/modules/esm/loader:530:30) at ESMLoader.getModuleJob (node:internal/modules/esm/loader:251:18) at ModuleWrap. (node:internal/modules/esm/module_job:79:40) at link (node:internal/modules/esm/module_job:78:36)

What is Expected?

使用 nuxt3 打包后的文件可以部署到服务器上正常运行

What is actually happening?

使用 nuxt3 打包后的文件可以部署到服务器上运行时提示缺少 @popperjs/core

Additional comments

(empty)

ryiot avatar Dec 13 '22 20:12 ryiot

解决了吗?发生了同样的问题

TuduTian avatar Dec 14 '22 07:12 TuduTian

可以参考nitro配置项做修改。具体细节我也没试过 nuxt#standalone-server nitro#output

hdw0504 avatar Dec 15 '22 06:12 hdw0504

可以参考nitro配置项做修改。具体细节我也没试过 nuxt#standalone-server nitro#output

试了,还是不行

ryiot avatar Dec 15 '22 07:12 ryiot

image 打包后,运行时,提示找不到这个包

ryiot avatar Dec 15 '22 07:12 ryiot

同样的问题,本地运行没问题,部署到Liunx服务器提示相同的错误

jetlong avatar Dec 19 '22 14:12 jetlong

同样的问题, 看了一下popperjs/core最新版是2.11.6 element-plus依赖的的是2.11.7 这是什么意思?

xujiongze avatar Jan 28 '23 15:01 xujiongze

由于 #7321,目前内部使用的 @popperjs/core 实际上是指向 @sxzz/popperjs-es,应该是 Nuxt 目前不支持这种软链接。

  1. 你可以手动修改目录 .output/server/node_modules/@sxzz/popperjs-es -> .output/server/node_modules/@popperjs/core

  2. 通过命令行

mkdir .output/server/node_modules/@popperjs
mv .output/server/node_modules/@sxzz/popperjs-es .output/server/node_modules/@popperjs/core
  1. 附加在 scripts 中

// package.json

- "build": "nuxi build",
+ "build": "nuxi build && mkdir .output/server/node_modules/@popperjs && mv .output/server/node_modules/@sxzz/popperjs-es .output/server/node_modules/@popperjs/core",

tolking avatar Feb 03 '23 09:02 tolking

由于 #7321,目前内部使用的 @popperjs/core 实际上是指向 @sxzz/popperjs-es,应该是 Nuxt 目前不支持这种软链接。

  1. 你可以手动修改目录 .output/server/node_modules/@sxzz/popperjs-es -> .output/server/node_modules/@popperjs/core
  2. 通过命令行
mkdir .output/server/node_modules/@popperjs
mv .output/server/node_modules/@sxzz/popperjs-es .output/server/node_modules/@popperjs/core
  1. 附加在 scripts 中

// package.json

- "build": "nuxi build",
+ "build": "nuxi build && mkdir .output/server/node_modules/@popperjs && mv .output/server/node_modules/@sxzz/popperjs-es .output/server/node_modules/@popperjs/core",

@tolking 目前我的项目有依赖是用到了@popperjs/core@tiptap/extension-bubble-menu里的tippy.js有依赖到'@popperjs/core': 2.11.6

  /tippy.js/6.3.7:
    resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==}
    dependencies:
      '@popperjs/core': 2.11.6
    dev: false

那这种情况下上面的办法就不支持了。在本地开发没问题。一打包就只用了2.11.6导致报错

file:///xxx/.output/server/chunks/popper.b2577a3d.mjs:10
import { placements, createPopper } from '@popperjs/core';
         ^^^^^^^^^^
SyntaxError: Named export 'placements' not found. The requested module '@popperjs/core' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@popperjs/core';
const { placements, createPopper } = pkg;

hdw0504 avatar Feb 03 '23 10:02 hdw0504

这只是临时的处理办法,还是要等Nuxt支持软连接

@popperjs/core - CommonJS @sxzz/popperjs-es - ES module

这两个是不同的

tolking avatar Feb 03 '23 11:02 tolking

这只是临时的处理办法,还是要等Nuxt支持软连接

@popperjs/core - CommonJS @sxzz/popperjs-es - ES module

这两个是不同的

非常感谢回复! 如果像我这种有别的依赖用到了@popperjs/core的时候。 得先删除原有的@popperjs/core再执行上面的命令,又或者直接写个方法

// scripts/fixPopper.ts
import { copy } from 'fs-extra'

const dereference = process.platform === 'win32' ? true : undefined

;(async () => {
  // 解决 popperjs 默认是 cjs 导致报错问题
  // https://github.com/element-plus/element-plus/issues/10979

  await copy(
    '.output/server/node_modules/@sxzz/popperjs-es',
    '.output/server/node_modules/@popperjs/core',
    { dereference }
  )
  console.log('finish cover @popperjs/core from @sxzz/popperjs-es ...')

  // 因为那边需要index.js ...
  await copy(
    'node_modules/@popperjs/core/dist/index.js',
    '.output/server/node_modules/@popperjs/core/dist/index.js',
    { dereference }
  )
  console.log('finish cover index.js ...')
})()
// package.json
{
  "scripts": {
    "build": "nuxt build && esno scripts/fixPopper.ts",
    ...
  },
  "devDependencies": {
    "esno": "^0.16.3",
    "fs-extra": "^11.1.0",
    ...
  }
}

hdw0504 avatar Feb 03 '23 16:02 hdw0504

个人理解:直接替换是不行的,本质上是因为项目里其他工具也需要这个库,且可能使用非es模式。

这样一来,不管最后安装成什么版本,都会有一个库不能正常工作的,总有一个其他依赖对不上号。

所以最根本的方法是element-plus更新依赖名称,直接用sxzz的,一直顶替的话,这种下载量这么高的库,可能经常有各种工具库一起使用时引起冲突

我这里是tippy.js冲突引起的,加了个脚本,把两个库的dist文件合并到一起,并且修改package.json,使其支持不同引用模式

import { copy, remove } from 'fs-extra'
import writejson from 'writejson'
import readjson from 'readjson'

const dereference = process.platform === 'win32' ? true : undefined

;(async () => {
  // 先删除旧的再迁移
  // await remove('.output/server/node_modules/@popperjs/core')
  await copy(
    '.output/server/node_modules/@sxzz/popperjs-es/dist/index.mjs',
    '.output/server/node_modules/@popperjs/core/dist/index.mjs',
    { dereference }
  )
  // 修改package.json
  const p = '.output/server/node_modules/@popperjs/core/package.json'
  let json = readjson.sync(p)
  const ex = {
    main: 'dist/index.mjs',
    module: 'dist/index.mjs',
    "exports": {
      ".": {
        "require": "./dist/cjs/popper.js",
        "import": "./dist/index.mjs"
      },
      "./*": "./*"
    },
  }
  json = Object.assign(json, ex)
  writejson.sync(p, json)
})()

chenyuncai avatar Mar 17 '23 05:03 chenyuncai

因为这个问题现在还在,留个👣

waerly avatar Mar 23 '23 08:03 waerly

edit .npmrc:

shamefully-hoist=true
node-linker=hoisted
public-hoist-pattern=*

RayJason avatar Apr 06 '23 12:04 RayJason

不要用pnpm 换成yarn

fanerger avatar Apr 26 '23 11:04 fanerger

Nuxt 3.4 之后在 package.json 加上这个就好了 Add this into package.json after Nuxt 3.4

    "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",

然后需要重建 packages-lock.json,可以看到这时 @popperjs/core 才真正使用 @sxzz/popperjs-es Then you need to rebuild packages-lock.json, then @popperjs/core actually uses @sxzz/popperjs-es

    "node_modules/@popperjs/core": {
      "version": "2.11.8",
      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
    "node_modules/@popperjs/core": {
      "name": "@sxzz/popperjs-es",
      "version": "2.11.7",
      "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",

AnzhiZhang avatar May 02 '23 15:05 AnzhiZhang

+1

wangjing013 avatar May 10 '23 08:05 wangjing013

+1

wangjing013 avatar May 10 '23 08:05 wangjing013

体验太糟糕了,尤其是我们用的还是pnpm的monorepo,希望nuxt3能尽快解决 shamefully-hoist 的问题

gyhyfj avatar May 12 '23 14:05 gyhyfj

edit .npmrc:

shamefully-hoist=true
node-linker=hoisted
public-hoist-pattern=*

在pnpm的monorepo中会直接导致项目整个都装不了依赖跑不起来

gyhyfj avatar May 12 '23 15:05 gyhyfj

这个方法试过有效的,👍

Epic-Deno avatar Jan 05 '24 10:01 Epic-Deno

Nuxt 3.4 之后加上这个就好了 add this into package.json after Nuxt 3.4

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

目前看到@sxzz/popperjs-es的最新版本是2.11.7 😭

StreakingMan avatar Jan 19 '24 03:01 StreakingMan

我试了上面的方案都不行,然后对照着官网将只能客户端渲染的组件用ClientOnly>包起来不报错了,只是这样子体验不好

yaowangmx avatar Jun 25 '24 01:06 yaowangmx

直接弃用吧,用其他对SSR友好的UI库,一些headless设计优先的对ssr场景更好

chenyuncai avatar Jun 25 '24 02:06 chenyuncai

error TS2742: The inferred type of 'default' cannot be named without a reference to '.pnpm/@[email protected]/node_modules/@sxzz/popperjs-es'. This is likely not portable. A type annotation is necessary.

1825 export default (await import('vue')).defineComponent({
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1826 setup() {
     ~~~~~~~~~
 ... 
1831 __typeRefs: {} as __VLS_TemplateResult['refs'],
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1832 });

TenviLi avatar Oct 16 '24 18:10 TenviLi

这个问题影响很大,目前看还没有好的解决方案。为什么关闭了呢。

terwer avatar Jan 10 '25 18:01 terwer

有同样的问题

xcy960815 avatar Jun 05 '25 09:06 xcy960815

有同样的问题

将部分不支持ssr的组件用ClientOnly包起来就不会报错,但是这部分的数据不会被seo

yaowangmx avatar Jun 05 '25 09:06 yaowangmx

我的解决方法: pnpm v10 在项目根目录创建 pnpm-workspace.yaml,添加配置项 nodeLinker: hoisted 文档,删除 node_modules .nuxt .output 然后重新安装依赖 pnpm i,再打包就正常了

RuixeWolf avatar Jun 09 '25 01:06 RuixeWolf

目前增加下面配置并重新安装依赖,就正常运行了

// .npmrc

shamefully-hoist=true
node-linker=hoisted

tolking avatar Jun 09 '25 06:06 tolking

nuxt版本 3.17.4可以在package.json中dependencies添加"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",参考链接 https://github.com/element-plus/element-plus/blob/dev/package.json

Image

xcy960815 avatar Jun 09 '25 10:06 xcy960815