Tecnología1 阅读

El MVP no es conformismo, sino una secuencia de desarrollo más inteligente

Como ingenieros, naturalmente nos gusta "hacerlo completo": diseñar una arquitectura elegante, abstraer componentes genéricos, configurar autenticación, CI/CD, un sistema de diseño completo... y al final, la fecha de lanzamiento se retrasa una y otra vez.

MVP (Minimum Viable Product, producto mínimo viable), esta mentalidad, en esencia te ayudaa verificar si vale la pena continuar invirtiendo en una idea con un costo menor.

Para los desarrolladores, no se trata de "escribir código malo", sino de "tomar las decisiones de ingeniería justas en el momento adecuado".

Primero, aclaremos: ¿Qué es MVP?

Una definición un poco más formal: MVP es una versión del producto con las funciones mínimas, pero suficiente para ser entregada a usuarios reales y utilizada para recopilar comentarios y validar hipótesis.

Aquí hay tres puntos clave:

Simplificado en una frase: Con el mínimo código posible, averiguar una cosa: si realmente hay alguien que quiera usar esto.

El pensamiento central del desarrollo MVP

Desde una perspectiva de ingeniería, podemos dividir el pensamiento MVP en varios pasos:

  1. Identificar 'un problema' a validar

    Por ejemplo: '¿Los usuarios estarían dispuestos a usar una herramienta de notas en línea minimalista en lugar de seguir enviándose mensajes a sí mismos por WeChat o correo electrónico?'

  2. Mantener solo las funciones necesarias para validar este problema

    Crear nota, mostrar lista, eliminar una: suficiente.

  3. Implementar de la manera más rápida que tengas

    No tiene que ser 'el stack más moderno', sino el que mejor conoces.

  4. Lanzar en el ámbito más pequeño, observar el uso real

    Primero pruébalo con colegas y amigos cercanos, luego considera el lanzamiento público.

  5. Iterar basado en datos de comportamiento, no en suposiciones o agregar requisitos

    Observa si la gente vuelve a usarlo, no solo escuches que dicen 'está bien, está bien'.

Una comparación simple: dos caminos comunes para los ingenieros

Ruta no MVP (la que solemos tomar):

Ruta MVP:

La arquitectura se puede recuperar después, pero si nadie quiere usarlo, habrás construido una 'ciudad vacía'.

Práctica: construir un MVP de notas con Next.js

A continuación, usaremos un 'cuaderno de notas en línea / memorándum' como ejemplo, y recorreremos una idea MVP con Next.js (App Router).

1. Primero definir el alcance del MVP

Los requisitos se reducen intencionalmente al mínimo:

Cosas que no se harán por ahora:

Con este alcance, cualquier desarrollador familiarizado con React puede crear una versión utilizable en 1-2 días.

2. Andamio del proyecto y estructura básica

Crear un proyecto App Router siguiendo la documentación oficial.

En la terminal:

bash
npx create-next-app@latest note-mvp
# 或者选择 TypeScript、App Router 等默认选项
cd note-mvp
npm run dev

En la estructura de directorios, el directorio app/ es el núcleo. [nextjs](https://nextjs.org/docs/app)

Podemos organizar la estructura mínima así:

3. Escribir una API mínima con App Router

En app/api/notes/route.ts, primero usa un arreglo en memoria para simular almacenamiento (en un entorno real puedes cambiarlo a SQLite/Supabase, etc.).

ts
// app/api/notes/route.ts
import { NextResponse } from 'next/server'

type Note = {
  id: string
  content: string
  createdAt: string
}

let notes: Note[] = []

export async function GET() {
  return NextResponse.json(notes)
}

export async function POST(request: Request) {
  const { content } = await request.json()
  if (!content || typeof content !== 'string') {
    return new NextResponse('Invalid content', { status: 400 })
  }

  const note: Note = {
    id: crypto.randomUUID(),
    content,
    createdAt: new Date().toISOString(),
  }

  notes.unshift(note)
  return NextResponse.json(note, { status: 201 })
}

export async function DELETE(request: Request) {
  const { searchParams } = new URL(request.url)
  const id = searchParams.get('id')
  if (!id) {
    return new NextResponse('Missing id', { status: 400 })
  }

  notes = notes.filter((n) => n.id !== id)
  return new NextResponse(null, { status: 204 })
}

Este código tiene muchos puntos que 'se pueden optimizar', por ejemplo:

Pero en la etapa MVP, ya cumple el objetivo de 'validar: si alguien quiere escribir algo y volver a verlo'.

4. Escribir una página simple

En app/page.tsx, usa un Client Component para manejar la interacción.

tsx
'use client'

import { useEffect, useState } from 'react'

type Note = {
  id: string
  content: string
  createdAt: string
}

export default function Home() {
  const [notes, setNotes] = useState<Note[]>([])
  const [input, setInput] = useState('')
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    fetch('/api/notes')
      .then((res) => res.json())
      .then((data) => setNotes(data))
  }, [])

  async function handleAdd(e: React.FormEvent) {
    e.preventDefault()
    if (!input.trim()) return

    setLoading(true)
    try {
      const res = await fetch('/api/notes', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ content: input.trim() }),
      })
      const note: Note = await res.json()
      setNotes((prev) => [note, ...prev])
      setInput('')
    } finally {
      setLoading(false)
    }
  }

  async function handleDelete(id: string) {
    await fetch(`/api/notes?id=${id}`, { method: 'DELETE' })
    setNotes((prev) => prev.filter((n) => n.id !== id))
  }

  return (
    <main style={{ maxWidth: 600, margin: '2rem auto', padding: '0 1rem' }}>
      <h1>Minimal Notes MVP</h1>

      <form onSubmit={handleAdd} style={{ marginBottom: '1rem' }}>
        <textarea
          value={input}
          onChange={(e) => setInput(e.target.value)}
          rows={3}
          style={{ width: '100%', marginBottom: '0.5rem' }}
          placeholder="写点什么..."
        />
        <button type="submit" disabled={loading}>
          {loading ? '保存中...' : '保存'}
        </button>
      </form>

      <section>
        {notes.length === 0 && <p>还没有任何笔记。</p>}
        {notes.map((note) => (
          <article
            key={note.id}
            style={{
              border: '1px solid #ddd',
              padding: '0.75rem',
              marginBottom: '0.75rem',
            }}
          >
            <p style={{ whiteSpace: 'pre-wrap' }}>{note.content}</p>
            <small style={{ color: '#666' }}>
              {new Date(note.createdAt).toLocaleString()}
            </small>
            <div>
              <button
                onClick={() => handleDelete(note.id)}
                style={{ marginTop: '0.25rem' }}
              >
                删除
              </button>
            </div>
          </article>
        ))}
      </section>
    </main>
  )
}

Esta página es muy 'sencilla': un textarea, un botón, una lista.

Pero ya ha completado un ciclo cerrado:

Desde la perspectiva MVP, esto ya es suficiente para dárselo a 5-10 usuarios de prueba y ver su comportamiento real.

¿Qué pensamientos MVP refleja este ejemplo de Next.js?

Alrededor de esta implementación, podemos verlo a la inversa:

No se introdujeron bibliotecas adicionales de gestión de estado, frameworks de UI, ni servicios backend complejos.

Aunque ahora se usa almacenamiento en memoria, las rutas de la API ya están fijadas; en el futuro, cambiar a una base de datos solo requiere modificar la implementación en route.

¿Alguien estaría dispuesto a escribir una nota breve en el navegador y volver a la misma entrada para verla/eliminarla?

Con el nivel de un ingeniero familiarizado con Next.js, esta implementación a nivel MVP se puede completar e implementar en Vercel en un día.

Desde este punto de partida, puedes decidir la ruta posterior según el comportamiento del usuario, por ejemplo:

Errores comunes: tomar la 'perfección de ingeniería' como objetivo

En proyectos reales, muchos ingenieros ven este tipo de MVP como un 'juguete temporal' y no se sienten cómodos:

Aquí hay dos consideraciones reales:

MVP no niega la calidad de la ingeniería, sino que pone la 'ingeniería de alta calidad' después de que la necesidad haya sido probada como válida.

Para finalizar: la mentalidad MVP para ingenieros

Se puede entender el pensamiento MVP como una gestión de riesgos de ingeniería:

Para desarrolladores experimentados, un enfoque práctico es:

Compartir

Compartir

Comparte este artículo.