A Personal Site Rebuilt After Five Years Mirrors a Decade-Long Journey from Mechanic to Full-Stack Engineer
Recently, I finally upgraded my website.
Logically, this should be a very happy thing. New pages, new features, new technology, and places I wanted to change before but never got around to were reorganized this time.
But when the moment of switching between the old and new versions actually arrived, I still felt a bit reluctant in my heart.
This old version of the site accompanied me for over five years.
Five-plus years is neither a long time nor a short time. It saw me stay up late updating with great enthusiasm, and it also saw me not open the backend for a long time because I was busy with work and life. When I was in good shape, I would write articles, modify pages, and tinker with a new feature; when I had nothing to write, I would casually jot down a small thing that just happened.
Looking back now, those contents are not all complete, nor can they be called very valuable. Some are just a few sentences, some are a small pitfall I stepped into at the time, and for some, I can't even remember the context anymore.
But it is precisely these fragmentary records that let me see my past self again.
It turns out I would be happy for a long time because the website gained a new feature; it turns out I once repeatedly modified a single image or a style; it turns out work, travel, reading, fitness, and some feelings I didn't have time to articulate were all quietly left here.
On the surface, it is a website; in reality, it is more like a diary written intermittently over many years.
Welcome to visit 航栈 | Let Creation Continue
Old Version
A Decade, Also Hidden in This Website
If I dial the time back a little further, this website actually records nearly ten years of my professional growth.
At 18, I was an apprentice in an auto repair shop in Anlu, earning only 300 yuan a month. Every day I changed belts, carried engine oil, and changed tires. At night, I would return to bed covered in the smell of engine oil, so tired I would fall asleep quickly. Later, I went to Wuhan, waited tables, and also worked in an optoelectronics factory. The work wasn't easy, and the future was unclear, but I always knew in my heart that this wasn't the life I wanted.
When I opened a Taobao store at 21, I seriously realized the importance of design for the first time. At that time, I took the household registration book behind my family's back, gritted my teeth, and borrowed 30,000 yuan to study UI design. For me at the time, this was not an easy decision, but it became the stepping stone into the internet industry.
After becoming a UI designer, I truly encountered code for the first time while decorating stores. Typing a few characters could turn a design draft into a clickable, interactive webpage—that feeling fascinated me deeply. So I started using my off-hours to watch tutorials, learning bit by bit from HTML, CSS, and JavaScript, slowly stepping into Web frontend.
The self-taught career switch was not smooth. Without a formal academic background and with insufficient ability, the pressure of unemployment and loans once left me breathless. But I didn't give up. Later, I joined a startup company, going from having my code scrutinized daily by the director to eventually being able to independently handle projects, which marked the true completion of my transformation from designer to developer.
In the years that followed, I went from slicing pages and writing interactions to Vue, engineering, and frontend architecture; from only caring about pages in the browser to PHP, Node.js, APIs, MySQL, Redis, Docker, and Nginx; and also grew from a frontend developer to a frontend lead, project manager, and today, to being able to independently complete a full project from the perspective of a full-stack engineer.
When I started building my personal website in 2017, I was actually still working while learning PHP and MySQL. Many newly learned things were immediately tested on the website. When the site could log in, comment, publish articles, or serve as a web directory, I would record an update log. Looking back now, those logs are not just product versions, but also milestones of my learning and growth.
So this website upgrade feels like a ten-year summary for me. From an auto repair apprentice to self-taught Web, then from frontend to full-stack, and now into the AI era, this path is not standard and has had many detours. But precisely because every step was figured out by myself, opening these old codes today makes me especially reluctant to let go.
The Tech Stack That Accompanied Me for Over Five Years
When I rewrote the old site in 2019, I chose a set of solutions I was relatively familiar with at the time: Vue 2 and Webpack 4 for the frontend, ThinkPHP 5, PHP, and MySQL for the backend, and Layui for the admin panel. The server switched from Apache to Nginx, and I also started experimenting with Docker.
The old frontend was not the common single-page application of today, but a multi-page application. The project used pages.js to configure entry points for pages like the homepage, article list, article detail, web directory, community, user center, and update log, which were then packaged by Vue CLI and Webpack into multiple HTML files like index.html, index_thread.html, index_archives.html.
At that time, I also did common code splitting, extracting third-party dependencies and common code into chunk-vendors and chunk-common, generating Gzip compressed files for JavaScript and CSS, and disabling production environment Source Maps. The pages used many libraries like Vue Router, Vuex, Axios, iView, ECharts, mavon-editor, and tui-editor. Looking at the dependency list now feels a bit bloated, but those features were indeed added one by one: article editing, code highlighting, charts, carousels, image cropping, comments, favorites, web directory... each one left traces of tinkering.
The old backend project was a typical ThinkPHP 5 MVC structure. MySQL was responsible for storing data like articles, users, web directories, communities, and update logs, while ThinkPHP simultaneously handled APIs, admin management, and some page template rendering. Nginx was responsible for domain and HTTPS redirects, static resource caching, and API reverse proxying. Many things needed to be pieced together manually back then, but it was precisely this architecture that let me truly experience the complete process from frontend pages, APIs, and databases to server deployment.
A Compromise Made for SEO
The most special part of the old site was an architectural adjustment made to solve SEO issues.
After separating the frontend and backend, Vue pages mainly relied on the browser to load JavaScript and then fetch content via APIs. Users could access it without problems, but search engines crawled very little initial HTML information, and article titles and descriptions couldn't change dynamically based on content. For a website that relied on article and URL indexing, this problem couldn't be left unresolved.
At the time, I didn't switch directly to a full server-side rendering solution. Instead, I kept the Vue 2 development approach and transformed the frontend into Webpack multi-page packaging. The packaged HTML files were then placed into ThinkPHP's view layer and rendered through MVC controllers.
When accessing the homepage, article details, navigation details, or community content, the ThinkPHP controller would first query MySQL based on URL parameters to get the current content's title, keywords, and summary, then inject title, keywords, and description into the page template. After the browser received the page, Vue would start up, and the rest of the content would continue loading via APIs.
Simply put, the parts needed for SEO were left to server-side rendering, while interaction and main business data were handed to the frontend. It wasn't the most standard frontend-backend separation, nor could it be considered true Vue SSR, but it was a solution found between existing technology and maintenance costs at the time. The fact that the old site continued to be indexed by search engines later was largely due to this approach.
The Current 航栈
This upgrade no longer requires placing frontend packaged files into PHP's MVC controllers to "work around" things.
The new site's frontend has been upgraded to Nuxt 4, Vue 3, and TypeScript, using Vite for development and building. Nuxt itself supports server-side rendering, so public pages like articles, tools, and communities can fetch data on the server and generate HTML. Each page's title, description, canonical URL, Open Graph information, and JSON-LD structured data can also be output alongside the real content. Pages that don't need indexing, like login, creator center, and admin backend, are explicitly set to noindex.
Compared to the old method where ThinkPHP controllers manually queried data and injected three SEO fields into templates, now the page content and SEO information belong to the same rendering process, making the structure clearer and easier to maintain.
The backend has also been upgraded from ThinkPHP 5 to NestJS 11 and Fastify 5, all using TypeScript. The data layer still uses the familiar MySQL, but upgraded to MySQL 8, with data models and queries managed through Prisma; Redis continues to handle high-frequency data like caching and visit deduplication. APIs have been re-split into modules like accounts, authentication, content, interaction, media, and admin backend, with added parameter validation, Swagger documentation, and more complete permission control.
The entire project is now organized as a Monorepo using pnpm Workspace and Turborepo, with the frontend, backend, database models, shared types, and design variables all in the same project. In the production environment, Nginx still stands at the front: /api requests are forwarded to NestJS, regular pages to the Nuxt SSR service, and static resources and uploaded files are set with different caching strategies. Applications can run via PM2 or Docker, and the responsibilities of MySQL, Redis, Web, and API are more clearly divided than before.
From Vue 2, Webpack 4, ThinkPHP 5 to Nuxt 4, Vue 3, TypeScript, NestJS, Fastify, and Prisma, this looks like a long list of tech terms. But to me, they are not just version upgrades; they also record the changes in my understanding of frontend, backend, databases, engineering, and server deployment over these years.
I'm reluctant to let go of the old site not because the old technology was advanced, but because it preserved the version of myself that earnestly tinkered and kept trying and failing.
Those old articles, old photos, update logs, and daily records, I will still try my best to keep them. They may no longer appear in the most prominent positions, but occasionally flipping back to look at them will still feel very interesting.
Thank you to the old site for accompanying me these five-plus years, and thank you to every friend who has read articles, left comments, or just passed by here.
The website has been upgraded, and I am still on the road. I will continue to write about technology and record life in the future, properly keeping those moments that seem ordinary now right here.
Welcome to the new 航栈. Let creation continue, and let every day worth remembering have a place to dock.