vant icon indicating copy to clipboard operation
vant copied to clipboard

SSR使用Popover组件报错Cannot find module和Hydration node mismatch

Open Ben-Ben-B opened this issue 3 years ago • 17 comments

重现链接

https://github.com/Ben-Ben-B/vant-popover-ssr-error

Vant 版本

3.3.2

描述一下你遇到的问题。

报错信息如下 [Vue Router warn]: uncaught error during route navigation: 在3.3.1版本没有这个报错 [ Midway ] Error: Cannot find module '/node_modules/vant/lib/popover' 在3.3.1版本没有这个报错 [Vue warn]: Hydration node mismatch: 问题原因大概就是vant在server/client的slot标签或者teleport的结构不一致,多个组件存在这个情况

重现步骤

直接运行

设备/浏览器

node v16.13.0

Ben-Ben-B avatar Dec 01 '21 03:12 Ben-Ben-B

我是使用 Quasar Framework ssr , 也是找不到模块,我是手动按需导入的,之前都是好的,升级到3.3.2及以上版本就挂了,只能回滚锁定到 "vant": "3.3.1",

import Lazyload from "vant/lib/lazyload";

image

[Quasar Dev Webserver] /mobile/ -> error during render
Error: Cannot find module '/Users/panhezeng/Workspace/moocnd-wechat-ssr/node_modules/vant/lib/lazyload'
    at createEsmNotFoundErr (node:internal/modules/cjs/loader:960:15)
...
  at Object.vant/lib/lazyload (render-app.js:4797:18)
    at __webpack_require__ (render-app.js:4898:41)

panhezeng avatar Dec 02 '21 03:12 panhezeng

can not find module 的问题已在 3.3.5 版本修复。

chenjiahan avatar Dec 02 '21 13:12 chenjiahan

@chenjiahan Hydration node mismatch的问题呢?

Ben-Ben-B avatar Dec 08 '21 03:12 Ben-Ben-B

can not find module 的问题已在 3.3.5 版本修复。

又出了另外一个问题:

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/lazyload' is not defined by "exports" in /Users/panhezeng/Workspace/moocnd-wechat-ssr/node_modules/vant/package.json at new NodeError (node:internal/errors:371:5)

panhezeng avatar Dec 08 '21 05:12 panhezeng

只要一改 vant/package.json exports 就出各种问题,还是测试得全面点再改吧

是不是应该 写成 **/* ,而不是把*去掉

回滚锁定到 "vant": "3.3.1" 了

panhezeng avatar Dec 08 '21 05:12 panhezeng

@panhezeng 参见 https://github.com/youzan/vant/pull/10014

@Ben-Ben-B 别急,后续会看。

chenjiahan avatar Dec 08 '21 09:12 chenjiahan

是不是应该 写成 */ ,而不是把*去掉

这个写法是无效的。目前所有场景都测试过,唯一不兼容的是省略 index 的写法,可以手动补全 index 来避免。

chenjiahan avatar Dec 08 '21 09:12 chenjiahan

是不是应该 写成 / ,而不是把去掉

这个写法是无效的。目前所有场景都测试过,唯一不兼容的是省略 index 的写法,可以手动补全 index 来避免。

不行啊,还是报错啊,改成index也不行 ,都不行啊。

import Lazyload from "vant/lib/lazyload/index";
import Lazyload from "vant/lib/lazyload/index.js";

image

image

image

panhezeng avatar Dec 09 '21 01:12 panhezeng

为了一个还是beta版本的nuxt3,把整个导入都搞挂了,这个值得吗?而且就算按您说的,唯一不兼容的是省略 index 的写法这一个问题,就不能只改小版本号了,所有用^3的用户,只要没有用加index的,都挂了。

何况还有加了index也不行的情况,比如这个lazyload插件

个人觉得,为某个特定框架的需求,应该使用类似 nuxt plugin 的方式解决,而不是改整个导出设置,这样影响面太大了

panhezeng avatar Dec 09 '21 01:12 panhezeng

实测 import Lazyload from "vant/lib/lazyload/index"; 没问题,[email protected] 版本

image

image

另外,需要澄清一下,并不是整个导入都挂了,以下情况都是正常的:

  • 对于 webpack 用户,任何写法都可以正常引入,webpack 默认会补全 index。
  • 对于使用 ssr 框架的用户,推荐的引用方式是 import { XX } from 'vant',这种写法可以正常工作,并且在生产环境可以引用到性能更好的压缩后代码。并不推荐直接引用某个相对路径。
  • 对于使用 vite 的用户,更没有必要引用相对路径了,vite 默认支持 tree shaking。并且社区中的 unplugin-vue-components 等插件已经完成了适配,在路径中补全了 index。

另外,exports field 也不只是为了兼容 nuxt3,它还会在 SSR 框架下提供 ssr.js 这个性能更优的代码包。

我们会继续寻找合适的方式去兼容省略 index 的写法,在此之前,可以手动补全 index,或者锁定一下版本。

chenjiahan avatar Dec 09 '21 02:12 chenjiahan

看你的截图,是ssr模式吗?你可以试试 quuasar ts ssr的环境,我再试试插件按需导入吧,之前用ts-import-plugin 好好的,好像也是升级3.3.1以后的版本,就不行了,我再试试在vue ts里面混合 js 使用babel-import-plugin 看能不能解决

panhezeng avatar Dec 09 '21 06:12 panhezeng

需要帮忙排查的话,你可以提供一个基于 quasar 的最小复现仓库给我们。

chenjiahan avatar Dec 09 '21 08:12 chenjiahan

Hydration node mismatch的问题啥时候看看啊,这个问题会造成SSR页面在客服端无法渲染,直接白屏 @chenjiahan

Ben-Ben-B avatar Dec 15 '21 08:12 Ben-Ben-B

@Ben-Ben-B 在此 issue 中有讨论:https://github.com/youzan/vant/pull/10099

chenjiahan avatar Dec 29 '21 03:12 chenjiahan

需要帮忙排查的话,你可以提供一个基于 quasar 的最小复现仓库给我们。

(node:68954) [DEP0148] DeprecationWarning: Use of deprecated folder mapping "./es/" in the "exports" field module resolution of the package at /.../node_modules/vant/package.json. Update this package.json to use a subpath pattern like "./es/*".

node -> stable (-> v16.13.1) (default)

"vant": "^3.3.7",

panhezeng avatar Dec 29 '21 03:12 panhezeng

/.../node_modules/vant/es/lazyload/index.js:1 import { Lazyload } from './vue-lazyload'; ^^^^^^

SyntaxError: Cannot use import statement outside a module at Object.compileFunction (node:vm:352:18) at wrapSafe (node:internal/modules/cjs/loader:1031:15) at Module._compile (node:internal/modules/cjs/loader:1065:27) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10) at Module.load (node:internal/modules/cjs/loader:981:32) at Function.Module._load (node:internal/modules/cjs/loader:822:12) at Module.require (node:internal/modules/cjs/loader:1005:19) at require (node:internal/modules/cjs/helpers:102:18) at _require (/.../node_modules/@quasar/ssr-helpers/lib/create-bundle.js:56:9) at Object.vant/es/lazyload (render-app.js:4772:18) No issues found. No issues found.

import { Lazyload } from "vant";

    getCustomTransformers: () => ({
      before: [
        tsImportPluginFactory({
          libraryName: "vant",
          libraryDirectory: "es",
          style: false,
        }),
      ],
    }),

====================

我把rm -rf node_modules package-lock.json yarn.lock 删了, 重新用yarn 安装包后,又不报错SyntaxError: Cannot use import statement outside a module的错误了,也没有[DEP0148] DeprecationWarning 警告了。无语了。

感觉是npm的问题,先用npm i就会报错,如果删除 node_modules package-lock.json yarn.lock 后,先用yarn 安装生成lock,再npm i 生成 package-lock 就没问题。无语了。

npm 8.2.0 yarn 1.22.17 node v16.13.1

panhezeng avatar Dec 29 '21 03:12 panhezeng

(node:77087) [DEP0148] DeprecationWarning: Use of deprecated folder mapping "./lib/" in the "exports" field module resolution of the package at /.../node_modules/vant/package.json. Update this package.json to use a subpath pattern like "./lib/*". (Use node --trace-deprecation ... to show where the warning was created)

panhezeng avatar Dec 29 '21 03:12 panhezeng

Vue 官方已修复 Teleport 导致的 : Hydration node mismatch 问题,参见 https://github.com/vuejs/core/issues/5126#issuecomment-1129551606

chenjiahan avatar Sep 11 '22 01:09 chenjiahan

我们使用vite4 中使用了vant4
然后就会提示如下错误:

  Error: ERR_UNKNOWN_FILE_EXTENSION .css /app/node_modules/vant/es/style/base.css
  at defaultGetFormat (/app/node_modules/ts-node/dist-raw/node-internal-modules-esm-get_format.js:93:15)
  at defer (/app/node_modules/ts-node/src/esm.ts:296:7)
  at entrypointFallback (/app/node_modules/ts-node/src/esm.ts:304:22)
  at getFormat (/app/node_modules/ts-node/src/esm.ts:338:26)
  at /app/node_modules/ts-node/src/esm.ts:245:17
  at addShortCircuitFlag (/app/node_modules/ts-node/src/esm.ts:409:21)
  at load (/app/node_modules/ts-node/src/esm.ts:239:12)
  at load (/app/node_modules/ts-node/src/child/child-loader.ts:18:36)
  at nextLoad (node:internal/modules/esm/loader:163:28)
  at ESMLoader.load (node:internal/modules/esm/loader:605:26)

我们的加载方式是 import vue from "@vitejs/plugin-vue"; import Components from "unplugin-vue-components/vite"; import { VantResolver } from "unplugin-vue-components/resolvers";

export default { plugins: [ vue(), Components({ resolvers: [VantResolver()], }), ], };

anjiacm avatar May 16 '23 05:05 anjiacm