vant
vant copied to clipboard
SSR使用Popover组件报错Cannot find module和Hydration node mismatch
重现链接
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
我是使用 Quasar Framework ssr , 也是找不到模块,我是手动按需导入的,之前都是好的,升级到3.3.2及以上版本就挂了,只能回滚锁定到 "vant": "3.3.1",
import Lazyload from "vant/lib/lazyload";
[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)
can not find module 的问题已在 3.3.5 版本修复。
@chenjiahan Hydration node mismatch的问题呢?
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)
只要一改 vant/package.json exports 就出各种问题,还是测试得全面点再改吧
是不是应该 写成 **/*
,而不是把*
去掉
回滚锁定到 "vant": "3.3.1" 了
@panhezeng 参见 https://github.com/youzan/vant/pull/10014
@Ben-Ben-B 别急,后续会看。
是不是应该 写成 */ ,而不是把*去掉
这个写法是无效的。目前所有场景都测试过,唯一不兼容的是省略 index 的写法,可以手动补全 index 来避免。
是不是应该 写成 / ,而不是把去掉
这个写法是无效的。目前所有场景都测试过,唯一不兼容的是省略 index 的写法,可以手动补全 index 来避免。
不行啊,还是报错啊,改成index也不行 ,都不行啊。
import Lazyload from "vant/lib/lazyload/index";
import Lazyload from "vant/lib/lazyload/index.js";
为了一个还是beta版本的nuxt3,把整个导入都搞挂了,这个值得吗?而且就算按您说的,唯一不兼容的是省略 index 的写法这一个问题,就不能只改小版本号了,所有用^3的用户,只要没有用加index的,都挂了。
何况还有加了index也不行的情况,比如这个lazyload插件
个人觉得,为某个特定框架的需求,应该使用类似 nuxt plugin 的方式解决,而不是改整个导出设置,这样影响面太大了
实测 import Lazyload from "vant/lib/lazyload/index";
没问题,[email protected] 版本
另外,需要澄清一下,并不是整个导入都挂了,以下情况都是正常的:
- 对于 webpack 用户,任何写法都可以正常引入,webpack 默认会补全 index。
- 对于使用 ssr 框架的用户,推荐的引用方式是
import { XX } from 'vant'
,这种写法可以正常工作,并且在生产环境可以引用到性能更好的压缩后代码。并不推荐直接引用某个相对路径。 - 对于使用 vite 的用户,更没有必要引用相对路径了,vite 默认支持 tree shaking。并且社区中的 unplugin-vue-components 等插件已经完成了适配,在路径中补全了 index。
另外,exports field 也不只是为了兼容 nuxt3,它还会在 SSR 框架下提供 ssr.js 这个性能更优的代码包。
我们会继续寻找合适的方式去兼容省略 index 的写法,在此之前,可以手动补全 index,或者锁定一下版本。
看你的截图,是ssr模式吗?你可以试试 quuasar ts ssr的环境,我再试试插件按需导入吧,之前用ts-import-plugin 好好的,好像也是升级3.3.1以后的版本,就不行了,我再试试在vue ts里面混合 js 使用babel-import-plugin 看能不能解决
需要帮忙排查的话,你可以提供一个基于 quasar 的最小复现仓库给我们。
Hydration node mismatch的问题啥时候看看啊,这个问题会造成SSR页面在客服端无法渲染,直接白屏 @chenjiahan
@Ben-Ben-B 在此 issue 中有讨论:https://github.com/youzan/vant/pull/10099
需要帮忙排查的话,你可以提供一个基于 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",
/.../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
(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)
Vue 官方已修复 Teleport 导致的 : Hydration node mismatch 问题,参见 https://github.com/vuejs/core/issues/5126#issuecomment-1129551606
我们使用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()], }), ], };