Svelte SPA 路由器 - 无效的组件对象错误
Svelte SPA Router - Invalid component object error
我正在使用 SvelteKit 和 svelte-spa-router
。
我的文件结构如下所示:
src/
├─ assets/
├─ lib/
│ ├─ Navbar.svelte
│ ├─ Sidebar.svelte
├─ routes/
│ ├─ about/
│ │ ├─ index.svelte
│ ├─ contact/
│ │ ├─ index.svelte
│ ├─ products/
│ │ ├─ index.svelte
│ ├─ Test.svelte
│ ├─ index.svelte
│ ├─ __layout.svelte
├─ app.css
├─ app.html
__layout.svelte:
(根据上面 link 中的示例。)
<script>
import Router from 'svelte-spa-router'
import Navbar from "$lib/Navbar.svelte";
import Sidebar from "$lib/Sidebar.svelte";
import Home from './index.svelte'
import About from './about/index.svelte'
import Contact from './contact/index.svelte'
import Products from './products/index.svelte'
import Test from './Test.svelte';
const routes = {
// Exact path
'/': Home,
'/about': About,
'/contact': Contact,
'/products': Products,
'/test': Test
}
</script>
<Navbar />
<Sidebar />
<Router {routes} />
<style>
</style>
错误:
Error: Invalid component object
at new RouteItem (Router.svelte:303:23)
at Router.svelte:432:28
at Array.forEach (<anonymous>)
at Router.svelte:431:31
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (/src/routes/__layout.svelte:62:85)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122)
at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26)
控制台:
如果我删除 <Router {routes} />
并使用 <slot></slot>
,一切正常。
关于此错误,我唯一设法找到的是 this GitHub Router.svelte
的源代码(第 #301
行),但没有太大帮助。
我尝试像示例中那样更改组件的名称,但仍然抛出错误(我想也许它们都被称为相同的事实可能是一个错误,我不知道.. .).
通过 localhost:3000/[path]
手动导航也会引发错误,包括 /test
路径,该路径位于与 __layout.svelte
相同的路径之外。我提到后者是因为在第一个link中我提供了作者说:
To display the router, in a Svelte component (usually App.svelte),
first import the router component...
通常从我看到的例子来看,你通常放在 App.svelte
中的结构进入 __layout.svelte
,然后是 index.svelte
,它作为“主页” /“登陆”页面,默认情况下自动进入位于 __layout.svelte
的 <slot />
(以及您可能拥有的任何其他路线)。
最后但同样重要的是,动态导入它们也不起作用。 参见 --> 编辑 3
我理解我尝试过的很多事情可能与问题无关,但问题本身对我来说毫无意义。比如,为什么组件作为 Router
不理解的类型的对象传递? Test.svelte
字面上只有<h1>TEST COMPONENT</h1>
在里面。
编辑:
将以下代码添加到我的 __layout.svelte
的 <script></script>
部分:
// Contains logging information used by tests
let logbox = ''
// Handles the "conditionsFailed" event dispatched by the router when a component can't be loaded because one of its pre-condition failed
function conditionsFailed(event) {
// eslint-disable-next-line no-console
console.error('Caught event conditionsFailed', event.detail)
logbox += 'conditionsFailed - ' + JSON.stringify(event.detail) + '\n'
// Replace the route
replace('/wild/conditions-failed')
}
// Handles the "routeLoaded" event dispatched by the router after a route has been successfully loaded
function routeLoaded(event) {
// eslint-disable-next-line no-console
console.info('Caught event routeLoaded', event.detail)
logbox += 'routeLoaded - ' + JSON.stringify(event.detail) + '\n'
}
// Handles the "routeLoading" event dispatched by the router whie a route is being loaded
// If the route is dynamically imported, such as with the `import()` syntax, then there might be a delay before the route is loaded
function routeLoading(event) {
// eslint-disable-next-line no-console
console.info('Caught event routeLoading', event.detail)
logbox += 'routeLoading - ' + JSON.stringify(event.detail) + '\n'
}
// Handles event bubbling up from nested routes
function routeEvent(event) {
// eslint-disable-next-line no-console
console.info('Caught event routeEvent', event.detail)
logbox += 'routeEvent - ' + JSON.stringify(event.detail) + '\n'
}
之后我在下面放了下面的,如图this test example:
<Router
{routes}
on:conditionsFailed={conditionsFailed}
on:routeLoaded={routeLoaded}
on:routeLoading={routeLoading}
on:routeEvent={routeEvent}
/>
None 个被调用,只有上图中的红色控制台消息。
编辑 2:
根据 Thomas Hennes 的建议,我在 __layout.svelte
文件中用每个组件单独替换了 <Router {routes} />
,如下所示:
<script>
import Router from 'svelte-spa-router'
import Navbar from "$lib/Navbar.svelte";
import Sidebar from "$lib/Sidebar.svelte";
import Home from './index.svelte'
import About from './about/index.svelte'
import Contact from './contact/index.svelte'
import Products from './products/index.svelte'
import Test from './Test.svelte';
const routes = {
// Exact path
'/': Home,
//'/about': About,
//'/contact': Contact,
//'/products': Products,
//'/test': Test
}
</script>
<Navbar />
<Sidebar />
<Routes {routes} />
<style>
</style>
None 他们工作了。
编辑 3:
有趣的是,我注意到动态导入路由会使我的本地服务器崩溃。 xD
const routes = {
// Exact path
'/': wrap({
asyncComponent: () => import('./index.svelte')
}),
'/about': wrap({
asyncComponent: () => import('./about/index.svelte')
}),
'/contact': wrap({
asyncComponent: () => import('./contact/.svelte')
}),
'/products': wrap({
asyncComponent: () => import('./products/.svelte')
}),
'/test': wrap({
asyncComponent: () => import('./Test.svelte')
}),
}
导入哪一个都无所谓,只导入其中一个或同时导入所有。
这是这次冒险的控制台输出:
window is not defined
ReferenceError: window is not defined
at getLocation (Router.svelte:38:31)
at start (Router.svelte:59:23)
at Object.subscribe ([Path to project]/node_modules/svelte/store/index.js:51:20)
at Router.svelte:493:36
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (/src/routes/__layout.svelte:112:85)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122)
at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26)
history is not defined
ReferenceError: history is not defined
at Router.svelte:455:10
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (/src/routes/__layout.svelte:112:85)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122)
at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26)
at render_response (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:561:28)
at async respond_with_error (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:1148:10)
at async respond (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:1392:4)
/node_modules/svelte-spa-router/Router.svelte:413
const match = routesList[i].match(newLoc.location);
^
TypeError: Cannot read properties of null (reading 'location')
at eval (/node_modules/svelte-spa-router/Router.svelte:413:45)
at Object.subscribe ([Path to project]/node_modules/svelte/store/index.js:53:9)
at eval (/node_modules/svelte-spa-router/Router.svelte:406:29)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (/src/routes/__layout.svelte:112:85)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122)
at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26)
at render_response (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:561:28)
svelte-spa-router
被设计为 Svelte 项目(仅客户端)的路由解决方案。它不适用于服务器端呈现的 SvelteKit 项目。
SvelteKit, which is a universal (CSR + SSR) framework, provides its own routing solution,将在客户端和服务器端工作。
我正在使用 SvelteKit 和 svelte-spa-router
。
我的文件结构如下所示:
src/
├─ assets/
├─ lib/
│ ├─ Navbar.svelte
│ ├─ Sidebar.svelte
├─ routes/
│ ├─ about/
│ │ ├─ index.svelte
│ ├─ contact/
│ │ ├─ index.svelte
│ ├─ products/
│ │ ├─ index.svelte
│ ├─ Test.svelte
│ ├─ index.svelte
│ ├─ __layout.svelte
├─ app.css
├─ app.html
__layout.svelte:
(根据上面 link 中的示例。)
<script>
import Router from 'svelte-spa-router'
import Navbar from "$lib/Navbar.svelte";
import Sidebar from "$lib/Sidebar.svelte";
import Home from './index.svelte'
import About from './about/index.svelte'
import Contact from './contact/index.svelte'
import Products from './products/index.svelte'
import Test from './Test.svelte';
const routes = {
// Exact path
'/': Home,
'/about': About,
'/contact': Contact,
'/products': Products,
'/test': Test
}
</script>
<Navbar />
<Sidebar />
<Router {routes} />
<style>
</style>
错误:
Error: Invalid component object
at new RouteItem (Router.svelte:303:23)
at Router.svelte:432:28
at Array.forEach (<anonymous>)
at Router.svelte:431:31
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (/src/routes/__layout.svelte:62:85)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122)
at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26)
控制台:
如果我删除 <Router {routes} />
并使用 <slot></slot>
,一切正常。
关于此错误,我唯一设法找到的是 this GitHub Router.svelte
的源代码(第 #301
行),但没有太大帮助。
我尝试像示例中那样更改组件的名称,但仍然抛出错误(我想也许它们都被称为相同的事实可能是一个错误,我不知道.. .).
通过 localhost:3000/[path]
手动导航也会引发错误,包括 /test
路径,该路径位于与 __layout.svelte
相同的路径之外。我提到后者是因为在第一个link中我提供了作者说:
To display the router, in a Svelte component (usually App.svelte), first import the router component...
通常从我看到的例子来看,你通常放在 App.svelte
中的结构进入 __layout.svelte
,然后是 index.svelte
,它作为“主页” /“登陆”页面,默认情况下自动进入位于 __layout.svelte
的 <slot />
(以及您可能拥有的任何其他路线)。
最后但同样重要的是,动态导入它们也不起作用。 参见 --> 编辑 3
我理解我尝试过的很多事情可能与问题无关,但问题本身对我来说毫无意义。比如,为什么组件作为 Router
不理解的类型的对象传递? Test.svelte
字面上只有<h1>TEST COMPONENT</h1>
在里面。
编辑:
将以下代码添加到我的 __layout.svelte
的 <script></script>
部分:
// Contains logging information used by tests
let logbox = ''
// Handles the "conditionsFailed" event dispatched by the router when a component can't be loaded because one of its pre-condition failed
function conditionsFailed(event) {
// eslint-disable-next-line no-console
console.error('Caught event conditionsFailed', event.detail)
logbox += 'conditionsFailed - ' + JSON.stringify(event.detail) + '\n'
// Replace the route
replace('/wild/conditions-failed')
}
// Handles the "routeLoaded" event dispatched by the router after a route has been successfully loaded
function routeLoaded(event) {
// eslint-disable-next-line no-console
console.info('Caught event routeLoaded', event.detail)
logbox += 'routeLoaded - ' + JSON.stringify(event.detail) + '\n'
}
// Handles the "routeLoading" event dispatched by the router whie a route is being loaded
// If the route is dynamically imported, such as with the `import()` syntax, then there might be a delay before the route is loaded
function routeLoading(event) {
// eslint-disable-next-line no-console
console.info('Caught event routeLoading', event.detail)
logbox += 'routeLoading - ' + JSON.stringify(event.detail) + '\n'
}
// Handles event bubbling up from nested routes
function routeEvent(event) {
// eslint-disable-next-line no-console
console.info('Caught event routeEvent', event.detail)
logbox += 'routeEvent - ' + JSON.stringify(event.detail) + '\n'
}
之后我在下面放了下面的,如图this test example:
<Router
{routes}
on:conditionsFailed={conditionsFailed}
on:routeLoaded={routeLoaded}
on:routeLoading={routeLoading}
on:routeEvent={routeEvent}
/>
None 个被调用,只有上图中的红色控制台消息。
编辑 2:
根据 Thomas Hennes 的建议,我在 __layout.svelte
文件中用每个组件单独替换了 <Router {routes} />
,如下所示:
<script>
import Router from 'svelte-spa-router'
import Navbar from "$lib/Navbar.svelte";
import Sidebar from "$lib/Sidebar.svelte";
import Home from './index.svelte'
import About from './about/index.svelte'
import Contact from './contact/index.svelte'
import Products from './products/index.svelte'
import Test from './Test.svelte';
const routes = {
// Exact path
'/': Home,
//'/about': About,
//'/contact': Contact,
//'/products': Products,
//'/test': Test
}
</script>
<Navbar />
<Sidebar />
<Routes {routes} />
<style>
</style>
None 他们工作了。
编辑 3:
有趣的是,我注意到动态导入路由会使我的本地服务器崩溃。 xD
const routes = {
// Exact path
'/': wrap({
asyncComponent: () => import('./index.svelte')
}),
'/about': wrap({
asyncComponent: () => import('./about/index.svelte')
}),
'/contact': wrap({
asyncComponent: () => import('./contact/.svelte')
}),
'/products': wrap({
asyncComponent: () => import('./products/.svelte')
}),
'/test': wrap({
asyncComponent: () => import('./Test.svelte')
}),
}
导入哪一个都无所谓,只导入其中一个或同时导入所有。
这是这次冒险的控制台输出:
window is not defined
ReferenceError: window is not defined
at getLocation (Router.svelte:38:31)
at start (Router.svelte:59:23)
at Object.subscribe ([Path to project]/node_modules/svelte/store/index.js:51:20)
at Router.svelte:493:36
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (/src/routes/__layout.svelte:112:85)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122)
at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26)
history is not defined
ReferenceError: history is not defined
at Router.svelte:455:10
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (/src/routes/__layout.svelte:112:85)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122)
at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26)
at render_response (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:561:28)
at async respond_with_error (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:1148:10)
at async respond (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:1392:4)
/node_modules/svelte-spa-router/Router.svelte:413
const match = routesList[i].match(newLoc.location);
^
TypeError: Cannot read properties of null (reading 'location')
at eval (/node_modules/svelte-spa-router/Router.svelte:413:45)
at Object.subscribe ([Path to project]/node_modules/svelte/store/index.js:53:9)
at eval (/node_modules/svelte-spa-router/Router.svelte:406:29)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (/src/routes/__layout.svelte:112:85)
at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122)
at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22)
at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26)
at render_response (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:561:28)
svelte-spa-router
被设计为 Svelte 项目(仅客户端)的路由解决方案。它不适用于服务器端呈现的 SvelteKit 项目。
SvelteKit, which is a universal (CSR + SSR) framework, provides its own routing solution,将在客户端和服务器端工作。