Next.js + Express.js 조합에서 service worker 에러가 발생 했다.
SW registration failed:
TypeError:
Failed to register a ServiceWorker for scope ('~~~') with script ('~~~/service-worker.js'):
A bad HTTP response code (404) was received when fetching the script.
본 에러는 404에러로 해당 도메인에서 service-worker.js를 찾지 못하는 이슈이다.
확인해야 할 부분은 아래와 같다.
- manifest.json, "start_url"
- service-worker.js 파일 확인
- express, static 파일 제공
- server.js, "/service-worker.js" 라우팅
"start_url": "/",
"display": "standalone",
"theme_color": "#3d5afe"
앱 설정 파일인 manifest.json 에서 start_url을 기준으로 service-worker.js를 찾는다.
해당 키에 올바른 주소값이 입력됐는지 확인해보자.
console.log(filePath)
// /Users/mac/WebstormProjects/frontend-project/.next/service-worker.js
next-offline 라이브러리를 적용하면 next js는 빌드 시, .next/ 에 service-worker.js를 생성 한다.
next.config.js에서 경로를 별도 지정했을 경우, 해당 경로에 파일이 생성된다.
server.use(express.static('.next'))
// http://localhost:3000/.next
express에서 .next와 같은 정적 폴더로 접근하려면, 위 함수를 사용하여 경로를 지정해 주어야 한다.
service worker가 public 폴더 내 위치한게 아니기 때문에, server.js에 직접 /service-worker.js 로 라우팅 작업이 필요 하다.
next.config.js에서 경로를 별도 지정했을 경우, 해당 경로로 설정해주자.
server.get('/service-worker.js', (req, res) => {
res.set(
'Cache-Control',
'no-store, no-cache, must-revalidate, proxy-revalidate'
)
res.set('Content-Type', 'application/javascript')
const parsedUrl = parse(req.url, true)
const { pathname } = parsedUrl
const filePath = join(__dirname, '.next', pathname)
return app.serveStatic(req, res, filePath)
})
정상적으로 service worker 가 등록된 것을 알 수 있다.
Lighthouse
Chrome dev console