← Назад к вопросам

Что использовал для валидации на прошлых местах работы?

1.3 Junior🔥 201 комментариев
#JavaScript Core#Тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Инструменты валидации в разных проектах

На протяжении 10+ лет я использовал различные подходы к валидации в зависимости от требований проекта, стека технологий и эволюции инструментов. Расскажу о наиболее значимых решениях.

Ранний период (2010-2015): базовая валидация

Собственные функции валидации

// Простой подход: писали валидацию сами
function validateEmail(email) {
  const regex = /^[^@]+@[^@]+\.[^@]+$/;
  return regex.test(email);
}

function validateRequired(value) {
  return value && value.trim() !== '';
}

function validateForm(formData) {
  const errors = {};
  if (!validateRequired(formData.name)) errors.name = "Name is required";
  if (!validateEmail(formData.email)) errors.email = "Invalid email";
  return Object.keys(errors).length === 0 ? null : errors;
}

Этот подход работал для небольших проектов, но быстро становился неудобным при масштабировании.

jQuery эра (2012-2018): jQuery Validation

jQuery Validation Plugin

// Популярный в то время подход
$("#myForm").validate({
  rules: {
    name: "required",
    email: {
      required: true,
      email: true
    },
    age: {
      required: true,
      number: true,
      min: 18
    }
  },
  messages: {
    name: "Name is required",
    email: "Please enter valid email",
    age: "Age must be at least 18"
  },
  submitHandler: function(form) {
    // Отправить форму
  }
});

Преимущества: просто, быстро, встроено. Недостатки: жёстко связано с jQuery, не типизировано.

Angular эра (2015-2019): Reactive Forms Validators

Angular встроенные валидаторы

import { FormBuilder, Validators } from '@angular/forms';

this.form = this.fb.group({
  name: ['', [Validators.required, Validators.minLength(3)]],
  email: ['', [Validators.required, Validators.email]],
  age: ['', [Validators.required, Validators.min(18)]],
  website: ['', [Validators.pattern(/^https?:\/\/.+/)]]
});

function passwordStrengthValidator(control) {
  const value = control.value;
  if (!value) return null;
  const hasNumber = /[0-9]/.test(value);
  const hasUpper = /[A-Z]/.test(value);
  const hasSymbol = /[!@#$%^&*]/.test(value);
  const passwordValid = hasNumber && hasUpper && hasSymbol;
  return passwordValid ? null : { weakPassword: true };
}

Это было лучше: типизировано, переиспользуемо, но специфично для Angular.

React эра (2017-2019): Formik

Formik - самая популярная библиотека

import { Formik, Form, Field, ErrorMessage } from 'formik';
import * as Yup from 'yup';

const validationSchema = Yup.object().shape({
  name: Yup.string()
    .required('Name is required')
    .min(3, 'Name must be at least 3 characters'),
  email: Yup.string()
    .email('Invalid email')
    .required('Email is required'),
  age: Yup.number()
    .required('Age is required')
    .min(18, 'Must be at least 18'),
  password: Yup.string()
    .required('Password is required')
    .min(8, 'Password must be at least 8 characters')
    .matches(/[A-Z]/, 'Must contain uppercase')
    .matches(/[0-9]/, 'Must contain number')
});

export function MyForm() {
  return (
    <Formik
      initialValues={{ name: '', email: '', age: '', password: '' }}
      validationSchema={validationSchema}
      onSubmit={(values) => {
        console.log(values);
      }}
    >
      {({ errors, touched }) => (
        <Form>
          <Field name="email" type="email" />
          <ErrorMessage name="email" />
        </Form>
      )}
    </Formik>
  );
}

Formik был идеален для React: управление состоянием, валидация и обработка ошибок в одном месте.

Современный период (2020-2026): React Hook Form + Zod

React Hook Form стал стандартом

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

const userSchema = z.object({
  name: z.string()
    .min(3, 'Name must be at least 3 characters')
    .max(50, 'Name must not exceed 50 characters'),
  email: z.string()
    .email('Invalid email address'),
  age: z.number()
    .int('Age must be integer')
    .min(18, 'Must be at least 18')
    .max(120, 'Invalid age'),
  password: z.string()
    .min(8, 'Password must be at least 8 characters')
    .regex(/[A-Z]/, 'Must contain uppercase')
    .regex(/[0-9]/, 'Must contain number')
});

type User = z.infer<typeof userSchema>;

export function UserForm() {
  const { register, handleSubmit, formState: { errors } } = useForm<User>({
    resolver: zodResolver(userSchema)
  });

  return (
    <form onSubmit={handleSubmit((data) => {
      console.log(data);
    })}>
      <input {...register('email')} />
      {errors.email && <span>{errors.email.message}</span>}
      <button type="submit">Submit</button>
    </form>
  );
}

Преимущества React Hook Form: минимальный overhead, отличная производительность, интеграция с Zod для типобезопасности, поддержка async валидации.

Валидация на бэкенде

Важный принцип: ВСЕГДА валидируй на обеих сторонах

const emailValid = /^[^@]+@[^@]+\.[^@]+$/.test(email);
if (!emailValid) showError("Invalid email");

// На бэкенде (Python + Pydantic):
from pydantic import BaseModel, EmailStr, validator

class UserCreate(BaseModel):
    email: EmailStr
    name: str
    age: int

Асинхронная валидация

Важно для проверки уникальности (email, username)

const userSchema = z.object({
  email: z.string()
    .email()
    .refine(
      async (email) => {
        const response = await fetch(`/api/check-email?email=${email}`);
        const { available } = await response.json();
        return available;
      },
      { message: "Email already in use" }
    )
});

Мои предпочтения сегодня

  1. Zod для валидации - типобезопасно, минимальные зависимости
  2. React Hook Form - минимальный overhead
  3. HTML5 constraints для базовой валидации
  4. Реальная валидация на бэкенде - никогда не доверяй фронтенду
  5. Асинхронная валидация только когда необходимо

Резюме

Валидация эволюционировала от простых проверок к типобезопасным, структурированным подходам. Сегодня стандарт - это React Hook Form + Zod, которые обеспечивают оптимальный баланс между DX и производительностью. Главный принцип: всегда валидируй на обеих сторонах (фронтенд для UX, бэкенд для безопасности).