Nuxt에서 useAsyncData와 useFetch는 서버 사이드 렌더링(SSR) 과정에서 데이터를 가져온 후, 해당 데이터를 클라이언트로 전달하기 위해 payload에 직렬화합니다. 이때 Nuxt는 JavaScript 객체를 안전하고 정확하게 직렬화하기 위해 devalue 라이브러리를 사용합니다.
1. 왜 devalue를 사용하는가?
JSON.stringify만으로는 Nuxt의 직렬화 요구 사항을 충족할 수 없는 경우가 있습니다:
- Circular references(순환 참조): JSON.stringify는 순환 참조를 처리할 수 없습니다.
- Functions, Symbols, undefined: JSON.stringify는 이러한 데이터를 직렬화하지 않습니다.
- Prototype references: 특정 객체의 프로토타입 정보를 유지해야 할 경우 JSON.stringify는 이를 잃어버릴 수 있습니다.
devalue는 이러한 한계를 극복하고, 안전하면서도 SSR에서 복잡한 데이터를 클라이언트로 전달할 수 있도록 도와줍니다.
2. Nuxt에서의 사용 흐름
Nuxt는 SSR 렌더링 후 데이터를 클라이언트로 전달하기 위해 다음 과정을 거칩니다:
a. 서버 사이드 데이터 획득
- useAsyncData나 useFetch를 호출하면 서버 측에서 API 호출 등의 작업을 통해 데이터를 가져옵니다.
- 데이터는 서버 측에서 JSON 객체 형태로 관리됩니다.
b. 데이터 직렬화 (devalue 사용)
- 데이터를 클라이언트로 보내기 전에 직렬화 과정이 필요합니다.
- 이때 Nuxt는 devalue를 사용하여 데이터를 안전하게 문자열로 변환합니다.
c. 클라이언트로 전달
- 직렬화된 데이터는 Nuxt의 payload로 포함됩니다.
- 이 payload는 클라이언트로 전달되고, HTML 문서 내 <script> 태그에 주입됩니다.
예)
<script>
window.__NUXT__ = {
data: [{ foo: 'bar', date: new Date("2025-01-17T00:00:00.000Z") }],
state: {}
};
</script>
d. 클라이언트 측 역직렬화
- 클라이언트는 payload 데이터를 읽고 JavaScript 객체로 복원합니다.
- 복원 과정에서도 devalue의 역직렬화 처리가 포함됩니다.
3. Nuxt에서 devalue가 필요한 이유
Nuxt는 SSR과 CSR을 원활하게 연결하기 위해 클라이언트가 서버에서 처리한 데이터를 정확히 사용할 수 있도록 보장해야 합니다. devalue는 다음과 같은 데이터 유형을 처리하는 데 탁월합니다:
- Date 객체: JSON.stringify는 Date 객체를 ISO 문자열로 변환하지만, devalue는 이를 유지합니다.
- RegExp 객체: 정규식을 문자열 대신 올바르게 직렬화합니다.
- Nested Structures: 깊은 중첩 객체를 처리하고, 순환 참조도 감지하여 에러를 방지합니다.
4. Nuxt 내부에서 devalue의 실제 사용 위치
Nuxt 소스 코드에서 devalue는 SSR에서 데이터를 직렬화할 때 다음 위치에서 사용됩니다:
1. 서버에서 데이터 직렬화
- Nuxt의 renderPayload 함수에서 데이터 직렬화에 devalue를 호출합니다.
- 소스 코드 예시(Nuxt 3 기준): 아래
import { devalue } from 'devalue';
function renderPayload(data) {
return devalue(data);
}
2. 클라이언트에서 직렬화된 데이터를 주입
- • 서버에서 렌더링된 데이터를 HTML 문서 내에 <script>로 삽입합니다.
- 클라이언트는 이 데이터를 복원해 재사용합니다.
5. 참고 사항
• 보안 이슈: devalue는 XSS 공격을 방지하기 위해 직렬화 과정에서 안전성을 보장합니다.
• 성능: devalue는 JSON.stringify보다 약간 느릴 수 있지만, Nuxt의 기능 요구를 충족하는 데 필수적입니다.
'코드 > Nuxt3' 카테고리의 다른 글
[Nuxt] Data serialized from server (0) | 2025.01.17 |
---|---|
[Nuxt] useFetch options (0) | 2025.01.15 |
[Nuxt] getCachedData 사용하기 (0) | 2025.01.13 |
[useAsyncData, useFetch] cache 처리 방식 비교 (0) | 2025.01.09 |
[Nuxt] useFetch 에 await 가 필요할까 (0) | 2024.12.28 |