ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

前端半年实践:从Next.js重构到AI编码,探索Vibe Coding工作流

前端半年实践:从Next.js重构到AI编码,探索Vibe Coding工作流 1. 项目概述一个普通前端的半年“氛围感”实践去年下半年我给自己定了个小目标不再只是被动地完成业务需求而是主动去探索一些能让自己保持兴奋感、同时又能沉淀为真实技能的东西。我管这叫“氛围感编码”或者更时髦点叫Vibe Coding。这个词最近在前端圈子里挺火的它指的是一种状态——不是为了赶Deadline而焦虑地敲代码而是沉浸在创造、学习和解决问题的愉悦节奏里。对我而言这就是用半年时间围绕四个具体的、有“氛围感”的小项目系统地走一遍从前端到“泛全栈”的实践路径。这四个项目分别覆盖了现代前端框架深度应用、TypeScript类型体操、全栈开发实战以及AI辅助编码工具链探索。它们不一定是多么宏大的系统但每一个都试图解决一个真实的小痛点或探索一个有趣的技术方向。接下来我就把这半年的实践、踩过的坑和收获的“ vibe ”分享给你。2. 核心项目一Next.js 应用现代化重构与部署实战2.1 项目背景与核心诉求我接手了一个历史包袱较重的营销活动页面项目最初是基于纯React Webpack构建的。随着活动迭代页面性能逐渐下降首屏加载时间过长且开发体验不佳。我的目标是用Next.js 15当时最新稳定版对其进行现代化重构核心诉求非常明确提升性能、改善开发者体验、并建立一套可靠的自动化部署流程。Next.js 的 App Router、服务端组件RSC和内置的优化功能如图像、字体、脚本优化是吸引我的关键。2.2 架构升级与核心配置解析重构的第一步是搭建新的Next.js项目骨架。这里有几个关键决策点使用 App Router 而非 Pages Router这是面向未来的选择。App Router 基于 React Server Components允许更灵活的数据获取和渲染策略。对于大量静态或轻度动态的营销页面可以在服务端完成渲染直接将HTML发送给客户端极大减少客户端JavaScript包体积。TypeScript 严格模式在tsconfig.json中启用“strict”: true。这虽然在初期会带来不少类型错误但能从根本上避免许多运行时错误是提升代码质量的基石。Tailwind CSS 作为样式方案为了与旧项目的样式平稳迁移并提升开发效率选择了Tailwind。Next.js 与 Tailwind 集成非常顺畅配合clsx或tailwind-merge工具库可以优雅地处理条件样式。一个关键的配置在于next.config.js。对于从旧项目迁移的静态资源我配置了自定义的图片优化域名并开启了experimental.optimizeCss以进一步优化CSS输出。// next.config.js 部分配置 const nextConfig { images: { remotePatterns: [ { protocol: https, hostname: assets.old-project.com, // 旧项目资源域名 pathname: /**, }, ], // 根据业务需求设置合适的设备尺寸 deviceSizes: [640, 750, 828, 1080, 1200, 1920], }, // 开启实验性CSS优化在Next.js 15中已相对稳定 experimental: { optimizeCss: true, }, };2.3 性能优化实践与效果性能提升是本次重构的重中之重主要从以下几个维度入手图片优化将所有img标签替换为next/image。这是收益最明显的改动之一。Next.js Image组件会自动将图片转换为现代格式如WebP、按需懒加载并生成响应式尺寸。一个页面的图片总加载体积从原来的数MB下降到了几百KB。字体优化使用next/font加载本地字体文件它会在构建时自动将字体文件预处理并注入到静态资源中消除布局偏移CLS。代码分割与懒加载利用React的lazy和Suspense以及Next.js动态导入import()将非首屏必需的组件如复杂的图表库、弹窗内容进行懒加载。服务端渲染策略选择对于数据实时性要求不高的页面如活动介绍页使用generateStaticParams进行静态生成SSG部署后就是纯粹的静态文件访问速度极快。对于需要用户交互、带搜索参数的列表页则采用服务端组件在请求时渲染。实操心得在迁移过程中最大的挑战是旧组件与新的服务端组件模式的兼容。一些在客户端组件中常用的钩子如useState,useEffect和浏览器API如window,document在服务端组件中无法使用。解决方案是使用“use client”指令将这类组件明确标记为客户端组件并仔细规划组件树让服务端组件尽可能位于顶层负责数据获取和骨架渲染客户端组件负责交互。2.4 自动化部署与监控项目采用 Vercel 进行部署因其与 Next.js 的无缝集成。我将仓库与 Vercel 关联实现了 Git 主分支推送即自动部署。更重要的是配置了性能监控Core Web Vitals 监控Vercel Analytics 提供了免费的 Core Web VitalsLCP, FID, CLS数据看板让我能直观看到重构后性能的提升。自定义性能打点在关键业务链路如页面跳转、按钮点击到数据展示使用performance.mark()和performance.measure()API 进行打点并将数据上报到自建的监控平台如使用 Sentry 或 Umami用于分析真实用户环境下的性能表现。部署后首屏加载时间LCP平均减少了52%交互延迟FID也有显著改善。整个重构过程就像给一台老车换上了新的引擎和底盘代码跑的更顺畅我开发的“ vibe ”也回来了。3. 核心项目二深入TypeScript类型系统构建工具库3.1 为什么需要自己的工具类型库在日常开发中我们经常需要处理一些重复的类型操作比如从API响应中提取某个字段的类型、深度可选Partial一个嵌套对象、或者构造复杂的表单验证类型。虽然有一些优秀的开源工具类型库如type-fest但自己动手实现一遍是理解 TypeScript 类型系统最有效的方式。这个项目的目标就是构建一个贴合自身业务习惯的TypeScript 工具类型集合。3.2 从Utility Types源码学起我并没有从零开始瞎写而是选择了“站在巨人的肩膀上”——阅读并模仿lib.es5.d.ts和主流工具库中的内置类型实现。例如实现一个DeepPartialT// 深度 Partial让嵌套对象的所有属性都可选 type DeepPartialT T extends object ? { [P in keyof T]?: DeepPartialT[P]; } : T; // 使用示例 interface User { id: number; profile: { name: string; address: { city: string; }; }; } type PartialUser DeepPartialUser; // 等价于 // { // id?: number; // profile?: { // name?: string; // address?: { // city?: string; // }; // }; // }关键点在于条件类型T extends object和递归调用DeepPartialT[P]。这让我深刻理解了分布式条件类型和递归类型别名的用法。3.3 解决实际业务场景的类型挑战接下来我尝试用类型解决一些业务中的具体问题。场景一基于API定义自动生成Hook的入参和返回类型。假设后端使用Swagger或类似工具生成了API类型定义我们有一个Paths类型描述了所有接口的路径、方法和响应。我可以写一个类型来提取特定接口的类型// 假设的API路径定义类型简化版 type ApiPaths { /user/{id}: { get: { response: { id: number; name: string }; params: { id: number }; }; }; /posts: { post: { body: { title: string; content: string }; response: { id: number }; }; }; }; // 提取特定接口请求参数和响应类型的工具类型 type GetApiParamsPath extends keyof ApiPaths, Method extends keyof ApiPaths[Path] ApiPaths[Path][Method] extends { params: infer P } ? P : never; type GetApiBodyPath extends keyof ApiPaths, Method extends keyof ApiPaths[Path] ApiPaths[Path][Method] extends { body: infer B } ? B : never; type GetApiResponsePath extends keyof ApiPaths, Method extends keyof ApiPaths[Path] ApiPaths[Path][Method] extends { response: infer R } ? R : never; // 使用 type GetUserParams GetApiParams/user/{id}, get; // { id: number } type CreatePostBody GetApiBody/posts, post; // { title: string; content: string }这样在编写请求Hook时就能获得完美的类型提示和校验。场景二构造表单验证类型。结合Zod或Yup这样的运行时验证库我们可以实现类型安全的表单。例如定义一个表单Schema其类型能同时用于前端TS校验和后端DTO。import { z } from zod; const loginSchema z.object({ email: z.string().email(), password: z.string().min(6), rememberMe: z.boolean().optional(), }); // 直接导出类型供TS使用 export type LoginFormData z.infertypeof loginSchema; // 在组件中使用 const LoginForm: React.FC () { const { register, handleSubmit } useFormLoginFormData({ // ... 配置 resolver: zodResolver(loginSchema) }); // register 的字段名将获得完整的类型提示 };3.4 类型体操的“心流”体验与避坑指南沉浸在这种纯粹的逻辑构建中很容易进入“心流”状态。但也会遇到一些棘手问题类型实例化过深或无限递归这在编写复杂的递归类型时很常见。解决方案是增加递归深度限制检查或者重构类型逻辑避免无限循环。TypeScript 4.5 对尾递归优化有更好支持。性能问题过于复杂的类型操作在大型项目中进行类型检查时可能会拖慢IDE或编译速度。应对策略是将最复杂的工具类型单独放在一个文件中并仅在需要时导入避免全局类型文件过于庞大。可读性与文档复杂的类型如同魔法别人甚至一个月后的自己很难看懂。我的习惯是为每个复杂的工具类型添加详细的JSDoc注释说明其用途、泛型参数和示例。这个项目没有直接产出可见的UI但它极大地提升了我代码的健壮性和开发效率。当看到自己编写的类型在VSCode中完美地提示出所有可能的状态和属性时那种成就感是独特的“技术 vibe”。4. 核心项目三基于Supabase的全栈小应用开发4.1 技术选型为什么是Supabase我想快速验证一个全栈想法——一个简单的“个人书影音记录”应用。核心需求是用户认证、数据CRUD、实时订阅如新评论通知。传统的方案需要自建或租赁服务器、配置数据库、编写API运维成本高。Supabase进入了我的视野它是一个开源的Firebase替代品基于 PostgreSQL提供了即时可用的数据库、身份认证、实时订阅、存储和边缘函数。对于个人项目或小团队快速原型它几乎是完美的选择。其与Next.js的集成尤其出色。4.2 项目初始化与数据库设计首先在Supabase官网创建项目获取API密钥和项目URL。然后在Next.js项目中安装supabase/supabase-js和supabase/ssr用于服务端和客户端兼容的认证。 数据库设计直接在Supabase的在线SQL编辑器中完成。我创建了两张表-- 电影记录表 create table movies ( id bigint primary key generated always as identity, user_id uuid references auth.users(id) on delete cascade not null, title text not null, rating smallint check (rating 1 and rating 5), watched_at date default now(), created_at timestamptz default now() ); -- 启用行级安全RLS alter table movies enable row level security; -- 创建策略用户只能操作自己的记录 create policy 用户可管理自己的电影记录 on movies for all using (auth.uid() user_id); -- 评论表支持实时 create table comments ( id bigint primary key generated always as identity, movie_id bigint references movies(id) on delete cascade not null, user_id uuid references auth.users(id) on delete cascade not null, content text not null, created_at timestamptz default now() ); alter table comments enable row level security; create policy 用户可查看和创建所有评论但只能修改自己的 on comments for all using ( auth.uid() user_id or -- 可修改自己的 true -- 可查看所有FOR SELECT ) with check (auth.uid() user_id); -- 创建/更新时必须是自己Supabase的Row Level Security (RLS)功能非常强大通过SQL策略就能在数据库层面实现精细的权限控制无需在后端逻辑中重复编写权限校验代码。4.3 前端集成与实时功能实现在Next.js中我创建了一个lib/supabase.ts文件来初始化客户端和服务端客户端。// lib/supabase.ts import { createBrowserClient } from supabase/ssr import { createServerClient } from supabase/ssr import { cookies } from next/headers export function createClient() { return createBrowserClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! ) } export async function createServerSideClient() { const cookieStore await cookies() return createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { getAll() { return cookieStore.getAll() }, setAll(cookiesToSet) { cookiesToSet.forEach(({ name, value, options }) cookieStore.set(name, value, options) ) }, }, } ) }实时评论功能的实现令人惊艳地简单。在电影详情页组件中import { createClient } from /lib/supabase; import { useEffect, useState } from react; export function CommentList({ movieId }: { movieId: number }) { const [comments, setComments] useState([]); const supabase createClient(); useEffect(() { // 1. 初始获取评论 const fetchComments async () { const { data } await supabase .from(comments) .select(*, profiles(username)) .eq(movie_id, movieId) .order(created_at, { ascending: false }); if (data) setComments(data); }; fetchComments(); // 2. 订阅该电影评论的实时变化 const channel supabase .channel(comments:movie${movieId}) .on( postgres_changes, { event: INSERT, // 监听插入事件 schema: public, table: comments, filter: movie_ideq.${movieId}, }, (payload) { // 当有新评论插入时更新本地状态 setComments((prev) [payload.new, ...prev]); } ) .subscribe(); // 清理订阅 return () { supabase.removeChannel(channel); }; }, [movieId, supabase]); return ( div {comments.map((comment) ( div key{comment.id}{comment.content}/div ))} /div ); }几行代码就实现了类似聊天室的实时更新体验这极大地增强了应用的互动感。4.4 身份认证与部署考量Supabase 提供了完整的邮箱/密码、OAuthGitHub, Google等认证流程。我直接使用了其React Auth UI组件库快速搭建了登录注册页面。对于部署由于Supabase处理了后端和数据库前端Next.js应用可以静态导出如果主要是SSG或部署在Vercel上几乎零运维。避坑指南RLS策略调试初期经常遇到“权限被拒绝”的错误。务必在Supabase Dashboard的“Authentication” - “Policies”界面仔细检查和测试每条策略。可以使用supabase.rpc(‘auth.uid’)在SQL编辑器中模拟用户上下文进行测试。实时订阅的性能不要过度订阅。确保在组件卸载时清理频道 (supabase.removeChannel)避免内存泄漏和多余的网络连接。本地开发使用Supabase CLI可以在本地运行完整的Supabase环境包括数据库迁移和种子数据这对开发调试至关重要。这个全栈小项目让我在极短的时间内体验了从数据库设计、API通过Supabase客户端、实时功能到前端展示的完整闭环极大地提振了我向全栈发展的信心。5. 核心项目四探索AI辅助编码Vibe Coding工作流5.1 Vibe Coding工具链的搭建“Vibe Coding” 不仅仅是心态也需要工具辅助以保持流畅的创作状态。我探索的核心是AI 结对编程。我的工具链核心是Cursor GitHub Copilot 自定义的代码片段/提示词库。Cursor作为主力编辑器其强大的AI对话和代码编辑能力如“在项目中搜索”、“编辑此函数”远超传统辅助。GitHub Copilot作为补充在编写重复模式代码或需要快速补全时非常高效。自定义提示词我建立了一个Markdown文件记录针对不同场景如“重构一个React组件”、“编写一个TypeScript工具类型”、“调试Next.js API路由错误”的有效提示词。5.2 实战用AI加速复杂组件开发以开发一个可拖拽、支持嵌套的树形列表组件为例。这是一个复杂的前端交互涉及状态管理、DOM操作和性能优化。需求拆解与提示我不会直接问“写一个树形组件”。而是先拆解数据结构向AI描述节点{id, label, children?}的结构。核心交互“使用dnd-kit库实现拖拽排序和嵌套。父节点可折叠/展开。”状态管理“使用Zustand管理树的状态包括展开/折叠状态、节点列表。”性能“使用React.memo优化节点渲染仅在必要时更新。” 我会将这些拆解后的需求分步骤、清晰地输入给Cursor。迭代与调试AI生成的初始代码往往不完美。当拖拽后状态更新不正确时我会将错误现象和关键代码片段发给AI“拖拽后onDragEnd事件里active和over节点的ID打印出来是对的但UI没有更新。这是我的handleDragEnd函数和Zustand store的代码请帮我分析可能的原因。” AI通常会指出我可能直接修改了状态违反了不可变性或者setState的用法有误。代码审查与优化AI还可以充当第一轮代码审查员。我会将一段自认为写的不错的代码发给它并提问“从代码风格、性能、TypeScript类型安全和潜在bug的角度审查这段代码并提出改进建议。” 它常常能发现一些我忽略的边缘情况或更优雅的写法。5.3 提示词工程与思维引导我意识到让AI写出高质量代码的关键在于“高质量的提问”。这本身就是一种编程思维的锻炼。我总结了几条原则提供上下文告诉AI我们正在做什么项目Next.js 15, TypeScript使用什么库Tailwind, Zustand。明确约束指定代码风格如函数式组件、使用特定的Hook、避免什么如避免any类型。分步骤引导复杂任务分解为多个简单指令像在指导一位初级程序员。要求解释在AI生成代码后追问“为什么这里要这样处理”或“这个参数的作用是什么”这能加深我对代码的理解。5.4 AI辅助的边界与价值反思AI不是银弹。它擅长基于模式生成代码、提供建议和快速检索信息但在架构设计、深度调试、理解复杂业务逻辑方面仍有局限。我的体会是不要盲目接受AI生成的代码一定要经过自己的理解和测试特别是涉及安全、性能和核心业务逻辑的部分。它是加速器不是替代品它把我从繁琐的样板代码和简单的bug查找中解放出来让我能更专注于更高层次的设计和问题解决。保持学习过度依赖AI会导致基础技能退化。我仍然坚持手动编写核心逻辑、阅读源码和文档确保自己理解背后的原理。这个探索项目让我的编码过程从“搜索-复制-修改”的被动模式转变为“构思-提问-迭代-理解”的主动创造模式真正找回了编程最初的乐趣和“ vibe ”。6. 半年总结技能提升与心态转变回顾这半年四个项目像四个不同的支点共同撬动了我的能力成长。Next.js重构让我对现代Web性能优化和全栈框架有了实战级理解TypeScript类型体操将我的静态类型思维提升到了新的高度写代码时更有“安全感”Supabase全栈实践让我亲身体验了云原生BaaS的便捷消除了对后端的神秘感AI辅助工作流则革新了我的开发习惯提升了效率。更重要的是心态的转变。我不再仅仅把自己看作一个“前端切图仔”或“业务逻辑实现者”而是开始以“产品建造者”和“问题解决者”的视角思考。我会主动问这个功能的技术选型是否最优用户体验能否更好代码是否足够健壮以应对未来变化这种主动探索和创造的状态就是我认为最棒的“Vibe Coding”。它无关乎你使用了多新的框架而在于你是否能从代码中找到持续的热情和成就感。如果你也感到有些倦怠不妨试着给自己设定一个这样的小项目周期沉浸进去你可能会收获意想不到的成长和快乐。
返回列表