![require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages](https://cdn.sanity.io/images/cgdhsj6q/production/be8ab80c8efa5907bc341c6fefe9aa20d239d890-1600x1097.png?w=400&fit=max&auto=format)
Security News
require(esm) Backported to Node.js 20, Paving the Way for ESM-Only Packages
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
Collect and generate route data from a file-based router such as svelte-kit's
<!-- before -->
<script lang="ts">
import { goto } from '$app/navigation';
goto('/organiztion/org-abc/members/member-123/posts/prefix-too-much-literals-no-safety');
// => 404 because organiztion is a typo
</script>
<!-- after -->
<script lang="ts">
import { goto } from '$app/navigation';
import { AppRoutes, route } from '$generated/routing';
goto(
route(
AppRoutes.organization.$orgId.members.$memberId.posts.prefix$slug,
'org-abc',
'member-123',
'type-support-no-typo',
),
);
</script>
npm install -D roullector
yarn add --dev roullector
pnpm install -D roullector
This package was initially built and tested for svelte-kit. But I expect it to work in other cases using the configurable options. Examples used in this docs will use svelte-kit common route setup.
If you are using svelte-kit and want a no lock-in jump start, do, at project root,...
npx roullector collect
...and inspect the src/generated/routing
directory for the generated goodies.
If you have a directory that contains some routes like below...
src/routes/
├── __components/
| ├── Navbar.svelte
| └── Footer.svelte
├── __layout.svelte
├── __error.svelte
├── me.svelte
├── sign-in.svelte
├── sign-up.svelte
├── index.svelte
└── admin/
├── __components/
| ├── Admin.layout.svelte
| ├── types.ts
└── users/
├── [id]/
| ├── __layout.svelte
| ├── index.svelte
| ├── types.ts
| └── posts/
| ├── [post_id].svelte
| ├── s-[slug].svelte
| └── l-[short-link]-l.svelte
└── index.svelte
...and a npm script that run roullector
with default options,...
// package.json
{
"scripts": {
"codegen:routing": "roullector collect"
}
}
...the following files will be generated:
// src/generated/routing/routes.json
{
"admin": {
"users": {
"$id": {
"index": "/admin/users/[id]",
"posts": {
"$postId": "/admin/users/[id]/posts/[post_id]",
"l$shortLink$L": "/admin/users/[id]/posts/l-[short-link]-l",
"s$slug": "/admin/users/[id]/posts/s-[slug]",
"__dir": "/admin/users/[id]/posts"
}
},
"index": "/admin/users"
},
"__dir": "/admin"
},
"index": "/",
"me": "/me",
"signIn": "/sign-in",
"signUp": "/sign-up"
}
// src/generated/routing/index.ts
export { default as AppRoutes } from './routes.json';
/**
* build a complete path with injected arguments
* @param path {string} based path
* @param args {string[]} arguments to inject
*/
export function route(path: string, ...args: string[]): string {
const params = path.match(/\[[a-zA-Z_-]+\]/g) ?? [];
for (const i in params) {
path = path.replace(params[i], args[i]);
}
return path;
}
Notice that index.ts
will import json, you need to configure your tsconfig.json
to enable resolveJsonModule
:
// tsconfig.json
{
"compilerOptions": {
"resolveJsonModule": true
}
}
You can then use the route
helper to construct a complete path with typescript support built-in. For example:
import { AppRoutes } from '$generated/routing'; // or use relative path
const path = route(AppRoutes.admin.users.$id.posts.s$slug, 'user-id-123', 'slug');
// path = '/admin/users/user-id-123/posts/s-slug'
// ... later
// navigate(path);
Run npx roullector collect help
to for configurable options in command-line mode
name | default | description | cli equivalent |
---|---|---|---|
inDir | 'src/routes' | input directory path to collect route data from | -i, --inDir |
extensions | ['.svelte'] | file extensions to accept | -e, --extensions (comma-separated) |
ignorePatterns | [/^_/] | patterns to ignore filenames | -x, --ignorePatterns (comma-separated) |
output | true | write generated files to disk?, if false will print to console | --no-output |
outDir | 'src/generated/routing' | output directory | -o, --outDir |
depth | Infinity | depth of directory traversal | -d, --depth |
dirkey | __dir | key to save path for directories with no index file | -k, --dirkey |
keyTransform | [dollarArgify(), camelCasify()] | how to transform route key in mapping | -t, --keyTransform (allows multiple) |
utils | true | generate utils for building path? | --no-utils |
typescript | true | generate files in typescript? | --no-typescript |
verbose | false | print more info during operation (for cli only) | --verbose |
Notes:
keyTransform
dollarArg | camelCase | none
,--keyTransform=dollarArg --keyTransform=camelCase
. The transforms will be applied in the order they are provided.AppRoutes['a-kebab-case']['[id']
.--keyTransform=none
.true
), the cli equivalent is --no-<option>
, meaning only add the flag if you want to negate the option.import {
collect,
defaultCollectOptions,
camelCasify,
dollarArgify,
compose,
} from `roullector`;
console.log('These are default options:', defaultCollectOptions);
let { json, route } = collect(); // use default options
// json = './src/generated/routing/routes.json'
// route = './src/generated/routing/index.ts'
({ json, route } = collect({ output: false; }); // helpful for testing
// json = generated route mapping content
// route = generated index source
const transformers = [dollarArgify, camelCasify];
({ json, route } = collect({
keyTransform: [
(key, original) => compose(key, ...defaultTransformers),
// key = the current key in the transformation pipeline
// original = the original key before all transformation
],
}))
FAQs
collect and generate map from file-based routers
We found that roullector demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
require(esm) backported to Node.js 20, easing the transition to ESM-only packages and reducing complexity for developers as Node 18 nears end-of-life.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.