개발 / / 2024. 4. 26. 06:44

webgpu parcel로 실행하기 + fetch 파일이 html인지 체크

반응형

script type module

parcel 설치 후 테스트는 해보았는데, 현재 canvas로 cube를 렌더링하고 있는 프로젝트로 실행을 해보았다.

 

WebGPUCanvas.ts:135 Uncaught ReferenceError: parcelRequire is not defined
    at WebGPUCanvas.ts:135:15
    at quat2.js:79:3
(anonymous) @ WebGPUCanvas.ts:135
(anonymous) @ quat2.js:79
Show 1 more frame
Show less
mat4.js:1910 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'offsetWidth')
    at CheckWebGPU (mat4.js:1910:26)
    at _callee$ (mat4.js:1910:26)
    at tryCatch (mat4.js:1910:26)
    at Generator.<anonymous> (mat4.js:1910:26)
    at Generator.next (mat4.js:1910:26)
    at mat4.js:1910:26
    at new Promise (<anonymous>)
    at __awaiter (mat4.js:1910:26)
    at mat4.js:1910:26
    at parcelRequire.main.ts../ObjLoader (mat4.js:1910:26)
CheckWebGPU @ mat4.js:1910
_callee$ @ mat4.js:1910
tryCatch @ mat4.js:1910
(anonymous) @ mat4.js:1910
(anonymous) @ mat4.js:1910
(anonymous) @ mat4.js:1910
__awaiter @ mat4.js:1910
(anonymous) @ mat4.js:1910
parcelRequire.main.ts../ObjLoader @ mat4.js:1910
newRequire @ PerspectiveCamera.ts:27
(anonymous) @ Program.ts:99
(anonymous) @ quat2.js:79
Show 10 more frames
Show less
localhost/:1 Unchecked runtime.lastError: The message port closed before a response was received.

헉. 어디가 문제지 하고 봤는데.

 

<html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>WebGPU Project</title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script type="module" src="main.ts"></script>
</head>
<body>
  <div id="error-text"></div>
  <canvas id="canvas-webgpu"></canvas>
</body>
</html>

여기서 혹시나 하고 main.ts를 module로 가져오지 않고

 

<script src="main.ts"></script>

이렇게 수정하고 실행해봤다.

 

이게 문제였다. 아무래도 module type으로 가져오면 main.ts에서 다른 import들을 참조하지 못하는 모양이다.

 

Object loader error 테스트 에러 출력 오류

만약 파일 경로가 잘못되었다면 에러가 잘 뜰지 테스트를 해봤는데

 

이렇게만 뜨고, load 경로가 잘못되었다는 에러를 안띄운다.

 

Calling [RenderPassEncoder].Draw with an index count of 0 is unusual.

대신에 오류만 나오는데

 

왜 throw된 에러를 출력하지 못하지?

 

ObjLoader.ts error throwing

이거 에러를 console창으로 못 띄우는 이유가 ObjLoader 코드에 있다고 생각해서 load함수를 봤다.

 

  async load(filePath: FilePath): Promise<ObjFile> {
    const resp = await fetch(filePath);
    console.log(resp);
    if (!resp.ok) {
      throw new Error(
        `ObjLoader could not fine file at ${filePath}. Please check your path.`
      );
    }
    const file = await resp.text();

    if (file.length === 0) {
      throw new Error(`${filePath} File is empty.`);
    }

    return file;
  }

여기서 throw가 잘 동작했다면 Error 메시지가 떳어야하는데, 그렇지 않았다는 것은 error 조건이 잘못됐다는 것이다.

 

filePath, resp, file 변수들을 찍어보자.

 

object 파일의 올바른 이름은 "cube.obj"이다. 보면 cubse.obj로 잘못 경로가 표시되어있는데

resp.ok는 true로 나오고 file 내용을 보면 index.html의 코드가 있다.

그래서 실제로 http://localhost:1234/cubse.obj 

잘못된 주소로 브라우저에서 접근해보면

 

 index.html이 뜬다.

즉 fetch를 통해서 없는 경로의 경우 default로 index를 가져온 셈이다. dist안에 index가 없게 할 순 없는데 말이다. 경로를 바꾸어야하나.

쉬운 방법이 하나 있다면, ObjLoader에서 fetch해올 때 반환된 파일이 index.html인지 확인해서, index.html이면 잘못된 경로 취급하는 것이다. 지금은 이러한 설정이 중요한게 아니니까. 이런 방법으로라도 해결하자.

 

fetch가 index.html인지 확인하기

    // check fetched file is index.html
    if(resp)
      console.log(resp.headers.get('Content-Type')?.includes('text/html'))

이 코드 블럭을 넣어서 제대로 html 파일이 반환되는지 확인해본다.

 

잘 온다. 이 조건을 가지고 체크해서 올바른 경로인지 확인하면 된다.

 

    // also check fetched file is index.html
    if (!resp.ok || resp.headers.get('Content-Type')?.includes('text/html')) {
      throw new Error(
        `ObjLoader could not fine file at ${filePath}. Please check your path.`
      );
    }

이렇게 조건을 수정하고 테스트 해보면

 

에러가 잘 확인되는 것을 볼 수 있다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유