Dudes. There are breaking changes in SvelteKit [on December 2022]. That means that my previous post on that topic is garbage now.
For those, who builds enterprise projects, not just landing-pages, and want to name your files and organise your folders based on domains (DDD), or based on technical convenience, rather than on url structure dictated by "marketing needs"; and get full control and flexibility, like — two different urls match one component etc. — please — welcome.
So. After a full day of research and code I've ended up with..
As a first step, let's check what is going on in SvelteKit's depths. Open file:
node_modules/@sveltejs/kit/src/core/sync/create_manifest_data/index.js
Navigate to:
292: prevent_conflicts(routes);
And print:
+ 293: console.log(routes);
It'l give us a complex array of objects as the result of defaults walking through file structure.
And that's exactly what we have to define somehow and somewhere in code.
So, what literally have I done...
I. In root of src/
create routes.js
...
... where I've places both routes
array with custom basic rules and router()
function that transforms that rules to array of objects that we've seen in console.log(routes)
:
const routes = [
{id: '/', pattern: /^\/$/, page: 'home.svelte', layout: 'layout.svelte', segment: ''},
{id: '/[slug]', pattern: /^\/([^/]+?)\/?$/, params: ['slug'], page: 'article/article.svelte', layout: 'article/layout.svelte', parent_layout_segment: ''}
]
export function router(routes_dir) {
const result = []
for (const route of routes) {
const parent = result.find(o => o.segment === route.parent_layout_segment)
const new_route = {
parent: parent,
id: route.id,
segment: route.segment,
pattern: route.pattern,
params: (route.params || []).map((param, index) => ({name: param, matcher: undefined, optional: false, rest: false, chained: false})),
layout: {
depth: route.layout_depth || route.depth || 0,
child_pages: [],
component:route.layout && routes_dir + route.layout,
shared: route.layout_js && routes_dir + route.layout_js,
server: route.layout_server_js && routes_dir + route.layout_server_js,
},
error: {
depth: route.error_depth || route.depth || 0,
component: route.error && routes_dir + route.error
},
leaf: {
depth: route.leaf_depth || route.depth || 0,
shared: route.page_js && routes_dir + route.page_js,
server: route.page_server_js && routes_dir + route.page_server_js,
component: routes_dir + route.page,
},
endpoint: route.server_js && {
file: routes_dir + route.server_js,
},
page: null, // Have no idea what is it for, but let it be here, just not to forget
}
result.push(new_route)
}
return result;
}
About params in routes object:
- id — need to be unique. Also goes to client manifest.
-
segment — also need to be unique, and it is needed to create nested layouts. So, another rule can use
parent_layout_segment
to refer parent layout (empty string is also ok). -
params — needed in case of dynamic slugs. Each round parentheses in
pattern
should be presented inparams
array, like:{pattern: /^\/(\d+)\/(\d+)\/?$/}, params: ['year', 'month']}
- You know, SvelteKit do not have only
+page.svelte
and+layout.svelte
, but also: -
+page.js
so{ ... page_js: 'my_page.js' ... }
could be passed in rule; -
+page.server.js
—>page_server_js
; -
+server.js
—>server_js
; -
+layout.js
—>layout_js
; -
+layout.server.js
—>layout.server_js
; - Didn't notice any changes in playing with some
depth
param, but, just in case we can pass: -
layout_depth
; -
page_depth
; -
error_depth
; -
depth
(global); Just in case we'll find one day that it matters)
II. In svelte.config.js
import adapter from '@sveltejs/adapter-auto';
+ import {router} from './routes.js'; // <— add this
/** @type {import('@sveltejs/kit').Config} */
const config = {
+ routes: router(), // <— add this
kit: {
adapter: adapter(),
}
};
export default config;
III. In already familiar
node_modules/@sveltejs/kit/src/core/sync/create_manifest_data/index.js
:
1) Replace file system walking result with our code routes
292: prevent_conflicts(routes);
+ 293: routes.length = 0;
+ 294: routes.push(...config.routes);
2) We do not need any magic sorting any more
372: return {
373: nodes,
- 374: routes: sort_routes(routes)
+ 375: routes: routes
376: };
IV. Install patch-package
, so this changes will be automatically applied in future without manual hacks:
> npm i patch-package
> npx patch-package @sveltejs/kit
package.json
:
{
...
"scripts": {
...
"postinstall": "patch-package" // <— add this
Top comments (2)
but why
also you sound a bit weird, are you a non-native speaker?
Hi! At least because "me as a developer" (sounds like user story :D ), want to organise my code and name files and folders according to project's code-style etc., which was designed to serve "that current enterprise project" needs. So, let's say I just do not want framework to dictate how to name my files and folders, and how to respect its hierarchy. I need total control and flexibility (which only code can give).
And I know, that I am not the only one
So, just for them) I feel their pain too) Probably it would help someone
Ye, I am not native