일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- Redux
- Image Resize typescript
- webrtc
- react
- identifierForVender
- code editor
- Game js
- web track
- Prism.js
- RouteObserver
- uint8array
- Completer
- KakaoMap
- Excel
- REST API
- userevent_tracker
- Three js
- Flutter
- swagger-typescript-api
- jszip
- Raycasting
- FirebaseAnalytics
- methodChannel
- babel
- Three-fiber
- uint16array
- Babel standalone
- typescript
- androidId
- node
- Today
- Total
Never give up
React - Failed to fetch dynamically imported module 본문
최근에 회사에서 다음과 같은 에러가 나타난다 라는 이야기를 들었는데
어떻게 해봐도 재연이 안됐었습니다(이유는 후술..)
먼저 발생한 에러를 보면
index.js가 안불러와진다 라는 이야기인데, dynamic import를 보고 혹시 suspense가 빠져있었나?
하고 봤더니 그걸 빼먹으면 애초에 dev모드에서 에러를 마주쳤을것이고, 다음과 같은 에러를 봤었겠지요
그래서 추측을 조금 해봤는데 보통 배포 이후에 발생하는것을 알게됐고
index-hash.js중 저 hash부분을 봤더니, 필자는 업데이트 대비를 하나도 안하고 있었다는것을 알게됐습니다..
보통 배포하고 새로 url을 쳐서 들어가면 문제가 없지만
새로 번들되었을 때 index.html이 바라보던 index-hash.js가 다른것으로 변경되면서 발생한것이죠..
그래서 경과를 보자면..
1. 모니터링 페이지이다보니 계속 켜놓고 테스트
2. 업데이트 발생
3. index를 못찾아서 에러 발생
4. 새로고침하니 해결
5. 문제 재연 안됨
6. 혹시 이건가!? - 발견
그래서 해결방안을 여러가지 생각해봤는데
1. html 다시 가져오기 : 업데이트 된 경우 업데이트(페이지 리로드)를 시켜주기
- 업데이트를 주기적으로 체크
- sse 처럼 업데이트 발생시 이벤트 발생
2. entry point index js hash 고정
- 캐싱된 index로 인해 기존 화면이 보일 수 있으나 max-age조절로 처리(다만 캐싱의 장점이 사라짐)
1, 2를 고민하던중 1로 결정했고, 서버를 최대한 이용하지 않고 작업해보기로 하고 찾아보던중
해당 자료를 발견하게 됐습니다
(링크 : https://github.com/vitejs/vite/issues/11804)
그리고 그 중 가장 간단하게 해결하는 방법을 찾았습니다
window.addEventListener("vite:preloadError", (event) => {
window.location.reload(); // for example, refresh the page
});
vite를 사용하고 있는 저로서는 가장 간단하게 해결할 수 있는 좋은 방법이 된거 같습니다
그러면 webpack이나 rollup등을 사용할 때 혹은 번들러 상관없이 처리를 할 수 있을까 해서 찾아봤습니다
1. error event로 처리
window.addEventListener('error', (event) => {
const isChunkLoadError = event.message && event.message.includes('Loading chunk');
const isDynamicImportError = event.message && event.message.includes('Failed to fetch dynamically imported module');
if (isChunkLoadError || isDynamicImportError) {
console.warn('Detected an error with dynamically loaded module. Reloading the page...');
window.location.reload();
}
});
해당 메시지로 찾아서 reload
2. version check.json 사용
fetch('배포된url/version.json')
.then(response => response.json())
.then(versionInfo => {
if (versionInfo.version !== currentAppVersion) {
window.location.reload();
}
});
페이지 이동할 때마다 version json을 fetch해서 사용
새로 번들링 할 때마다 자동으로 버전 올라가게 해놓으면 정말 편할거 같습니다
다만 리소스를 조금 더 사용해야된다는 단점이 있지만 조금 더 확실한 방법인거 같습니다
최근에 바쁘다는 핑계로 포스트 안하고 있었는데 다시 열심히 해보도록 하겠습니다
'WEB' 카테고리의 다른 글
React - zip, unzip(Feat. JSZip) (2) | 2024.11.14 |
---|---|
React - excel example(feat. XLSX) (1) | 2024.11.14 |
React - code editor 3(feat. Prism.js) (1) | 2023.12.15 |
React - code editor 2 (0) | 2023.12.15 |
React - code editor 1(feat. babel standalone) (0) | 2023.12.13 |