From f887343dbf4cd7f03e673a9be0568ab016af72b3 Mon Sep 17 00:00:00 2001 From: peacepiece7 Date: Wed, 25 Sep 2024 06:59:28 +0900 Subject: [PATCH] =?UTF-8?q?feat(@app/punk-record):=20=ED=8F=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8,=20metadata=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/global.code-snippets | 4 +- apps/punk-record/.vscode/global.code-snippets | 20 ++++++ ...\354\232\251 \354\240\225\353\246\254.mdx" | 72 ++++++++++++++----- ...\354\212\210 \354\240\225\353\246\254.mdx" | 60 +++++++++++++--- ...5\204\264\354\212\244\354\231\200 jpa.mdx" | 14 ++-- ...4\354\240\225\355\225\230\352\270\260.mdx" | 37 ++++++++-- ...\353\212\224 \354\230\265\354\205\230.mdx" | 46 ++++++++++++ ...4\354\240\225\355\225\230\352\270\260.mdx" | 36 ++++++++++ ...235\264\352\270\260 (sparse-checkout).mdx" | 13 +++- .../[pageId]/1. semver\354\231\200 npm.mdx" | 13 +++- ...\353\262\225 \354\240\225\353\246\254.mdx" | 13 +++- ... \355\201\264\353\236\230\354\212\244.mdx" | 13 +++- .../languages/java/syntax/[pageId]/3. api.mdx | 11 ++- .../java/syntax/[pageId]/4. mini projects.mdx | 13 +++- ...\355\214\205 \353\241\234\352\267\270.mdx" | 23 ++++-- .../@contents/styles/css/[pageId]/2. ux.mdx | 37 ++++++---- .../[pageId]/1. arc browser shortcut.mdx | 8 +++ ...\353\212\245 \354\240\225\353\246\254.mdx" | 11 +++ ...\353\257\270\354\204\270 \355\214\201.mdx" | 8 +++ ...\353\257\270\354\204\270 \355\214\201.mdx" | 11 +++ ...ground.mdx => 1. storybook playground.mdx} | 21 ++++-- .../tools/yarn/[pageId]/1. yarn-berry.mdx | 15 +++- 22 files changed, 434 insertions(+), 65 deletions(-) create mode 100644 apps/punk-record/.vscode/global.code-snippets create mode 100644 "apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/5. ObjectMapper \354\236\220\354\243\274 \354\202\254\354\232\251\355\225\230\353\212\224 \354\230\265\354\205\230.mdx" create mode 100644 "apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/6. Swagger \354\204\244\354\240\225\355\225\230\352\270\260.mdx" rename apps/punk-record/src/app/posts/@contents/tools/storybook/[pageId]/{1. stoybook playground.mdx => 1. storybook playground.mdx} (89%) diff --git a/.vscode/global.code-snippets b/.vscode/global.code-snippets index 692b18e..14ac927 100644 --- a/.vscode/global.code-snippets +++ b/.vscode/global.code-snippets @@ -2,7 +2,6 @@ "Create MDX": { "prefix": "create-mdx", "body": [ - "$0", "export const METADATA = {", " title: \"blog | ${TM_FILENAME_BASE}\"", " description: \"${TM_FILENAME_BASE}\",", @@ -12,6 +11,9 @@ "}", "import { Detail } from \"@/components/mdx/detail\"", "import { MDXImage, MDXFlex } from \"@/components/mdx/image\"", + "\n", + "# ${TM_FILENAME_BASE}", + "$0" ], }, } diff --git a/apps/punk-record/.vscode/global.code-snippets b/apps/punk-record/.vscode/global.code-snippets new file mode 100644 index 0000000..4682ab6 --- /dev/null +++ b/apps/punk-record/.vscode/global.code-snippets @@ -0,0 +1,20 @@ +{ + "Create MDX": { + "prefix": "create-mdx", + "body": [ + "export const METADATA = {", + " title: \"blog | ${TM_FILENAME_BASE}\"", + " description: \"${TM_FILENAME_BASE}\",", + " date: \"\",", + " tags: [],", + " authors: \"scv7282@gmail.com\"" + "}", + "import { Detail } from \"@/components/mdx/detail\"", + "import { MDXImage, MDXFlex } from \"@/components/mdx/image\"", + "import { Kbd } from \"@repo/ui-shadcn/ui/typography/kdb\"" + "\n", + "# ${TM_FILENAME_BASE}", + "$0" + ], + }, +} diff --git "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/1. Spring boot \352\263\265\353\266\200 \353\202\264\354\232\251 \354\240\225\353\246\254.mdx" "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/1. Spring boot \352\263\265\353\266\200 \353\202\264\354\232\251 \354\240\225\353\246\254.mdx" index f3f7b5c..d2ced28 100644 --- "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/1. Spring boot \352\263\265\353\266\200 \353\202\264\354\232\251 \354\240\225\353\246\254.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/1. Spring boot \352\263\265\353\266\200 \353\202\264\354\232\251 \354\240\225\353\246\254.mdx" @@ -109,11 +109,11 @@ public class UserEntity { 컨트롤러를 정의할 떄 사용하는 어노테이션이다. -@RestController는 JSON, XML같은 데이터를 반환하기위해 사용하는 어노테이션이다. 이걸 붙여줘야 스프링 컨테이너에 등록된다. +`@RestController`는 JSON, XML같은 데이터를 반환하기위해 사용하는 어노테이션이다. 이걸 붙여줘야 스프링 컨테이너에 등록된다. -@Controller도 있는데 이건 view를 반환할 때 사용한다. +`@Controller`도 있는데 이건 view를 반환할 때 사용한다. -@GetMapper, @PostMapper, @PutMapper, @DeleteMapper를 사용하면 각각 GET, POST, PUT, DELETE 요청을 처리할 수 있다. +`@GetMapper`, `@PostMapper`, `@PutMapper`, `@DeleteMapper`를 사용하면 각각 GET, POST, PUT, DELETE 요청을 처리할 수 있다. 아래 예시는 `POST /api/post` 경로에서 User 객체를 받아서 반환하는 컨트롤러이다. @@ -131,9 +131,9 @@ public class RestApiController { ## @JsonProperty, @JsonIgnore -@JsonProperty: json으로 변환할 때 필드명을 변경할 수 있다. +`@JsonProperty`: json으로 변환할 때 필드명을 변경할 수 있다. -@JsonIgnore: json으로 변환할 때 해당 필드를 무시한다. +`@JsonIgnore`: json으로 변환할 때 해당 필드를 무시한다. ```java @Data @@ -152,12 +152,11 @@ public class User { ### 직렬화, 역직렬화 -java는 jackson 라이브러리로 json을 역/직렬화한다. - -이는 내부적으로 getter/setter, toString을 사용한다. (자스랑 비슷함) - -JSON 변환할 때 예외 사항이 있을 경우 @JsonProperty, @JsonIgnore로 충분하지만 +java는 jackson 라이브러리로 json을 역/직렬화한다.\ +이는 내부적으로 getter/setter, toString을 사용한다.\ +(자스랑 비슷함) +JSON 변환할 때 예외 사항이 있을 경우 @JsonProperty, @JsonIgnore로 충분하지만\ 경우에 따라서 `@JsonSerialize`, `@JsonDeserialize`이나 getter/setter, toString 등 여러 방법을 고려할 수 있다. ## Exception @@ -248,7 +247,7 @@ var prevData = dataList.stream() .filter(it -> it.getId().equals(data.getId())) .findFirst(); -public void failture() { +public void failure() { if(prevData.isPresent()) { // 왠지 dataList 는 List 일 것 같은데 Optional> 임 } @@ -263,8 +262,7 @@ prevData.ifPresent(dataList::remove); ``` -그외 is(if)Empty 도 있고 로직이 길어지지만 `dataList.get(i)`을 써도 된다. - +그외 is(if)Empty 도 있고 로직이 길어지지만 `dataList.get(i)`을 써도 된다.\ ~~대충 만들언 intellij 가 알아서 추천해줌~~ @@ -296,7 +294,7 @@ public class Controller() { ## @service -서비스 레이어는 @Service 어노테이션을 적어줘야한다. +서비스 레이어는 `@Service` 어노테이션을 적어줘야한다. ```java @Service @@ -305,8 +303,7 @@ public class UserService { } ``` -Service 계층이 아님에도 스프링 컨테이너에 등록해야 하는 경우는 `@Component`를 붙여주면 되고 - +Service 계층이 아님에도 스프링 컨테이너에 등록해야 하는 경우는 `@Component`를 붙여주면 되고\ 외부 라이브러리라면 `@Configuration` -> `@Bean` 어노테이션을 붙이고 인스턴스를 리턴하면 스프링 컨테이너에 등록된다. ```java @@ -320,6 +317,49 @@ public class DataBaseConfig { } ``` +## @MappedSuperclass + +직접 테이블에 매핑되지 않지만 해당 필드를 상속받아 쓸수 있다.\ +(createdAt, UpdatedAt, Id 같은 것들에 사용된다.) + +```java +@MappedSuperclass +public abstract class BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "created_at") + private LocalDateTime createdAt; + + @Column(name = "updated_at") + private LocalDateTime updatedAt; +} + +@Entity +public class User extends BaseEntity { + // ...rest attrs +} +``` + +## @SuperBuilder + +엔티티를 상속 받을 경우 부모 엔티티의 속성을 쓰고 싶다면 `@SuperBuilder`를 사용해야한다. + +```java +@MappedSuperclass +@SuperBuilder +public class BaseEntity {} + +@Entity +@Table(name = "account") +@SuperBuilder +public class AccountEntity extends BaseEntity { + // ... rest attrs +} +``` + ## 참고 [전체 소스 보기 (각 챕터마다 note.md 있응께 가물가물한 내용있으면 잠고하자)](https://github.com/peacepiece7/spring-boot-playground) diff --git "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/2. Spring boot \354\235\264\354\212\210 \354\240\225\353\246\254.mdx" "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/2. Spring boot \354\235\264\354\212\210 \354\240\225\353\246\254.mdx" index e9fc518..61335e3 100644 --- "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/2. Spring boot \354\235\264\354\212\210 \354\240\225\353\246\254.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/2. Spring boot \354\235\264\354\212\210 \354\240\225\353\246\254.mdx" @@ -1,8 +1,15 @@ -import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" +export const METADATA = { + title: "blog | 2. Spring boot 이슈 정리" + description: "2. Spring boot 이슈 정리", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} import { Detail } from "@/components/mdx/detail" import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" -# Spring Boot 이슈 정리 +# 2. Spring boot 이슈 정리 ## IntelliJ에서 JVM 버전 변경이 안되는 이슈 @@ -53,12 +60,9 @@ gradlew -version ### 방법 1 -UTF-8이 기본인데 ms는 ms949 포멧이라서 한글이 깨짐 - -UTF-8 3byte, ms949나 euc-kr은 2byte 로 한글을 표현해서 깨짐 - -ctrl + p -> 전체 -> file encoding 검색 - +UTF-8이 기본인데 ms는 ms949 포멧이라서 한글이 깨진다\ +UTF-8 3byte, ms949나 euc-kr은 2byte 로 한글을 표현해서 깨진다.\ +ctrl + p -> 전체 -> file encoding 검색\ global encoding, project encoding utf-8로 변경 ### 방법 2 @@ -96,3 +100,43 @@ public class UserRequest { private Boolean isKorean; // matched } ``` + +## Using @EqualsAndHashCode for JPA entities is not recommended. It can cause severe performance and memory consumption issues. + +`@Data`, `@EqualsAndHashCode` 어노테이션 모두 메모리 소비 이슈로 추천하지 않는 경고가 출력된다.\ +다음 코드처럼 변경하길 권한다. + +```java +@Getter +@Entity +@NoArgsConstructor(access = PROTECTED) +public class Users { + + /// ... 생략 + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) { + return false; + } + Users that = (Users) o; + return id != null && Objects.equals(id, that.id); + } + + @Override + public int hashCode() { + return getClass().hashCode(); + } + +} +``` + +추가로 + +`@EqualsAndHashCode(callSuper = true)` 어노테이션은 Equal, HashCode 오버라이드해준다.\ +callSuper = true 일 경우 부모 클래스의 속성도 포함한다. + +[Warnings when using @EqualsAndHashCode for JPA entities](https://youtrack.jetbrains.com/issue/IDEA-279243/Warnings-when-using-EqualsAndHashCode-for-JPA-entities) diff --git "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/3. \354\236\220\353\260\224 \355\215\274\354\213\234\354\212\244\355\204\264\354\212\244\354\231\200 jpa.mdx" "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/3. \354\236\220\353\260\224 \355\215\274\354\213\234\354\212\244\355\204\264\354\212\244\354\231\200 jpa.mdx" index 1f3ff1e..63df1e5 100644 --- "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/3. \354\236\220\353\260\224 \355\215\274\354\213\234\354\212\244\355\204\264\354\212\244\354\231\200 jpa.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/3. \354\236\220\353\260\224 \355\215\274\354\213\234\354\212\244\355\204\264\354\212\244\354\231\200 jpa.mdx" @@ -1,4 +1,10 @@ -import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" +export const METADATA = { + title: "blog | 3. 자바 퍼시스턴스와 jpa" + description: "3. 자바 퍼시스턴스와 jpa", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} import { Detail } from "@/components/mdx/detail" import { MDXImage, MDXFlex } from "@/components/mdx/image" @@ -10,10 +16,8 @@ import { MDXImage, MDXFlex } from "@/components/mdx/image" ## 그리고 jpa -jpa는 자바 퍼시스턴스의 구현체이다. - -spring boot에서 db와 연동할 때 `JpaRepository`를 확장하는 인터페이스를 정의하면 jpa가 자동으로 구현체를 생성해준다. - +jpa는 자바 퍼시스턴스의 구현체이다.\ +spring boot에서 db와 연동할 때 `JpaRepository`를 확장하는 인터페이스를 정의하면 jpa가 자동으로 구현체를 생성해준다.\ 이떄 구현체에는 기본적인 CRUD 메소드가 포함되어 있고, 규칙에 맞게 메소드를 작성하면 jpa가 알아서 쿼리를 생성해준다. ```java diff --git "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/4. \353\251\200\355\213\260 \353\252\250\353\223\210 \354\204\244\354\240\225\355\225\230\352\270\260.mdx" "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/4. \353\251\200\355\213\260 \353\252\250\353\223\210 \354\204\244\354\240\225\355\225\230\352\270\260.mdx" index 27559b4..ae07f6d 100644 --- "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/4. \353\251\200\355\213\260 \353\252\250\353\223\210 \354\204\244\354\240\225\355\225\230\352\270\260.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/4. \353\251\200\355\213\260 \353\252\250\353\223\210 \354\204\244\354\240\225\355\225\230\352\270\260.mdx" @@ -1,10 +1,15 @@ -import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" +export const METADATA = { + title: "blog | 4. 멀티 모듈 설정하기" + description: "4. 멀티 모듈 설정하기", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} import { Detail } from "@/components/mdx/detail" import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" -# 멀티 모듈 설정 - -## 프로젝트 생성 +# 멀티 모듈 설정하기 alt + f -> alt + n -> alt + j ![img](/images/multi_module_1.png) @@ -45,7 +50,7 @@ allprojects { api 모듈에 db를 의존성으로 추가 -아래사진처럼 compileClasspath project.db 추가 된 것을 확인한다. +아래사진처럼 compileClassPath project.db 추가 된 것을 확인한다. ![img](/images/multi_module_4.png) @@ -53,16 +58,19 @@ api 모듈에 db를 의존성으로 추가 bootJar:\ spring boot 실행 파일을 만들어준다. + ```txt bootJar { enabled = true // default } ``` + 빌드시 build/libs/<>-SNAPSHOT.jar 파일이 생성되는데, `java -jar <>-SNAPSHOT.jar` 로 실행해보면 intelliJ에서 ctrl + shift + f10으로 실행한 것과 동일하게 동작한다. jar:\ 요것도 true로 하면 jar 파일을 만들어준다.\ boorJar랑 다른점은 실행 파일은 아니고 클래스를 묶어주는 역할이다. + ```txt jar { enabled = true // default @@ -83,3 +91,22 @@ gradle 아이콘을 열면 build 스크립트들이 있다. 다만 intelliJ에서 설정한 jdk 버전이 멀티 모듈이나, 로컬에 설치된 jdk와 버전이 다르면 cli로 해당 명령어를 입력하면 에러가 발생할 것이다. gradlew는 jdk 버전을 %JAVA_HOME% 변수에서 찾는데 gradlew을 수동으로 돌릴 떈 요거를 수정해줘야한다. + +## 멀티모듈 Bean 등록 문제 + +Spring Boot 는 `@SpringBootApplication` 이 있는 패키지와 그 하위 패키지를 기본으로 스캔하여 빈으로 등록한다. + +`@SpringBootApplication`의 스캔 규칙으로 패키지 명이 동일하면 멀티 모듈에서도 자동으로 스캔되는데\ +그렇기에 org.delivery.db.~.java 파일과 org.delivery.api.~.java 파일은 동일한 컨테이너에 빈으로 등록 할 수 없다. + +해결 방법으로 패키지명을 동일하게 바꿔주거나\ +다음과 같이 설정해줄 수 있다. + +```java +@Configuration +@EntityScan(basePackages = "org.delivery.db") +@EnableJpaRepositories(basePackages = "org.delivery.db") +public class JpaConfig { + +} +``` diff --git "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/5. ObjectMapper \354\236\220\354\243\274 \354\202\254\354\232\251\355\225\230\353\212\224 \354\230\265\354\205\230.mdx" "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/5. ObjectMapper \354\236\220\354\243\274 \354\202\254\354\232\251\355\225\230\353\212\224 \354\230\265\354\205\230.mdx" new file mode 100644 index 0000000..f128c35 --- /dev/null +++ "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/5. ObjectMapper \354\236\220\354\243\274 \354\202\254\354\232\251\355\225\230\353\212\224 \354\230\265\354\205\230.mdx" @@ -0,0 +1,46 @@ +export const METADATA = { + title: "blog | 5. ObjectMapper 자주 사용하는 옵션" + description: "5. ObjectMapper 자주 사용하는 옵션", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" + +# ObjectMapper 자주 사용하는 옵션 + +```java +// object mapper 를 안만들면 스프링에서 default 로 하나 만들어 줌 만들었으니까 내것으로 적용될 것 +@Configuration +public class ObjectMapperConfig { + + @Bean + public ObjectMapper objectMapper() { + // 존슨을 자바 객체로 변환하거나, 자바 객체를 존슨으로 변환하는 데 사용한다. + var objectMapper = new ObjectMapper(); + + // jdk 8 버전 이후에 나온 클래스, 기능을 Jackson 이 처라할 수 있도록 해준다. + objectMapper.registerModule(new Jdk8Module()); + + // Java 8의 java.time.LocalDate, java.time.LocalDateTime 등을 Jackson 이 처리할 수 있도록 해준다. + objectMapper.registerModule(new JavaTimeModule()); + + // JSON 데이터에 포함된 예상하지 못한 필드를 처리하는 방식을 지정한다. + // 정의되지 않은 필드를 만나면 Exception 발생이 default, false 시 이를 무시하고 de/serialization 수행 + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + // Getter 가 없는 빈 클래스를 직렬화 시 예외 발생이 default, false 시 이를 무시하고 de/serialization 수행, 모든 필드가 null 일 경우 사용됨 + objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); // + + // Jackson 은 TimeStamp 로 직렬화 하는게 default, disable 시 ISO 8601 형식으로 직렬화 됨, LocalDate, LocalDateTime 을 가독성 좋게 변경할 떄 사용 + objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); + + // Java 객채 필드의 이름을 JSON 필드 이름으로 변환할 떄 Snake Case 스타일 지정 + // 요거 있으면 @JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) 안붙여도 됨 + objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategies.SnakeCaseStrategy()); + + return objectMapper; + } +} +``` diff --git "a/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/6. Swagger \354\204\244\354\240\225\355\225\230\352\270\260.mdx" "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/6. Swagger \354\204\244\354\240\225\355\225\230\352\270\260.mdx" new file mode 100644 index 0000000..d32b50d --- /dev/null +++ "b/apps/punk-record/src/app/posts/@contents/frameworks/spring_boot/[pageId]/6. Swagger \354\204\244\354\240\225\355\225\230\352\270\260.mdx" @@ -0,0 +1,36 @@ +export const METADATA = { + title: "blog | 5. Swagger 설정하기" + description: "5. Swagger 설정하기", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" + +# Swagger 설정하기 + +mavenRepository SpringDoc 검색 + +1.8v 까지 나왔는데 강의랑 맞추기 위해 1.7 씀 + +springDoc 패키지를 build.gradle 설정 파일에 추가 + +```text +// Swagger(Spring 3.x.x 이상부터 SpringFox 대신, SpringDoc) +implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2' +``` + +## swagger config 설정 + +```java +@Configuration +public class SwaggerConfig { + + // ObjectMapperConfig.java에 정의한 objectMapper 메서드가 실행되면 리턴값이 요기 파라메터(objectMapper)로 주어짐 + @Bean + public ModelResolver modelResolver (ObjectMapper objectMapper) { + return new ModelResolver(objectMapper); + } +} +``` diff --git "a/apps/punk-record/src/app/posts/@contents/knowledge/etc/[pageId]/1. monorepo\354\227\220\354\204\234 git clone \354\232\251\353\237\211 \354\244\204\354\235\264\352\270\260 (sparse-checkout).mdx" "b/apps/punk-record/src/app/posts/@contents/knowledge/etc/[pageId]/1. monorepo\354\227\220\354\204\234 git clone \354\232\251\353\237\211 \354\244\204\354\235\264\352\270\260 (sparse-checkout).mdx" index 7e5baab..d4c42ab 100644 --- "a/apps/punk-record/src/app/posts/@contents/knowledge/etc/[pageId]/1. monorepo\354\227\220\354\204\234 git clone \354\232\251\353\237\211 \354\244\204\354\235\264\352\270\260 (sparse-checkout).mdx" +++ "b/apps/punk-record/src/app/posts/@contents/knowledge/etc/[pageId]/1. monorepo\354\227\220\354\204\234 git clone \354\232\251\353\237\211 \354\244\204\354\235\264\352\270\260 (sparse-checkout).mdx" @@ -1,4 +1,15 @@ -# sparse-checkout +export const METADATA = { + title: "blog | 1. monorepo에서 git clone 용량 줄이기 (sparse-checkout)" + description: "1. monorepo에서 git clone 용량 줄이기 (sparse-checkout)", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + +# monorepo에서 git clone 용량 줄이기 (sparse-checkout) 모노레포에서 git clone 용량 줄이기 위해 sparse-checkout으로 필요한 브랜치만 가져올 때 사용한다. diff --git "a/apps/punk-record/src/app/posts/@contents/knowledge/semver/[pageId]/1. semver\354\231\200 npm.mdx" "b/apps/punk-record/src/app/posts/@contents/knowledge/semver/[pageId]/1. semver\354\231\200 npm.mdx" index e5bbd30..c0b1f96 100644 --- "a/apps/punk-record/src/app/posts/@contents/knowledge/semver/[pageId]/1. semver\354\231\200 npm.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/knowledge/semver/[pageId]/1. semver\354\231\200 npm.mdx" @@ -1,4 +1,15 @@ -# 유의적 버전 +export const METADATA = { + title: "blog | 1. semver와 npm" + description: "1. semver와 npm", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + +# semver와 npm ## version diff --git "a/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/1. \353\254\270\353\262\225 \354\240\225\353\246\254.mdx" "b/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/1. \353\254\270\353\262\225 \354\240\225\353\246\254.mdx" index e454c90..6ffad4f 100644 --- "a/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/1. \353\254\270\353\262\225 \354\240\225\353\246\254.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/1. \353\254\270\353\262\225 \354\240\225\353\246\254.mdx" @@ -1,4 +1,15 @@ -# 자바 문법 정리 +export const METADATA = { + title: "blog | 1. 문법 정리" + description: "1. 문법 정리", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + +# 문법 정리 ## 원시 타입 (Primitive type) diff --git "a/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/2. \355\201\264\353\236\230\354\212\244.mdx" "b/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/2. \355\201\264\353\236\230\354\212\244.mdx" index e481507..c6d7066 100644 --- "a/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/2. \355\201\264\353\236\230\354\212\244.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/2. \355\201\264\353\236\230\354\212\244.mdx" @@ -1,4 +1,15 @@ -# 클래스 +export const METADATA = { + title: "blog | 자바 클래스" + description: "자바 클래스", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + +# 자바 클래스 ## OOP diff --git a/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/3. api.mdx b/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/3. api.mdx index 994dce7..6294c97 100644 --- a/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/3. api.mdx +++ b/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/3. api.mdx @@ -1,6 +1,15 @@ +export const METADATA = { + title: "blog | 3. api" + description: "3. api", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" -# API +# api ## maven, gradle diff --git a/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/4. mini projects.mdx b/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/4. mini projects.mdx index 94d42a8..f841442 100644 --- a/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/4. mini projects.mdx +++ b/apps/punk-record/src/app/posts/@contents/languages/java/syntax/[pageId]/4. mini projects.mdx @@ -1,4 +1,15 @@ -# min projects +export const METADATA = { + title: "blog | 4. mini projects" + description: "4. mini projects", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + +# mini projects ## apache poi diff --git "a/apps/punk-record/src/app/posts/@contents/styles/css/[pageId]/1. CSS \355\212\270\353\237\254\353\270\224\354\212\210\355\214\205 \353\241\234\352\267\270.mdx" "b/apps/punk-record/src/app/posts/@contents/styles/css/[pageId]/1. CSS \355\212\270\353\237\254\353\270\224\354\212\210\355\214\205 \353\241\234\352\267\270.mdx" index 19f208a..cfd89aa 100644 --- "a/apps/punk-record/src/app/posts/@contents/styles/css/[pageId]/1. CSS \355\212\270\353\237\254\353\270\224\354\212\210\355\214\205 \353\241\234\352\267\270.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/styles/css/[pageId]/1. CSS \355\212\270\353\237\254\353\270\224\354\212\210\355\214\205 \353\241\234\352\267\270.mdx" @@ -1,4 +1,17 @@ -# input autofocus, focus가 안됨 +export const METADATA = { + title: "blog | 1. CSS 트러블슈팅 로그" + description: "1. CSS 트러블슈팅 로그", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + +## 1. CSS 트러블슈팅 로그 + +## input autofocus, focus가 안됨 `document.querySelector('input').focus()`와 ``가 안되는 이슈가 있었다. @@ -8,16 +21,16 @@ 2. transition 이벤트가 걸려있고, 모달이 오픈되는 동안 transition이 발생한다. 3. 모달은 transition-all로 되어 있고, css visibility, opacity 속성이 transition 대상이다. -## 원인 +### 원인 visibliity가 원인으로 transition되는 동안은 focus가 되지 않는다. -## 해결 방안 +### 해결 방안 -### ref.addEventListener('transitionend')를 사용하여 transition이 끝난 후 focus를 준다. +#### ref.addEventListener('transitionend')를 사용하여 transition이 끝난 후 focus를 준다. transiton-all 이벤트가 외부 패키지에 있거나 컴포넌트를 수정할 수 없을 경우 차선책으로 사용할 수 있다. -### transition-all을 transition-opacity로 변경한다. +#### transition-all을 transition-opacity로 변경한다. css 수정이 가능하다면 transition-opacity만 transition 이벤트를 줘서 해결한다. diff --git a/apps/punk-record/src/app/posts/@contents/styles/css/[pageId]/2. ux.mdx b/apps/punk-record/src/app/posts/@contents/styles/css/[pageId]/2. ux.mdx index e7a353f..7d77403 100644 --- a/apps/punk-record/src/app/posts/@contents/styles/css/[pageId]/2. ux.mdx +++ b/apps/punk-record/src/app/posts/@contents/styles/css/[pageId]/2. ux.mdx @@ -1,4 +1,17 @@ -# 탭 (tabindex) +export const METADATA = { + title: "blog | 2. ux" + description: "2. ux", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + +# ux + +## 탭 (tabindex) anchor, button, input, select, summary(+ details), textarea는 기본적으로 tab으로 focus를 받을 수 있다. @@ -6,7 +19,7 @@ anchor, button, input, select, summary(+ details), textarea는 기본적으로 t Breadcumb, Dropbox, Dropdown, Checkbox, Cascader, Switch, ~Picker, ~Tree 등의 이름이 사용되는 컴포넌트라면 tabindex를 점검하자 -# 모달 (Modal) +## 모달 (Modal) 한 페이지 않에서 체계적인 정보를 보여주고 싶을 떄 모달을 사용한다. @@ -16,7 +29,7 @@ React는 `React.createPortal`, Vue는 `Teleport`를 사용하여 마운트 지 html만 사용할 경우 [popover api](https://developer.mozilla.org/ko/docs/Web/API/Popover_API)를 사용해서 모달을 만들 수 있다. -## 컨텐츠 밀림 +### 컨텐츠 밀림 뷰포트 우측에 스크롤이 있을 경우 모달이 열렸을 때 우측 스크롤 바가 사라지는 경우가 있다. @@ -45,7 +58,7 @@ scrollbar-gutter : stable을 사용하여 문제를 해결했다. position : fixed로 모달 전체를 덮는 커버를 만든다. -## 포커스 (focus) +### 포커스 (focus) 모달이 열리면 focus가 모달 내부로 이동해야하고 @@ -53,7 +66,7 @@ position : fixed로 모달 전체를 덮는 커버를 만든다. `` 나 `ref.current.focus()`를 사용하여 모달이 열리면 포커스가 이동하도록 한다. -## 키보드 트랩 +### 키보드 트랩 모달이 띄워지면 모달 내부에서만 탭 이동이 되어야한다. @@ -61,7 +74,7 @@ position : fixed로 모달 전체를 덮는 커버를 만든다. `useFoucsWithout`이나 `useFocusBoundary`같은 hook을 직접 만들어 사용한다. -## ESC(Escape) 키 +### ESC(Escape) 키 모달이 열려있을 때 ESC 키를 누르면 모달이 닫혀야한다. @@ -74,13 +87,13 @@ useEffect(() => { }, []) ``` -# kbd 태그 +## kbd 태그 ``태그는 키보드 입력을 나타낸다. HTML 문서 표준화와 일관적인 스타일링에 유리하기 때문에 short cut을 나타내는 인터페이스가 있다면 `kdb` 태그를 사용하는 것이 좋다. -## Ctrl + K +### Ctrl + K 브라우저 기본 기능으로 `Ctrl + L`키를 브라우저 주르면 주소창으로 포커스되고 `Ctrl + K`를 누르면 보통 검색창으로 포커스된다. @@ -88,16 +101,16 @@ HTML 문서 표준화와 일관적인 스타일링에 유리하기 때문에 sho 웹 애플리케이션 내에서 검색 기능이 있다면 `Ctrl + K`이벤트를 hooking하여 검색창으로 포커스되도록 한다. -# 줄 바꿈 (white-space, word-break, text-overflow) +## 줄 바꿈 (white-space, word-break, text-overflow) 사용자에게 전달하고자 하는 목적에 따라서 줄 바꿈을 다르게 처리하자. 샘플 문장 : `터보레포(Turborepo)는 JavaScript 생태계의 패키지 관리자의 기능인 워크스페이스를 기반으로 구축된 빌드 시스템입니다.` -## 정확한 정보를 보여줘야 하는 경우 +### 정확한 정보를 보여줘야 하는 경우 `word-break : normal` => 기본 줄바꿈, break-all 보단 가독성이 좋다. -`work-break : keep-all` => 단어 단위 줄바꿈 +`work-break : keep-all` => 단어 단위 줄바꿈 `word-break : break-all` => 글자(char)단위 줄바꿈, 이건 쓸 일이 거의 없다. 1. `word-break : normal`를 쓸 경우 @@ -140,7 +153,7 @@ JavaScript 생태계의 패키지 구축된 빌드 시스템입니다. ``` -## 정보가 중요하지 않을 경우 +### 정보가 중요하지 않을 경우 1. 한 줄로 표현하기 diff --git a/apps/punk-record/src/app/posts/@contents/tools/arc_browser/[pageId]/1. arc browser shortcut.mdx b/apps/punk-record/src/app/posts/@contents/tools/arc_browser/[pageId]/1. arc browser shortcut.mdx index 5dd217d..a6e8399 100644 --- a/apps/punk-record/src/app/posts/@contents/tools/arc_browser/[pageId]/1. arc browser shortcut.mdx +++ b/apps/punk-record/src/app/posts/@contents/tools/arc_browser/[pageId]/1. arc browser shortcut.mdx @@ -1,5 +1,13 @@ +export const METADATA = { + title: "blog | 1. arc browser shortcut" + description: "1. arc browser shortcut", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} import { Detail } from "@/components/mdx/detail" import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" # arc browser 주요 사용법 정리 diff --git "a/apps/punk-record/src/app/posts/@contents/tools/git-action/[pageId]/1. git-action \352\270\260\353\212\245 \354\240\225\353\246\254.mdx" "b/apps/punk-record/src/app/posts/@contents/tools/git-action/[pageId]/1. git-action \352\270\260\353\212\245 \354\240\225\353\246\254.mdx" index 6f33ace..e237e3d 100644 --- "a/apps/punk-record/src/app/posts/@contents/tools/git-action/[pageId]/1. git-action \352\270\260\353\212\245 \354\240\225\353\246\254.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/tools/git-action/[pageId]/1. git-action \352\270\260\353\212\245 \354\240\225\353\246\254.mdx" @@ -1,3 +1,14 @@ +export const METADATA = { + title: "blog | 1. git-action 기능 정리" + description: "1. git-action 기능 정리", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + # git-action 기능 정리 ## extension diff --git "a/apps/punk-record/src/app/posts/@contents/tools/ide/[pageId]/1. vscode \353\257\270\354\204\270 \355\214\201.mdx" "b/apps/punk-record/src/app/posts/@contents/tools/ide/[pageId]/1. vscode \353\257\270\354\204\270 \355\214\201.mdx" index 63fea8c..48391ac 100644 --- "a/apps/punk-record/src/app/posts/@contents/tools/ide/[pageId]/1. vscode \353\257\270\354\204\270 \355\214\201.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/tools/ide/[pageId]/1. vscode \353\257\270\354\204\270 \355\214\201.mdx" @@ -1,5 +1,13 @@ +export const METADATA = { + title: "blog | 1. vscode 미세 팁" + description: "1. vscode 미세 팁", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} import { Detail } from "@/components/mdx/detail" import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" # vscode 미세 팁 diff --git "a/apps/punk-record/src/app/posts/@contents/tools/ide/[pageId]/2. intellij \353\257\270\354\204\270 \355\214\201.mdx" "b/apps/punk-record/src/app/posts/@contents/tools/ide/[pageId]/2. intellij \353\257\270\354\204\270 \355\214\201.mdx" index 3fcbc77..45b779c 100644 --- "a/apps/punk-record/src/app/posts/@contents/tools/ide/[pageId]/2. intellij \353\257\270\354\204\270 \355\214\201.mdx" +++ "b/apps/punk-record/src/app/posts/@contents/tools/ide/[pageId]/2. intellij \353\257\270\354\204\270 \355\214\201.mdx" @@ -1,3 +1,14 @@ +export const METADATA = { + title: "blog | 2. intellij 미세 팁" + description: "2. intellij 미세 팁", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + # intellij 미세 팁 힙 메모리 최소 최대값 설정 diff --git a/apps/punk-record/src/app/posts/@contents/tools/storybook/[pageId]/1. stoybook playground.mdx b/apps/punk-record/src/app/posts/@contents/tools/storybook/[pageId]/1. storybook playground.mdx similarity index 89% rename from apps/punk-record/src/app/posts/@contents/tools/storybook/[pageId]/1. stoybook playground.mdx rename to apps/punk-record/src/app/posts/@contents/tools/storybook/[pageId]/1. storybook playground.mdx index 4da1698..c27939a 100644 --- a/apps/punk-record/src/app/posts/@contents/tools/storybook/[pageId]/1. stoybook playground.mdx +++ b/apps/punk-record/src/app/posts/@contents/tools/storybook/[pageId]/1. storybook playground.mdx @@ -1,6 +1,17 @@ +export const METADATA = { + title: "blog | 1. stoybook playground" + description: "1. stoybook playground", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + +# storybook playground -# Controller +## Controller 컨트롤러 조건부 추가 @@ -26,7 +37,7 @@ export const Default: Story = { ``` -# Decorator +## Decorator meta, component, preview 모두 추가 가능하다 @@ -63,7 +74,7 @@ export const Default: Story = { ``` -# Autodocs custom template +## Autodocs custom template Preview.tsx에서 autodocs를 수정할 수 있다. @@ -117,7 +128,7 @@ const meta = { export default meta ``` -# composite, multiple components +## composite, multiple components 한 페이지에서 여러 컴포넌트를 보여주는 방법 @@ -125,7 +136,7 @@ https://storybook.js.org/docs/writing-docs/autodocs#documenting-multiple-compone https://storybook.js.org/tutorials/intro-to-storybook/react/ko/composite-component/ -# reference +## reference https://velog.io/@nasikun/%EC%8A%A4%ED%86%A0%EB%A6%AC%EB%B6%81-StoryBook%EC%9D%98-%EA%B8%B0%EB%8A%A5%EC%9D%80-%EC%96%B4%EB%94%94%EA%B9%8C%EC%A7%80-%ED%99%9C%EC%9A%A9-%EA%B0%80%EB%8A%A5%ED%95%9C%EA%B1%B0%EC%97%90%EC%9A%94 diff --git a/apps/punk-record/src/app/posts/@contents/tools/yarn/[pageId]/1. yarn-berry.mdx b/apps/punk-record/src/app/posts/@contents/tools/yarn/[pageId]/1. yarn-berry.mdx index c133ac2..8d69f81 100644 --- a/apps/punk-record/src/app/posts/@contents/tools/yarn/[pageId]/1. yarn-berry.mdx +++ b/apps/punk-record/src/app/posts/@contents/tools/yarn/[pageId]/1. yarn-berry.mdx @@ -1,4 +1,15 @@ -# yarn +export const METADATA = { + title: "blog | 1. yarn-berry" + description: "1. yarn-berry", + date: "", + tags: [], + authors: "scv7282@gmail.com" +} +import { Detail } from "@/components/mdx/detail" +import { MDXImage, MDXFlex } from "@/components/mdx/image" +import { Kbd } from "@repo/ui-shadcn/ui/typography/kdb" + +# yarn-berry 다음 명령어로 yarn 설치한다. @@ -18,7 +29,7 @@ yarn init -2 1. vscode extension에서 ZipFs를 설치 -PnP 모드시 zip archives에서 타입을 가져와주는 yarn toolchain이다. [ZipFS](https://marketplace.visualstudio.com/items?itemName=arcanis.vscode-zipfs) +PnP 모드시 zip archives에서 타입을 가져와주는 yarn toolchain이다. [ZipFS](https://marketplace.visualstudio.com/items?itemName=arcanis.vscode-zipfs) (node_modules가 없기 때문에 타입 에러 발생한다. yarn pnp 모드시 필수) 2. `yarn dlx @yarnpkg vscode` 실행