Refactor project with TypeScript and JSX & Support LeetCode Card
Content
- Migrate source codes to TypeScript to reduce coding error rate.
- Abstract logic by OOP, all cards based on class Card, easier to create new type of card.
- Support JSX and function component, help to reuse svg structure.
- Clearify project hierarchy and style hierarchy
- Coverage test bottom-up
Advantage
With a clear project hierarchy
- utils: Basic unit functions, e.g. encodeHTML/clampValue/retry......
- helpers: Classes with specific feature, I18n for internationalization, Error for internal error system, SVGRender for parse jsx to svg string
- components: the system supports function component(like react), put all resuable components to this folder, e.g. FlexLayout/CircleProgress/Progress
- cards: describe the main logic of one type of card, how to initialize exclusive options/how to fetch data and process it/how to render svg by jsx.
Easy to create new type of card
Based on Card class which declare the workflow: preprocess -> checkProps -> fetchData -> renderCard -> setCache, also catch error. Extend it and fill in needed part, I've provided a script npm run create [cardName] to generate a new card by template, like, npm run create leetcode.
With dynamtic router, it's easy to maintain path-card by cards/index.ts
import GitHubStats from "./github-stats";
import GithubTopLangs from "./github-top-langs";
import GithubPinRepo from "./gituhb-pin-repo";
import WakaTime from "./wakatime";
export default {
stats: GitHubStats,
"top-langs": GithubTopLangs,
pin: GithubPinRepo,
wakatime: WakaTime,
};
Test coverage
With a clear project hierarchy, it's easier to work with unit tests.


Project Preview
https://github-readme-stats-git-master-curly210102.vercel.app/api/wakatime?username=curly_brackets&hide=json,css
@anuraghazra When I tried to create leetcode card, I found it is not a interesting experience with lots of duplicate files. So some ideas pop-up: TypeScript to increase develop efficiency, a small render framework to reuse code, and import powerful chart library(echarts, highcharts or other). I really hope to do some improvment for this project, meanwhile, if you have a different plan, I'd like to start another project and continue this PR.
@curly210102 is attempting to deploy a commit to the github readme stats Team on Vercel.
A member of the Team first needs to authorize it.
Hi @curly210102 this is super cool, and a hell lot of work! 💯
Wow! Thank you!
As much as I appreciate all the hard work and effort you put in to do this huge refactor, It would have been really good if you first opened an issue or discussed about the changes you were going to make.
I'm saying this because I know you probably poured some good amount of your own time to contribute to this project which is highly appreciate, But I can't really guarantee that I would be able to merge this whole PR (maybe just parts of it), and here's why
Note: I haven't looked at the full code, only glossed over it
Things what I liked
-
TypeScript migration We actually had plans for doing a whole typescript migration even @Bas950 was working on it #832 which I didn't got time to look into.
-
The Card class, the changes which are made to the class card and the whole workflow of
preprocess -> checkProps -> fetchData -> renderCard -> setCacheI really liked and I will love to have this it will make things nicer. -
The Error handling logic is amazing, it gives more info to the user and throws really good errors.
-
Of course the helpers are also nicely refactored.
Things which I'm concerned with
Now these are the things which i'm concerned with and probably does not align with current requirement of this project
- JSX Yes it's really cool to have a custom JSX factory and using JSX is far more nicer than using strings. But there is a reason why choose strings in the first place, which is performance. github-readme-stats calculates everything on the runtime and vercel's serverless timeouts are really fragile and since we also fetch/process and render the card keeping things performant is must otherwise the function execution can take more time, and this is where JSX might not be the right choice because of it's runtime overhead.
Yes i do not have metrics over the JSX vs strings performance but as I've observed from the start strings worked out well for most of the use case and JSX seems a bit overkill for this.
- Breaking changes There i can see some huge breaking change which is because this PR changed the api URLs to be /stats /top-langs /wakatime, which will be a breaking change and all the /api routes will stop working if we deploy this.
There might be some more breaking changes relating to core logic and rendering which I haven't checked out so if you have anything list of breaking changes do let me know/
- Leetcode card
We actually don't have any plans to add any further card for the moment, atleast not any for external stats (like leetcode) We don't want to bloat github-readme-stats with lots of stat cards.
Sidenote: I could not able to get it work with vercel running
vercel devis throwing error Error while parsing "D:\CAM Files\Javascript\github-readme-stats\tsconfig.json" SyntaxError: Unexpected token } in JSON at position 199 Is there any prerequisites to setup the project or build it?
Hi, @anuraghazra, Thanks for the reply.
It's really excited that you also agree with most of the core points. And I got a lot of inspiration from your reply.
- I realized that I should dicussion it first when the job almost completed 😂. I start working on it after the idea popup, didn't realize it would be a big job. And my starting point is to add a Leetcode card, then extend the idea of creating a clear workflow, the purpose is more closest to provide a framework to "display stats in markdown" rather than "display github stats in github readme". This is related to the positioning of project, as you mentioned github-readme-stats focus on github stats and not plan to add any further card, I agree with this view, less is more.
- JSX, Yes JSX and component can be replaced with string and function, maybe more flexibility and elegance, but the performance of vercel is an more important factor.
- Breaking changes, dynamic route is still work with /api, /api/top-langs, /api/pin, /api/wakatime, and add /api/stats which is same with /api, the query parameters have not changed either.
TypeScript, the Card class, project structure are still suitable for this project, but it's a big change, I think PR to another branch is better. My plan is to update code to apply to this project and create another repo for "generate stats with SVG"
Error while parsing "D:\CAM Files\Javascript\github-readme-stats\tsconfig.json" SyntaxError: Unexpected token } in JSON at position 199
This error may because haven't install TypeScript in project, you can try to run npm install or npm install typescript.