JS 기반 프로젝트 진행시 주요 라이브러리(JS, CSS 라이브러리) 외 개발에 필요한 추가 라이브러리를 통해 작업 생산성, 효율성을 높일 수 있다.
npm i -D @craco/craco
npm i -D @craco/types *타입스크립트 사용시
craco.config.js
파일 생성, 덮어쓸 설정(alias, less loader 등) 추가// craco.config.js
module.exports = {
plugins: [
{
plugin: CracoAlias,
options: {
source: "tsconfig",
baseUrl: "./src",
tsConfigPath: "tsconfig.paths",
},
},
],
};
package.json
command 수정// package.json
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "craco eject"
}
git-hook
에 따라 원하는 동작을 하게 도와주는 패키지로, git add, commit, push가 시행되기 전이나 후에 원하는 스크립트를 실행시켜준다.npx husky-init && npm install
package.json
스크립트 추가// package.json
{
"scripts": {
"prepare": "husky install"
}
}
husky install
을 먼저 실행하고, husky add <File> [cmd]
를 쓴다.npx husky add .husky/pre-commit "npm test"
git add .husky/pre-commit
git commit -m "Keep calm and commit"
_
기호를 처음에 선언하여 사용된다. _.(변수)
로 작성할 경우 lodash wrapper로 변수를 감싸게 되면서 해당 변수에 대한 chaining을 시작한다.$ npm i -g npm
$ npm i --save lodash
// ES6
import _ from "lodash";
// commonJs
var _ = require("lodash");
var myFriend = [
{ name: "kys", job: "developer", age: 27 },
{ name: "cys", job: "webtoons man", age: 27 },
{ name: "yhs", job: "florist", age: 26 },
{ name: "chj", job: "nonghyup man", age: 27 },
{ name: "ghh", job: "coffee man", age: 27 },
{ name: "ldh", job: "kangaroo", age: 27 },
];
// 콜백함수가 처음으로 참이되는 객체를 반환
_.find(myFriend, function (friend) {
return friend.age < 28;
}); // → { name: 'kys',job:'developer' ,'age': 27}
var myFriend = [
{ name: "kys", job: "developer", age: 27 },
{ name: "cys", job: "webtoons man", age: 27 },
{ name: "yhs", job: "florist", age: 26 },
{ name: "chj", job: "nonghyup man", age: 27 },
];
myFriend.findIndex(function (friend) {
return friend.age === 26; // 2
});
_.findIndex(myFriend, function (friend) {
return friend.age === 26; // 2
});
// 처음 일치하는 object의 index 값을 반환
_.findIndex(myFriend, { name: "cys", job: "webtoons man", age: 27 });
// -> 1
// 나이가 26인 객체가 처음으로 나오는 index 반환
_.findIndex(myFriend, { age: 26 });
// → 2
Yup
은 폼 형식의 데이터에 대한 유효성 검사 및 그 상황에 맞는 에러 메시지를 효율적으로 관리할 수 있는 라이브러리다. 유효성 검사 항목이 많아지는 경우 코드가 길어지고 불필요한 렌더링이 일어나는데, 코드를 줄이고 유지보수 측면에서 효율적이다.react-hook-form
은 기존 React의 npm i yup
npm install react-hook-form
import * as yup from "yup";
export const crewRequiredValidation = yup.object({
// 사번
crewId: yup
.string()
.required("사번을 입력해주세요.")
.max(10, "사번은 10자리 이하여야 합니다."),
// 한글 이름
crewName: yup
.string()
.required("이름을 입력해주세요.")
.max(15, "이름은 15자리 이하여야 합니다."),
// 영문 이름
crewNameEn: yup
.string()
.required("영문 이름을 입력해주세요.")
.max(30, "영문 이름은 30자리 이하여야 합니다."),
//코코네 아이디
coconeId: yup
.string()
.matches(/^[A-Za-z_]+$/, "영어와 특수문자만 입력 가능합니다.")
.required("코코네 아이디를 입력해주세요.")
.max(30, "코코네 아이디는 영문 30자리 이하여야 합니다."),
// 조직원 상태
activeStatus: yup.string().required("조직원 상태를 선택해 주세요."),
// 근무형태
workType: yup.string().required("근무형태를 선택해 주세요."),
// 브랜치
branchId: yup.string().required("Branch를 선택해 주세요."),
// 부서
deptId: yup.string().required("부서를 선택해 주세요."),
//직책
dutyId: yup.string().required("직책을 선택해 주세요."),
// 직군
jobKind: yup.string().required("직군을 선택해 주세요."),
// 세부 직군
jobPart: yup.string().required("세부직군을 선택해 주세요."),
// 생년월일
birthday: yup
.date()
.typeError("생년월일을 입력해 주세요.")
.required("생년월일을 입력해 주세요."),
// 입사일
hireDate: yup
.date()
.typeError("입사일을 입력해 주세요.")
.required("입사일을 입력해 주세요."),
email: yup
.string()
.email("이메일 형식에 맞춰 작성해 주세요.")
.required("이메일을 입력해 주세요."),
});
export const crewOptionalValidation = yup.object({
// 핸드폰 번호
phoneNo: yup
.string()
.nullable()
.matches(
/^01([0|1|6|7|8|9]?)-?([0-9]{3,4})-?([0-9]{4})$/,
"형식에 맞춰 입력해 주세요.",
),
// 비상 연락처
emergencyCall: yup
.string()
.nullable()
.matches(
/(^01([0|1|6|7|8|9]?)-?([0-9]{3,4})-?([0-9]{4})$)|(^$)/,
// /^01([0|1|6|7|8|9]?)-?([0-9]{3,4})-?([0-9]{4})$/,
"형식에 맞춰 입력해 주세요.",
),
// 겸직
deptCrewList: yup.array().of(
yup.object().shape({
deptId: yup.string().required("부서를 선택해 주세요."),
dutyId: yup.string().required("직책을 선택해 주세요."),
}),
),
// 개인 이메일
privateEmail: yup
.string()
.nullable()
.email("이메일 형식에 맞춰 작성해 주세요."),
});
import { yupResolver } from '@hookform/resolvers/yup';
export default function RequiredForm() {
const methods = useForm({
resolver: yupResolver(crewRequiredValidation),
mode: 'onBlur',
defaultValues: formData,
});
const { handleSubmit, watch, resetField } = methods;
const onSubmit = (data: Crew) => {
setFormData({ ...formData, ...data });
onClickNextStep();
};
return (
<FormProvider {...methods}>
<ContentWrapper>
<Row gutter={[24, 10]}>
<Col span={12}>
<FormInputRadio
name="isActive"
label="사원 ON/OFF"
options={isActiveOptions}
/>
</Col>
<Col span={12}>
<FormInputText label="이름" name="crewName" />
</Col>
<Col span={12}>
<FormInputText label="사번" name="crewId" />
</Col>
<Col span={12}>
<FormInputText label="cocone ID" name="coconeId" />
</Col>
<Col span={12}>
<FormInputSelect
name="workType"
label="고용형태"
options={workTypeOptions}
/>
</Col>
....
</Row>
</ContentWrapper>
<ButtonWrapper>
<Button type="primary" onClick={handleSubmit(onSubmit)}>
다음
</Button>
</ButtonWrapper>
</FormProvider>
);
}
yupResolver
로 스키마를 호출하면 form의 input 값의 검증은 Yup에서 값은 useForm에서 관리하게 된다.