μ΅μ μΉ μ ν리μΌμ΄μ μμ 볡μ‘ν μ ν¨μ± κ²μ¬ λ° μν κ΄λ¦¬λ₯Ό μ²λ¦¬νκΈ° μν κ³ κΈ νλ‘ νΈμλ νΌ μν€ν μ² κΈ°μ μ νμν©λλ€. κ²¬κ³ νκ³ μ¬μ©μ μΉνμ μΈ νΌμ ꡬμΆνκΈ° μν λͺ¨λ² μ¬λ‘μ μ λ΅μ λ°°μ°μΈμ.
νλ‘ νΈμλ νΌ μν€ν μ²: 볡μ‘ν μ ν¨μ± κ²μ¬ λ° μν κ΄λ¦¬ λ§μ€ν°νκΈ°
νΌμ μ¬μ©μ μ λ ₯ λ° λ°μ΄ν° μμ§μ μν κΈ°λ³Έ μΈν°νμ΄μ€ μν μ νλ μΉμ 보νΈμ μΈ λΆλΆμ λλ€. κ°λ¨ν νΌμ λΉκ΅μ ꡬννκΈ° μ½μ§λ§, κ³ κΈ μ ν¨μ± κ²μ¬ κ·μΉ, λμ νλ, 볡μ‘ν μν κ΄λ¦¬ μꡬμ¬νμ΄ λμ λλ©΄μ 볡μ‘μ±μ΄ ν¬κ² μ¦κ°ν©λλ€. μ΄ κΈμμλ νλ‘ νΈμλ νΌ μν€ν μ²μ 볡μ‘μ±μ κΉμ΄ νκ³ λ€μ΄ κ²¬κ³ νκ³ μ μ§λ³΄μ κ°λ₯νλ©° μ¬μ©μ μΉνμ μΈ νΌμ ꡬμΆνκΈ° μν μ€μ©μ μΈ μ λ΅κ³Ό λͺ¨λ² μ¬λ‘λ₯Ό μ 곡ν©λλ€.
볡μ‘ν νΌμ κ³Όμ μ΄ν΄νκΈ°
볡μ‘ν νΌμ μ’ μ’ λ€μκ³Ό κ°μ μλ§μ κ³Όμ λ₯Ό μ μν©λλ€:
- μ ν¨μ± κ²μ¬μ 볡μ‘μ±: μ¬λ¬ νλμ κ±ΈμΉ λ³΅μ‘ν μ ν¨μ± κ²μ¬ κ·μΉ, μΈλΆ APIμ λν λΉλκΈ° νμΈ λλ μ¬μ©μλ³ λ°μ΄ν°μ μμ‘΄νλ κ·μΉμ ꡬνν΄μΌ ν©λλ€.
- μν κ΄λ¦¬: νΉν λμ νλλ μ‘°κ±΄λΆ λ‘μ§μ λ€λ£° λ λ€μν μ»΄ν¬λνΈ κ°μ νΌ μνλ₯Ό μ μ§νκ³ λκΈ°νν΄μΌ ν©λλ€.
- μ¬μ©μ κ²½ν: μ ν¨μ± κ²μ¬ μ€λ₯μ λν΄ μ¬μ©μμκ² λͺ ννκ³ μ μ©ν νΌλλ°±μ μ 곡νκ³ , νΌ μμ± κ³Όμ μ μλ΄νλ©°, μννκ³ μ§κ΄μ μΈ κ²½νμ 보μ₯ν΄μΌ ν©λλ€.
- μ μ§λ³΄μμ±: μꡬμ¬νμ΄ λ°μ ν¨μ λ°λΌ μ΄ν΄νκ³ , μμ νκ³ , νμ₯νκΈ° μ¬μ΄ νΌ μν€ν μ²λ₯Ό μ€κ³ν΄μΌ ν©λλ€.
- μ±λ₯: μ¬μ©μ μλ΅μ±μ μν₯μ μ£Όμ§ μμΌλ©΄μ λκ·λͺ¨ λ°μ΄ν° μΈνΈμ 볡μ‘ν κ³μ°μ μ²λ¦¬ν μ μλλ‘ νΌ μ±λ₯μ μ΅μ νν΄μΌ ν©λλ€.
- μ κ·Όμ±: μ κ·Όμ± μ§μΉ¨(WCAG)μ μ€μνμ¬ μ₯μ κ° μλ μ¬μ©μλ₯Ό ν¬ν¨ν λͺ¨λ μ¬μ©μκ° νΌμ μ¬μ©ν μ μλλ‘ λ³΄μ₯ν΄μΌ ν©λλ€.
- κ΅μ ν(i18n) λ° νμ§ν(l10n): νΌμ λ€μν μΈμ΄, λ¬Ένμ κ΄μ΅, μ§μ λ°μ΄ν° νμμ λ§κ² μ‘°μ ν΄μΌ ν©λλ€.
ν¨κ³Όμ μΈ νΌ μν€ν μ²μ ν΅μ¬ μμΉ
μ΄λ¬ν κ³Όμ λ₯Ό ν¨κ³Όμ μΌλ‘ ν΄κ²°νλ €λ©΄ λ€μ μμΉμ κΈ°λ°ν μ μ μλ νΌ μν€ν μ²λ₯Ό μ±ννλ κ²μ΄ μ€μν©λλ€:
- κ΄μ¬μ¬ λΆλ¦¬: νΌμ νλ μ ν μ΄μ λ‘μ§, μ ν¨μ± κ²μ¬ κ·μΉ, μν κ΄λ¦¬λ₯Ό μλ‘ λΆλ¦¬ν©λλ€. μ΄λ μ μ§λ³΄μμ±κ³Ό ν μ€νΈ μ©μ΄μ±μ ν₯μμν΅λλ€.
- μ μΈμ μ κ·Ό λ°©μ: κ΅¬μ± κ°μ²΄λ λλ©μΈ νΉν μΈμ΄(DSL)λ₯Ό μ¬μ©νμ¬ νΌμ μ€ν€λ§, μ ν¨μ± κ²μ¬ κ·μΉ, μ’ μμ±μ μ€λͺ νλ λ± μ μΈμ μΈ λ°©μμΌλ‘ νΌμ ꡬ쑰μ λμμ μ μν©λλ€.
- μ»΄ν¬λνΈ κΈ°λ° μ€κ³: νΌμ μ¬μ¬μ© κ°λ₯ν μ»΄ν¬λνΈλ‘ λΆν΄νμ¬ κ° μ»΄ν¬λνΈκ° μ λ ₯ νλ, μ ν¨μ± κ²μ¬ λ©μμ§ λλ μ‘°κ±΄λΆ μΉμ κ³Ό κ°μ νΌ κΈ°λ₯μ νΉμ μΈ‘λ©΄μ μ± μμ§λλ‘ ν©λλ€.
- μ€μ μ§μ€μ μν κ΄λ¦¬: Redux, Vuex λλ React Contextμ κ°μ μ€μ μ§μ€μ μν κ΄λ¦¬ μ루μ μ μ¬μ©νμ¬ νΌμ μνλ₯Ό κ΄λ¦¬νκ³ μ»΄ν¬λνΈ κ°μ μΌκ΄μ±μ 보μ₯ν©λλ€.
- λΉλκΈ° μ ν¨μ± κ²μ¬: μ¬μ©μ μΈν°νμ΄μ€λ₯Ό μ°¨λ¨νμ§ μκ³ μΈλΆ API λλ λ°μ΄ν°λ² μ΄μ€λ₯Ό νμΈνκΈ° μν΄ λΉλκΈ° μ ν¨μ± κ²μ¬λ₯Ό ꡬνν©λλ€.
- μ μ§μ ν₯μ: κΈ°λ³Έ νΌ κ΅¬νμΌλ‘ μμνμ¬ νμμ λ°λΌ κΈ°λ₯κ³Ό 볡μ‘μ±μ μ μ§μ μΌλ‘ μΆκ°ν©λλ€.
볡μ‘ν μ ν¨μ± κ²μ¬λ₯Ό μν μ λ΅
1. μ ν¨μ± κ²μ¬ μ€ν€λ§
μ ν¨μ± κ²μ¬ μ€ν€λ§λ νΌμ κ° νλμ λν μ ν¨μ± κ²μ¬ κ·μΉμ μ μνλ μ μΈμ μΈ λ°©λ²μ μ 곡ν©λλ€. Yup, Joi, Zodμ κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ©΄ μ μ°½ν APIλ₯Ό μ¬μ©νμ¬ μ€ν€λ§λ₯Ό μ μνκ³ λ°μ΄ν° μ ν, νμ νλ, μ κ· ννμ λ° μ¬μ©μ μ§μ μ ν¨μ± κ²μ¬ ν¨μλ₯Ό μ§μ ν μ μμ΅λλ€.
μμ (Yup μ¬μ©):
import * as Yup from 'yup';
const schema = Yup.object().shape({
firstName: Yup.string().required('μ΄λ¦μ νμ νλͺ©μ
λλ€'),
lastName: Yup.string().required('μ±μ νμ νλͺ©μ
λλ€'),
email: Yup.string().email('μ ν¨νμ§ μμ μ΄λ©μΌ μ£Όμμ
λλ€').required('μ΄λ©μΌμ νμ νλͺ©μ
λλ€'),
age: Yup.number().integer().positive().required('λμ΄λ νμ νλͺ©μ
λλ€'),
country: Yup.string().required('κ΅κ°λ νμ νλͺ©μ
λλ€'),
});
// μμ μ¬μ©λ²
schema.validate({ firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com', age: 30, country: 'USA' })
.then(valid => console.log('μ ν¨ν¨:', valid))
.catch(err => console.error('μ ν¨νμ§ μμ:', err.errors));
μ΄ μ κ·Ό λ°©μμ μ¬μ©νλ©΄ μ ν¨μ± κ²μ¬ λ‘μ§μ μ€μμμ κ΄λ¦¬νκ³ μ¬μ¬μ©ν μ μμ΄ νΌμ μ ν¨μ± κ²μ¬ κ·μΉμ μ μ§νκ³ μ λ°μ΄νΈνκΈ°κ° λ μ¬μμ§λλ€.
2. μ¬μ©μ μ§μ μ ν¨μ± κ²μ¬ ν¨μ
λ 볡μ‘ν μ ν¨μ± κ²μ¬ μλ리μ€μ κ²½μ°, νΌμ μνλ μΈλΆ λ°μ΄ν°λ₯Ό κΈ°λ°μΌλ‘ νΉμ κ²μ¬λ₯Ό μννλ μ¬μ©μ μ§μ μ ν¨μ± κ²μ¬ ν¨μλ₯Ό μ μν μ μμ΅λλ€. μ΄λ¬ν ν¨μλ μ ν¨μ± κ²μ¬ μ€ν€λ§μ ν΅ν©νκ±°λ νΌ μ»΄ν¬λνΈ λ΄μμ μ§μ μ¬μ©ν μ μμ΅λλ€.
μμ (μ¬μ©μ μ§μ μ ν¨μ± κ²μ¬):
const validatePassword = (password) => {
if (password.length < 8) {
return 'λΉλ°λ²νΈλ 8μ μ΄μμ΄μ΄μΌ ν©λλ€';
}
if (!/[a-z]/.test(password)) {
return 'λΉλ°λ²νΈλ μ΅μ νλμ μλ¬Έμλ₯Ό ν¬ν¨ν΄μΌ ν©λλ€';
}
if (!/[A-Z]/.test(password)) {
return 'λΉλ°λ²νΈλ μ΅μ νλμ λλ¬Έμλ₯Ό ν¬ν¨ν΄μΌ ν©λλ€';
}
if (!/[0-9]/.test(password)) {
return 'λΉλ°λ²νΈλ μ΅μ νλμ μ«μλ₯Ό ν¬ν¨ν΄μΌ ν©λλ€';
}
return null; // μ€λ₯ μμ
};
// νΌ μ»΄ν¬λνΈμμ μ¬μ©
const passwordError = validatePassword(formValues.password);
3. λΉλκΈ° μ ν¨μ± κ²μ¬
λΉλκΈ° μ ν¨μ± κ²μ¬λ μ¬μ©μ μ΄λ¦ μ¬μ© κ°λ₯ μ¬λΆ νμΈμ΄λ μ°νΈλ²νΈ μ ν¨μ± κ²μ¬μ κ°μ΄ μΈλΆ APIλ λ°μ΄ν°λ² μ΄μ€λ₯Ό νμΈν΄μΌ ν λ νμμ μ λλ€. μ΄λ μλ²μ λΉλκΈ° μμ²μ 보λ΄κ³ μλ΅μ λ°λΌ νΌμ μνλ₯Ό μ λ°μ΄νΈνλ κ²μ ν¬ν¨ν©λλ€.
μμ (`fetch`λ₯Ό μ¬μ©ν λΉλκΈ° μ ν¨μ± κ²μ¬):
const validateUsernameAvailability = async (username) => {
try {
const response = await fetch(`/api/check-username?username=${username}`);
const data = await response.json();
if (data.available) {
return null; // μ¬μ©μ μ΄λ¦μ μ¬μ©ν μ μμ΅λλ€
} else {
return 'μ΄λ―Έ μ¬μ© μ€μΈ μ¬μ©μ μ΄λ¦μ
λλ€';
}
} catch (error) {
console.error('μ¬μ©μ μ΄λ¦ μ¬μ© κ°λ₯ μ¬λΆ νμΈ μ€ μ€λ₯ λ°μ:', error);
return 'μ¬μ©μ μ΄λ¦ μ¬μ© κ°λ₯ μ¬λΆ νμΈ μ€ μ€λ₯';
}
};
// νΌ μ»΄ν¬λνΈμμ μ¬μ© (μ: useEffect μ¬μ©)
useEffect(() => {
if (formValues.username) {
validateUsernameAvailability(formValues.username)
.then(error => setUsernameError(error));
}
}, [formValues.username]);
λΉλκΈ° μ ν¨μ± κ²μ¬ μ€μλ λ‘λ© νμκΈ°μ κ°μ μκ°μ νΌλλ°±μ μ¬μ©μμκ² μ 곡νμ¬ μ ν¨μ± κ²μ¬ νλ‘μΈμ€κ° μ§ν μ€μμ μ리λ κ²μ΄ μ€μν©λλ€.
4. μ‘°κ±΄λΆ μ ν¨μ± κ²μ¬
μ‘°κ±΄λΆ μ ν¨μ± κ²μ¬λ νΌμ λ€λ₯Έ νλ κ°μ λ°λΌ μ ν¨μ± κ²μ¬ κ·μΉμ μ μ©νλ κ²μ ν¬ν¨ν©λλ€. μλ₯Ό λ€μ΄, μ¬μ©μκ° νΉμ κ΅κ°λ₯Ό κ΅μ μΌλ‘ μ νν κ²½μ°μλ§ μ¬κΆ λ²νΈλ₯Ό μ λ ₯νλλ‘ μꡬν μ μμ΅λλ€.
μμ (μ‘°κ±΄λΆ μ ν¨μ± κ²μ¬):
const schema = Yup.object().shape({
nationality: Yup.string().required('κ΅μ μ νμ νλͺ©μ
λλ€'),
passportNumber: Yup.string().when('nationality', {
is: (nationality) => nationality === 'Non-EU', // μμ 쑰건
then: Yup.string().required('λΉ EU μλ―Όμ μ¬κΆ λ²νΈκ° νμμ
λλ€'),
otherwise: Yup.string(), // EU μλ―Όμκ²λ νμ μμ
}),
});
μν κ΄λ¦¬ μ λ΅
ν¨κ³Όμ μΈ μν κ΄λ¦¬λ λμ νΌ, 볡μ‘ν μ’ μμ± λ° λκ·λͺ¨ λ°μ΄ν° μΈνΈλ₯Ό μ²λ¦¬νλ λ° μ€μν©λλ€. κ°κ°μ μ₯λ¨μ μ΄ μλ μ¬λ¬ μν κ΄λ¦¬ μ κ·Ό λ°©μμ μ¬μ©ν μ μμ΅λλ€.
1. μ»΄ν¬λνΈ μν
νλ μκ° μ νλ κ°λ¨ν νΌμ κ²½μ°, `useState`(React) λλ λ€λ₯Έ νλ μμν¬μ μ μ¬ν λ©μ»€λμ¦μ μ¬μ©νμ¬ κ΄λ¦¬λλ μ»΄ν¬λνΈ μνλ‘ μΆ©λΆν μ μμ΅λλ€. κ·Έλ¬λ νΌμ΄ 볡μ‘ν΄μ§μλ‘ μ΄ μ κ·Ό λ°©μμ κ΄λ¦¬νκΈ° μ΄λ €μμ§λλ€.
2. νΌ λΌμ΄λΈλ¬λ¦¬ (Formik, React Hook Form)
Formik λ° React Hook Formκ³Ό κ°μ νΌ λΌμ΄λΈλ¬λ¦¬λ νΌ μν, μ ν¨μ± κ²μ¬ λ° μ μΆ κ΄λ¦¬λ₯Ό μν ν¬κ΄μ μΈ μ루μ μ μ 곡ν©λλ€. μ΄λ¬ν λΌμ΄λΈλ¬λ¦¬λ λ€μκ³Ό κ°μ κΈ°λ₯μ μ 곡ν©λλ€:
- μλ μν κ΄λ¦¬
- μ ν¨μ± κ²μ¬ ν΅ν© (Yup, Joi λλ μ¬μ©μ μ§μ μ ν¨μ± κ²μ¬κΈ° μ¬μ©)
- μ μΆ μ²λ¦¬
- νλ μμ€ μ€λ₯ μΆμ
- μ±λ₯ μ΅μ ν
μμ (Formikμ Yup μ¬μ©):
import { useFormik } from 'formik';
import * as Yup from 'yup';
const validationSchema = Yup.object({
firstName: Yup.string().required('μ΄λ¦μ νμ νλͺ©μ
λλ€'),
lastName: Yup.string().required('μ±μ νμ νλͺ©μ
λλ€'),
email: Yup.string().email('μ ν¨νμ§ μμ μ΄λ©μΌμ
λλ€').required('μ΄λ©μΌμ νμ νλͺ©μ
λλ€'),
});
const MyForm = () => {
const formik = useFormik({
initialValues: {
firstName: '',
lastName: '',
email: '',
},
validationSchema: validationSchema,
onSubmit: (values) => {
alert(JSON.stringify(values, null, 2));
},
});
return (
);
};
3. μ€μ μ§μ€μ μν κ΄λ¦¬ (Redux, Vuex)
μ¬λ¬ νΌμ΄λ 곡μ νΌ μνκ° μλ 볡μ‘ν μ ν리μΌμ΄μ μ κ²½μ° Reduxλ Vuexμ κ°μ μ€μ μ§μ€μ μν κ΄λ¦¬ μ루μ μ΄ λ κ²¬κ³ νκ³ νμ₯ κ°λ₯ν μ κ·Ό λ°©μμ μ 곡ν μ μμ΅λλ€. μ΄λ¬ν λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ©΄ λ¨μΌ μ€ν μ΄μμ νΌμ μνλ₯Ό κ΄λ¦¬νκ³ λͺ¨λ μ»΄ν¬λνΈμμ μνλ₯Ό μ λ°μ΄νΈνκΈ° μν μ‘μ μ λμ€ν¨μΉν μ μμ΅λλ€.
μ€μ μ§μ€μ μν κ΄λ¦¬μ μ΄μ :
- νΌ μνλ₯Ό μν μ€μ μ§μ€μ λ°μ΄ν° μ μ₯μ
- μ‘μ κ³Ό 리λμλ₯Ό ν΅ν μμΈ‘ κ°λ₯ν μν μ λ°μ΄νΈ
- μ»΄ν¬λνΈ κ° μ¬μ΄ νΌ μν 곡μ
- μκ° μ¬ν λλ²κΉ κΈ°λ₯
4. React Context API
React Context APIλ νλ‘ λ릴λ§(prop drilling) μμ΄ μ»΄ν¬λνΈ κ°μ μνλ₯Ό 곡μ ν μ μλ λ΄μ₯ λ©μ»€λμ¦μ μ 곡ν©λλ€. νΌ μ»¨ν μ€νΈλ₯Ό λ§λ€μ΄ νΌμ μνλ₯Ό κ΄λ¦¬νκ³ λͺ¨λ νΌ μ»΄ν¬λνΈμ μ 곡ν μ μμ΅λλ€.
κ΅μ ν(i18n) λ° νμ§ν(l10n) κ³ λ €μ¬ν
κΈλ‘λ² μ¬μ©μλ₯Ό λμμΌλ‘ νΌμ κ°λ°ν λλ κ΅μ ν(i18n) λ° νμ§ν(l10n) μΈ‘λ©΄μ κ³ λ €νλ κ²μ΄ μ€μν©λλ€.
- μΈμ΄ μ§μ: μ¬λ¬ μΈμ΄λ₯Ό μ§μνμ¬ μ¬μ©μκ° νΌμ λ μ΄λΈ, λ©μμ§, μ§μΉ¨μ λν΄ μ νΈνλ μΈμ΄λ₯Ό μ νν μ μλλ‘ ν©λλ€.
- λ μ§ λ° μ«μ νμ: μ¬μ©μμ λ‘μΌμΌμ λ§κ² λ μ§ λ° μ«μ νμμ μ‘°μ ν©λλ€. μλ₯Ό λ€μ΄, λ μ§λ λ―Έκ΅μμλ MM/DD/YYYY, μ λ½μμλ DD/MM/YYYYλ‘ νμλ μ μμ΅λλ€.
- ν΅ν κΈ°νΈ: μ¬μ©μμ λ‘μΌμΌμ λ°λΌ ν΅ν κΈ°νΈλ₯Ό νμν©λλ€.
- μ£Όμ νμ: κ΅κ°λ³λ‘ λ€λ₯Έ μ£Όμ νμμ μ²λ¦¬ν©λλ€. μλ₯Ό λ€μ΄, μΌλΆ κ΅κ°μμλ λμ μ΄λ¦ μμ μ°νΈλ²νΈλ₯Ό μ¬μ©νκ³ λ€λ₯Έ κ΅κ°μμλ λ€μ μ¬μ©ν©λλ€.
- μ€λ₯Έμͺ½μμ μΌμͺ½μΌλ‘(RTL) μ°κΈ° μ§μ: μλμ΄ λ° νλΈλ¦¬μ΄μ κ°μ RTL μΈμ΄μ λν΄ νΌ λ μ΄μμκ³Ό ν μ€νΈ λ°©ν₯μ΄ μ¬λ°λ₯΄κ² νμλλμ§ νμΈν©λλ€.
i18next λ° react-intlκ³Ό κ°μ λΌμ΄λΈλ¬λ¦¬λ νλ‘ νΈμλ μ ν리μΌμ΄μ μμ i18n λ° l10nμ ꡬννλ λ° λμμ΄ λ μ μμ΅λλ€.
μ κ·Όμ± κ³ λ €μ¬ν
μ₯μ κ° μλ μ¬μ©μλ₯Ό ν¬ν¨ν λͺ¨λ μ¬μ©μκ° νΌμ μ κ·Όν μ μλλ‘ λ³΄μ₯νλ κ²μ νλ‘ νΈμλ νΌ μν€ν μ²μ μ€μν μΈ‘λ©΄μ λλ€. μ κ·Όμ± μ§μΉ¨(WCAG)μ μ€μνλ©΄ μκ° μ₯μ , μ΄λ μ₯μ , μΈμ§ μ₯μ λ° κΈ°ν μ₯μ κ° μλ μ¬μ©μλ₯Ό μν΄ νΌμ μ¬μ©μ±μ ν¬κ² ν₯μμν¬ μ μμ΅λλ€.
- μλ§¨ν± HTML: `
- ARIA μμ±: ARIA μμ±μ μ¬μ©νμ¬ μ€ν¬λ¦° 리λμ κ°μ 보쑰 κΈ°μ μ μΆκ° μ 보λ₯Ό μ 곡ν©λλ€.
- ν€λ³΄λ νμ: λͺ¨λ νΌ μμμ ν€λ³΄λ νμμΌλ‘ μ κ·Όν μ μλλ‘ λ³΄μ₯ν©λλ€.
- λͺ νν μ€λ₯ λ©μμ§: μ΄ν΄νκ³ ν΄κ²°νκΈ° μ¬μ΄ λͺ ννκ³ μ μ©ν μ€λ₯ λ©μμ§λ₯Ό μ 곡ν©λλ€.
- μΆ©λΆν λλΉ: ν μ€νΈμ λ°°κ²½ μ¬μ΄μ μΆ©λΆν μμ λλΉκ° μλμ§ νμΈν©λλ€.
- νΌ λ μ΄λΈ: λͺ¨λ νΌ μμμ λν΄ λͺ ννκ³ μ€λͺ μ μΈ λ μ΄λΈμ μ¬μ©νκ³ , `for` μμ±μ μ¬μ©νμ¬ ν΄λΉ μ λ ₯ νλμ μ¬λ°λ₯΄κ² μ°κ²°ν©λλ€.
- ν¬μ»€μ€ κ΄λ¦¬: νΌμ΄ λ‘λλ λ, μ ν¨μ± κ²μ¬ μ€λ₯κ° λ°μν λ, νΌμ΄ μ μΆλ λ ν¬μ»€μ€λ₯Ό μ μ νκ² κ΄λ¦¬ν©λλ€.
λͺ¨λ² μ¬λ‘ λ° ν
- λ¨μνκ² μμνκΈ°: κΈ°λ³Έ νΌ κ΅¬νμΌλ‘ μμνμ¬ νμμ λ°λΌ κΈ°λ₯κ³Ό 볡μ‘μ±μ μ μ§μ μΌλ‘ μΆκ°ν©λλ€.
- μ² μ νκ² ν μ€νΈνκΈ°: λ€μν λΈλΌμ°μ , κΈ°κΈ° λ° νλ©΄ ν¬κΈ°μμ νΌμ μ² μ νκ² ν μ€νΈν©λλ€.
- μ€νμΌ κ°μ΄λ μ¬μ©νκΈ°: νΌ μμ λ° λ μ΄μμμ λν΄ μΌκ΄λ μ€νμΌ κ°μ΄λλ₯Ό λ°λ¦ λλ€.
- μ½λ λ¬ΈμννκΈ°: κ° μ»΄ν¬λνΈ, μ ν¨μ± κ²μ¬ κ·μΉ λ° μν κ΄λ¦¬ λ©μ»€λμ¦μ λͺ©μ μ μ€λͺ νλ©΄μ μ½λλ₯Ό λͺ ννκ³ κ°κ²°νκ² λ¬Έμνν©λλ€.
- λ²μ κ΄λ¦¬ μ¬μ©νκΈ°: λ²μ κ΄λ¦¬(μ: Git)λ₯Ό μ¬μ©νμ¬ μ½λ λ³κ²½ μ¬νμ μΆμ νκ³ λ€λ₯Έ κ°λ°μμ νμ ν©λλ€.
- μλνλ ν μ€νΈ: νΌμ κΈ°λ₯μ 보μ₯νκ³ νκ·λ₯Ό λ°©μ§νκΈ° μν΄ μλνλ ν μ€νΈλ₯Ό ꡬνν©λλ€. μ¬κΈ°μλ κ°λ³ μ»΄ν¬λνΈμ λν λ¨μ ν μ€νΈμ μ»΄ν¬λνΈ κ°μ μνΈ μμ©μ νμΈνλ ν΅ν© ν μ€νΈκ° ν¬ν¨λ©λλ€.
- μ±λ₯ λͺ¨λν°λ§: νΌμ μ±λ₯μ λͺ¨λν°λ§νκ³ μ΅μ νν λΆλΆμ μλ³ν©λλ€. Lighthouseμ κ°μ λꡬλ μ±λ₯ λ³λͺ© νμμ μλ³νλ λ° λμμ΄ λ μ μμ΅λλ€.
- μ¬μ©μ νΌλλ°±: κ°μ ν λΆλΆμ μλ³νκ³ νΌμ μ¬μ©μ±μ ν₯μμν€κΈ° μν΄ μ¬μ©μ νΌλλ°±μ μμ§ν©λλ€. μ νμ¨μ μ΅μ ννκΈ° μν΄ λ€μν νΌ λμμΈμ λν A/B ν μ€νΈλ₯Ό κ³ λ €ν©λλ€.
- 보μ: ν¬λ‘μ€ μ¬μ΄νΈ μ€ν¬λ¦½ν (XSS) 곡격 λ° κΈ°ν 보μ μ·¨μ½μ μ λ°©μ§νκΈ° μν΄ μ¬μ©μ μ λ ₯μ μ΄κ· μ²λ¦¬ν©λλ€. μ μ‘ μ€μΈ λ°μ΄ν°λ₯Ό μνΈννκΈ° μν΄ HTTPSλ₯Ό μ¬μ©ν©λλ€.
- λͺ¨λ°μΌ λ°μν: νΌμ΄ λ°μνμ΄κ³ λ€μν νλ©΄ ν¬κΈ°μ μ μνλμ§ νμΈν©λλ€. λ―Έλμ΄ μΏΌλ¦¬λ₯Ό μ¬μ©νμ¬ λͺ¨λ°μΌ κΈ°κΈ°μ λ§κ² λ μ΄μμκ³Ό κΈκΌ΄ ν¬κΈ°λ₯Ό μ‘°μ ν©λλ€.
κ²°λ‘
κ²¬κ³ νκ³ μ¬μ©μ μΉνμ μΈ νΌμ ꡬμΆνλ €λ©΄ μ μ€ν κ³ν, μ μ μλ μν€ν μ², κ·Έλ¦¬κ³ κ΄λ ¨λ κ³Όμ μ λν κΉμ μ΄ν΄κ° νμν©λλ€. μ΄ κΈμμ μ€λͺ ν μ λ΅κ³Ό λͺ¨λ² μ¬λ‘λ₯Ό μ±νν¨μΌλ‘μ¨ μ μ§λ³΄μ, νμ₯ λ° λ³ννλ μꡬμ¬νμ μ μνκΈ° μ¬μ΄ 볡μ‘ν νΌμ λ§λ€ μ μμ΅λλ€. νΌμ΄ κΈλ‘λ² μ¬μ©μμκ² μ μ©νκ³ μ κ·Ό κ°λ₯νλλ‘ μ¬μ©μ κ²½ν, μ κ·Όμ± λ° κ΅μ νλ₯Ό μ°μ μνλ κ²μ μμ§ λ§μμμ€.
νλ‘ νΈμλ νλ μμν¬μ λΌμ΄λΈλ¬λ¦¬μ λ°μ μ νΌ κ°λ°μ μν μλ‘μ΄ λꡬμ κΈ°μ μ κ³μν΄μ μ 곡νκ³ μμ΅λλ€. μ΅μ νΈλ λμ λͺ¨λ² μ¬λ‘λ₯Ό μ΅μ μνλ‘ μ μ§νλ κ²μ νλμ μ΄κ³ ν¨μ¨μ μ΄λ©° μ¬μ©μ μΉνμ μΈ νΌμ ꡬμΆνλ λ° νμμ μ λλ€.