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