New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal to reduce router development and maintenance costs by using standardized manifest files #14685
Comments
How about |
|
The reason behind file splits is because we have cold start issue before: every time when there is a need to fetch and compile artifacts based on routes info, or development purposes, we will have to loads all codes even though only small portion of them is useful. It is time consuming to read these files(IO bound) and parse them (as JS file, CPU bound) so I break them as smaller parts based on their usage. From what I observe so far, at least radar.js and maintainer.js are just objects and should be just fine given parsing should be fast nowadays. At that time I was thinking if performance was still an issue, since maintainer.js is just simple an js object and could be even treated as json file. Happy to see this change takes place 🥳 |
These three configuration files are significant improvements over previous practices, providing great convenience for current updates. Thanks to @NeverBehave for this innovation. The most important area that urgently needs improvement now is documents, which have caused the greatest inconvenience and lack of standardization, and are also the biggest obstacle to this proposal implementation. |
export default {} satisfies RouterManifest I think it should be in doc and not related to this proposal. Proposed here as an enhancement. |
@DIYgod Thanks for the kind word, and the docs part is annoying indeed. I have some preliminary thoughts of the current proposal:
Instead of coupling these markdowns in {
description: {
"en-us": `some description about this route`
// if a specific route translate is missing, show corresponded key instead.
// However I think there are better way/lib to handle this, just build the right key, not sure if we can enforce this as type check
},
"routes.<path>.parameters.since": {
"en-us": `...`,
"zh-cn": `...`
},
} When building the docs, we can group all of these keys with their prefix, say Still I think multi line markdown in ts is a bit tricky to handle but it should be fine...? The following might be a bit nitpicks :P so just leave here for some ideas.
|
I think if the doc is split into a file. |
|
I understand the fact that we want to keep it simple as we goes, while from my pov, if we strip out this flexibility that allow maintainer/community to add custom notes specific to their language it would a great setback. With that being said, there are two things to add here:
|
I think it's a good idea to use separate files for different languages, because the name and url may vary depending on the language. In this way, we can have multiple manifest files |
If we just export some customized "middleare" functions to define manifest metadata and write handler logic at the same time so that we don't need many manifest files, and also ensure the typings easily. Example: // index.ts
import { defineRootRoute } from "common"
import trending from "./trending"
export default defineRootRoute({
name: "GitHub",
url: "https://github.com/",
description: "...",
// ... other basic metadata,
routes: [
trending
]
}) // trending.ts
import { defineSubRoute } from "common"
export default defineSubRoute({
name: 'Trending',
description: "...",
url: "/trending/:since/:language/:spoken_language?"
// ... other basic metadata,
route: "./trending",
parameters: {
since: {
type: "string",
description: "time frame, available in [Trending page](https://github.com/trending/javascript?since=monthly) \'s URL, possible values are: `daily`, `weekly` or `monthly`",
},
// ... we could even use "zod" to define the parameters for more strict typings
},
handler: async (ctx) => {
// ...
}
}) |
Although there are not many manifest files, there are many index files, the difference is not very obvious 🤣 It is a good idea to use the factory method to ensure type correctness. Defining manifest in each route module seems good, but it is not a good idea in the special scenario of RSSHub, because this requires RSSHub to load all route files. In the current situation where there are too many routes, it will cause significant performance issues (RSSHub still has to use |
Yes, in this case, loading all modules could be time-consuming. The current dynamic loading method is more ideal. We could actually keep this dynamic loading with the factory methods, e.g., do not relative importing routes or use manual dynamic importing:
But it doesn't make anything more beneficial than it is now. I was also thinking that this docs+logic merging could avoid writing duplicated information. Since we still have to load all the files when generating documents anyway, what do you think of the way to merge the manifest and handler function? |
@Songkeys But the problem is, if the route module is not loaded, the route information cannot be obtained, and the path of the route cannot be obtained to initialize Hono (Hono needs to pass in all paths at the beginning and cannot be passed dynamically). The problem lies not in I think it's a good idea to define a factory function, and the handler can also be included in this factory function. I think it's okay to load all files when generating documents, even if loading all routes is not a problem, because it is one-time and does not need to run on users' machines that may have poor performance. |
I think The imported routes shall be asynchronous iterable/generator. The performance should be adequate. |
So, I think it's also okay to generate the route information when pushing every commit? This is like the idea of caching the result instead of dynamically browsing and loading the directories every time when starting up. |
@SettingDust Performance issues refer to the need to load a lot of module during initialization and running, rather than during the request process. @Songkeys This is feasible, but I doubt if it's worth it. Imagine a developer who wants to add a route. He needs to first add the module, then execute this generation script before debugging and running so that Hono can load his newly added route correctly. |
If this generating step only takes a few seconds, I think it's okay. But I'm not sure. The whole idea is to avoid writing verbose route information (i.e. some repeated metadata in splitted files). It's more like a tradeoff - writing less code means generating more code in dev-stage or spending more time figuring out the result in prod-stage. |
I came up with a good solution. We can import all modules in the development environment, and use cached results in the production environment. This is great as it can avoid confusion when there are too many routes under the namespace. |
@NeverBehave @SettingDust @Songkeys @TonyRL Hey guys, based on the suggestions above, I have implemented a minimal version here. Please help check if it looks reasonable. I will migrate all routes later today. The cache routing path for the production environment and document generation are not yet completed. |
What feature is it?
To add a new route, developers currently have to create three files in the namespace:
maintainer.ts
,radar.ts
, androuter.ts
, as well as manually adding documents. This process is cumbersome, non-standardized, error-prone, and challenging for review. To address this issue, a new development and maintenance approach is suggested: simply include amanifest.ts
file with all necessary information in a fixed format within the namespace. The RSSHub core will then read this manifest file to load routes. Moreover, automated scripts will generate the required markdown files for documentation purposes.What problem does this feature solve?
As mentioned above
Additional description
Update2: Implement here #14718
Update1: #14685 (comment)
(Outdated) I propose a preliminary manifest format here:
For example:
This is not a duplicated feature request or new RSS proposal
The text was updated successfully, but these errors were encountered: