[debug日记]

[Vue Router warn]: Component “default” in record with path “/xxx” is a function that does not return a Promise. If you were passing a functional component, make sure to add a “displayName” to the component. This will break in production if not fixed.

【方案一】

一种可能的解决方法是更改你的导入组件的路径。
当使用vite时,使用了一款插件dynamic-import-vars进行动态导入有只能使用相对路径的要求。

这些限制的中文翻译如下:


限制

要知道在汇总包中注入什么,我们必须能够对代码进行一些静态分析,并对可能的导入做出一些假设。比如当你只使用一个变量,理论上您可以从整个文件系统中导入任何内容。

function importModule(path) {// 鬼知道这里会导入什么?return import(path);
}

为了帮助静态分析,并避免可能的脚枪,我们仅限于以下几条规则:

导入必须以 ./ 或者 ../开头

所有导入(import)必须使用相对被导入文件的路径。导入**允许以一个变量开头、使用绝对路径**,或者裸导入

// 不允许
import(bar);
import(`${bar}.js`);
import(`/foo/${bar}.js`);
import(`some-library/${bar}.js`);

导入必须带有一个文件扩展名

一个文件夹可能包含了你不想导入的东西。 所以我们要求在静态部分的导入以一个文件扩展名来结尾。

// 不允许
import(`./foo/${bar}`);
// 允许
import(`./foo/${bar}.js`);

导入你自己的目录时必须指定一个文件名字符串模板

当你导入你的目录,你可能最终会得到你不想导入的文件,包括你自己的模块,基于这个原因要求指定一个文件名字符串模板

// 不允许
import(`./${foo}.js`);
// 允许
import(`./module-${foo}.js`);

因此,虽然你在vite配置文件vite.config.ts(或js)中配置了defineConfig中的resolve.alias字段以指定了别名,但是由于插件只允许使用相对路径,因此导致报错。
因此改成以./或者以../开头的相对路径就好。

【方案二】

可以给vue-routercomponent 字段返回一个 Promise将的组件作为value传入resolve。
请返照以下思路:

{path:..., ..., component:() =>  Promise.resolve(your_component)}

实际上遇到这种情况时更可能是在使用一个函数导入一个异步组件,比如这样:

import { defineAsyncComponent } from "vue" const AsyncComp = defineAsyncComponent(() =>new Promise((resolve, reject) => {resolve(...)})
)

其中解决函数中可以直接指定一个描述VUE组件的对象。也可以导入,即:

const AsyncComp = defineAsyncComponent(() => import("./components/LoginPopup.vue"))

可以打开vue router源码的类型声明文件相关部分内容:

这里默认给出的为defineAsyncComponent第一个参数loader,就是VUE文件的路径。更详细的请自行看这部分源码了解。

function defineAsyncComponent(source) {if (shared.isFunction(source)) {source = { loader: source };}const { loader, loadingComponent, errorComponent, delay = 200, timeout, // undefined = never times outsuspensible = true, onError: userOnError } = source;let pendingRequest = null;let resolvedComp;let retries = 0;const retry = () => {retries++;pendingRequest = null;return load();};const load = () => {let thisRequest;return (pendingRequest ||(thisRequest = pendingRequest =loader().catch(err => {err = err instanceof Error ? err : new Error(String(err));if (userOnError) {return new Promise((resolve, reject) => {const userRetry = () => resolve(retry());const userFail = () => reject(err);userOnError(err, userRetry, userFail, retries + 1);});}else {throw err;}})// !!! 当 Promise 为resolve 的时候,.then((comp) => { if (thisRequest !== pendingRequest && pendingRequest) {return pendingRequest;}if (!comp) {warn(`Async component loader resolved to undefined. ` +`If you are using retry(), make sure to return its return value.`);}// interop module defaultif (comp &&(comp.__esModule || comp[Symbol.toStringTag] === 'Module')) {comp = comp.default;}if (comp && !shared.isObject(comp) && !shared.isFunction(comp)) {throw new Error(`Invalid async component load result: ${comp}`);}resolvedComp = comp; return comp;})));};return defineComponent({name: 'AsyncComponentWrapper',__asyncLoader: load,get __asyncResolved() {return resolvedComp;},setup() {const instance = currentInstance;// already resolvedif (resolvedComp) {return () => createInnerComp(resolvedComp, instance);}const onError = (err) => {pendingRequest = null;handleError(err, instance, 13 /* ASYNC_COMPONENT_LOADER */, !errorComponent /* do not throw in dev if user provided error component */);};// suspense-controlled or SSR.if ((suspensible && instance.suspense) ||(isInSSRComponentSetup)) {return load().then(comp => {return () => createInnerComp(comp, instance);}).catch(err => {onError(err);return () => errorComponent? createVNode(errorComponent, {error: err}): null;});}const loaded = reactivity.ref(false);const error = reactivity.ref();const delayed = reactivity.ref(!!delay);if (delay) {setTimeout(() => {delayed.value = false;}, delay);}if (timeout != null) {setTimeout(() => {if (!loaded.value && !error.value) {const err = new Error(`Async component timed out after ${timeout}ms.`);onError(err);error.value = err;}}, timeout);}load().then(() => {loaded.value = true;if (instance.parent && isKeepAlive(instance.parent.vnode)) {// parent is keep-alive, force update so the loaded component's// name is taken into accountqueueJob(instance.parent.update);}}).catch(err => {onError(err);error.value = err;});return () => {if (loaded.value && resolvedComp) {return createInnerComp(resolvedComp, instance);}else if (error.value && errorComponent) {return createVNode(errorComponent, {error: error.value});}else if (loadingComponent && !delayed.value) {return createVNode(loadingComponent);}};}});
}

附:标准的JavaScript动态导入是不要求相对路径的:

动态导入-摘录自MDN

标准导入语法是静态的,并且总是会在加载时评估导入模块中的所有代码。在您希望有条件地或按需加载模块的情况下,您可以改用动态导入。以下是您可能需要使用动态导入的一些原因:

仅在必要时使用动态导入。静态形式更适合加载初始依赖项,并且可以更容易地从静态分析工具和tree shaking中受益。

要动态导入模块,import可以将关键字作为函数调用。以这种方式使用时,它会返回一个承诺。

import('/modules/my-module.js').then((module) => {// Do something with the module.});

复制到剪贴板

这种形式也支持await关键字。

let module = await import('/modules/my-module.js');

[Vue Router warn]: Component “default“ in record with path “/xx“ is a function that does not return相关推荐

  1. 报错 Component “default“ in record with path “/“ is a Promise instead of a function that return ...

    vue3+vite2 抱错 vue-router.esm-bundler.js:72 [Vue Router warn]: Component "default" in recor ...

  2. 已解决vue-router4路由报“[Vue Router warn]: No match found for location with path“

    vue-router4动态加载的模式下,当我们在当前页面刷新浏览器时,会出现一个警告 [Vue Router warn]: No match found for location with path ...

  3. vue-router.esm-bundler.js6c0271 [Vue Router warn] No match found for location with path

    vue-router.esm-bundler.js6c02:71 [Vue Router warn]: No match found for location with path 又是低级问题,上图 ...

  4. vue-router.esm-bundler.js?6c02:71 [Vue Router warn]: No match found for location with path

    vue-router.esm-bundler.js?6c02:71 [Vue Router warn]: No match found for location with path 又是低级问题,上图 ...

  5. [Vue Router warn]: Discarded invalid param(s) “id“ when navigating. Seexxxxxxxfor more details

    警告信息建议访问的链接 场景: 当我 在vue3 组合式api中尝试使用name+params去路由跳转并传递参数的时候,出现警告信息,并且接收不到params的参数.代码如下: a页面跳转b页面 / ...

  6. Vue Router路由守卫

    全局前置.后置路由守卫 router/index.js import Vue from 'vue'; import VueRouter from 'vue-router'; import List f ...

  7. Vue | Vue Router 路由的使用

    文章目录 一.路由的基本使用 1.创建 Vue 项目并引入 vue-router 2.编写 Components 组件 3.编写路由文件 4.在主文件 Main.js 中引入路由 5.添加 route ...

  8. Vue源码 Vue Router(三)matcher 路由匹配器

    Vue源码 Vue Router(三)matcher Vue源码 Vue Router(三)matcher matcher createMatcher addRoutes match 总结 单步调试参 ...

  9. Vue Router的详细教程

    Vue Router的详细教程 安装 #直接下载 / CDN https://unpkg.com/vue-router/dist/vue-router.js Unpkg.com 提供了基于 NPM 的 ...

最新文章

  1. 论坛报名 | 人工智能与疫情精准防控
  2. CMake 指定安装目录
  3. jboss1.7_在JBoss 7中使用HA Singleton
  4. mysql 索引语法_MySQL 索引:语法及案例剖析
  5. 【深度学习】当YOLOv5遇见OpenVINO!
  6. python实验三答案_20194123 实验三《Python程序设计》实验报告
  7. Mysql半双工主从复制
  8. 零基础学Java的10个方法
  9. 李善友:为什么外企人不敢创业
  10. VSCode配置PyQt5和designer
  11. 开发者生态与双引擎:华为的雄心壮志!
  12. SwiftyJSON的基本用法
  13. oracle获取字符的长度的函数,oracle取字符串长度的函数length()和hengthb()
  14. 龙芯3A3000上实现BLFS的轻量级桌面LXDE
  15. php远程登录linux,如何远程连接linux桌面
  16. 树莓派4B 编译安装rtl8192eu usb网卡驱动
  17. Win 7 配置FTP权限
  18. 两个案例带你搞定JBoss Marshalling编解码在Netty中的应用
  19. 2017CCPC中南地区赛暨湘潭大学邀请赛总结
  20. Cadence Allegro解散Group组图文教程及视频演示

热门文章

  1. 【Leetcode 795】Number of Subarrays with Bounded Maximum
  2. 【React】设计高质量的React组件
  3. ValueError: could not broadcast input array from shape (*,*) into shape (*)
  4. C# Programming Study #2
  5. C#通过COM组件调用IDL的pro程序
  6. [Ajax] 如何使用Ajax传递多个复选框的值
  7. 个人开发—进度记录(二)
  8. tesseract-ocr 识别中文扫描图片
  9. macosx安装之旅(1)-硬盘安装
  10. Mono for Android 4.2初探