일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- device in use
- camera permission
- animation
- npm package
- electron-packager
- camera access
- rolldown
- custom printing
- Git
- Recoil
- dvh
- ffi-napi
- silent printing
- github lfs
- 이미지 데이터 타입
- adb connect
- Can't resolve
- vercel git lfs
- Failed to compiled
- react-native
- adb pair
- 티스토리 성능
- nextjs
- Each child in a list should have a unique "key" prop.
- react-native-dotenv
- github pdf
- ELECTRON
- github 100mb
- augmentedDevice
- html
- Today
- Total
Bleeding edge
prerendering page "/" ReferenceError: window is not defined 본문
문제점
이번에 React native와 Nextjs를 이용하여 앱을 만들고 있었다. 전역 상태로 window를 사용하는 함수가 있었고, SSR 에서 window 객체가 없는 순간에 에러가 나오기 때문에 빌드 에러가 발생한다.
에러 메세지
일반적인 window is not defined 해결 방법
처음부터 끝까지 내가 작성한 함수의 경우 window is not defined는 그 함수가 시작하는 지점 혹은, window 객체를 사용하는 지점에서 다음과 같이 return을 하면 문제가 없다.
if(typeof window === 'undefined') return
하지만 이번에 문제를 일으킨 함수같은 경우 heic2any라는 라이브러리라서 import를 하는 순간 window is not defined가 발생한다.
첫 번째 시도: DynamicProvider
문제가 생긴 지점에서 window type을 이용하는 방법이 통하지 않는다는 것을 확인하고, 전역 함수의 프로바이더를 Dyanmic import 하였다.
//before
import { ImageFetchProvider } from '@/contexts/ImageFetchContext';
//after
const DynamicProviderWithoutSSR = dynamic(
async () => {
const ImageFetch = await import('@/contexts/ImageFetchContext');
return ImageFetch.ImageFetchProvider;
},
{ ssr: false }
);
이 방법이 어느 정도는 유효했던 것은 처음에는 Context를 공유하는 모든 페이지에서 prerendering 에러가 발생했었지만, 이 방법을 사용하니 ImageFetchProvider만 사용한 페이지만 prerendering 에러가 발생했다.
두 번째 시도: Dynamic import
before
import heic2any from 'heic2any';
export async function convertToJPG(file: File): Promise<Blob> {
let imageFile: Blob = file;
if (file.type === 'image/jpeg') return imageFile;
if (file.type === 'image/heic' || file.type === 'image/heif') {
const result = heic2any({
blob: file,
toType: 'image/png',
quality: 1,
});
...
}
...
}
after
if (file.type === 'image/heic' || file.type === 'image/heif') {
const heic2any = (await import('heic2any')).default;
const result = heic2any({
blob: file,
toType: 'image/png',
quality: 1,
});
if (Array.isArray(result)) {
throw new Error('Expected a single image, but got multiple images.');
}
imageFile = result;
}
이 방법을 사용하니 prerendering 해결되었다. 물론, heic2any에서는 blob 객체와 blob을 반환하기 때문에 이를 원하는 값이 나오도록 수정하였지만..
후기
nodejs와 javascript가 혼재하는 nextjs에서는 window is not defined는 생각보다 자주 만나는 에러다. 항상 localstorage나 다른 내가만든 함수에서만 만나는 에러여서 조건문 하나로 해결하고 넘어갔었다. 하지만 이번에 라이브러리 내부에서 window를 사용하는 것을 보고, 새로운 해결책을 찾아내면서 다음에 같은 에러가 발생하면 이런 방식으로도 해결 할 수 있거나를 생각 할 수 있어서 좋았다.
'Javascript' 카테고리의 다른 글
Image date 다루기(data 변환에 관하여) (0) | 2023.12.03 |
---|---|
자바스크립트로 모든 이벤트를 확인하기 (0) | 2023.10.21 |
Axios로 간이 api mocking 세팅하기 (0) | 2023.08.14 |
순차적으로 비동기 실행시키기 (0) | 2023.08.13 |
환경에 따라 다른 서버로 Request 보내기 (0) | 2023.08.09 |