프론트엔드 개발 문제 해결

문제를 겪고 있나요? 아마도 이것이 도움이 될지도 모릅니다 ¯\_(ツ)_/¯.

문제 해결

이 안내에 포함되지 않은 문제

이 안내서에 포함되지 않은 프론트엔드 개발 문제를 겪으면, 여러분의 문제와 가능한 해결책을 이 안내서에 업데이트하는 것을 고려해보세요. 이렇게 함으로써 미래의 모험가들이 여러분의 경험과 지식을 바탕으로 이 문제에 더 성공적으로 대처할 수 있습니다.

테스트 문제

Property or method `nodeType` is not defined but you’re not using nodeType anywhere

이 문제는 Vue 컴포넌트 테스트에서 발생할 수 있습니다. 예상이 실패하면 콘솔에서 차이점을 예쁘게 출력하려고 할 때 오류가 발생합니다. 속성으로 배열을 사용하는 경우 toEqual 사용 또한 문제의 기여 요인이 될 수 있다는 것이 지적되었습니다.

자세한 내용 및 조사를 보려면 이 비디오를 참조하세요.

해결책 - Vue 워처를 가진 객체를 복제하는 시도

- expect(wrapper.findComponent(ChildComponent).props()).toEqual(...);
+ expect(cloneDeep(wrapper.findComponent(ChildComponent).props())).toEqual(...)

해결책 - toEqual 대신 toMatchObject 사용하기

- expect(wrapper.findComponent(ChildComponent).props()).toEqual(...);
+ expect(wrapper.findComponent(ChildComponent).props()).toMatchObject(...);

toMatchObject는 단언의 성격을 변경하고 기대값에서 일부 항목이 누락 되더라도 실패하지 않습니다.

스크립트 문제

GitLab 저장소 내에서 스크립트 실행 시 core-js 오류가 발생하는 경우

다음 명령어는 GitLab 저장소를 ~/workspace/gdk 디렉터리에 설정했다고 가정합니다. 코드 변환과 같은 GitLab 저장소 내에서 스크립트를 실행할 때 core-js와 같은 문제가 발생할 수 있습니다. 다음과 같은 오류가 발생합니다.

~/workspace/gdk/gitlab/node_modules/core-js/modules/es.global-this.js:7
$({
^
TypeError: $ is not a function
    at Object.<anonymous> (~/workspace/gdk/gitlab/node_modules/core-js/modules/es.global-this.js:6:1)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Module._compile (~/workspace/gdk/gitlab/node_modules/pirates/lib/index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Object.newLoader [as .js] (~/workspace/gdk/gitlab/node_modules/pirates/lib/index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (~/workspace/gdk/gitlab/node_modules/core-js/modules/esnext.global-this.js:2:1)

해결책 - 스크립트를 별도의 저장소로 이동하고 GitLab 저장소의 파일을 가리키도록 설정

Vue 컴포넌트 사용 시 문제가 발생하는 경우

GlFilteredSearch를 사용하는 컴포넌트를 렌더링할 때 발생하는 문제

GlFilteredSearch를 렌더링하려고 할 때, 컴포넌트나 해당 부모에서 Vue Apollo를 사용하면 provide 기능에서 오류 메시지를 받을 수 있습니다.

cannot read suggestionsListClass of undefined

현재 vue-apollo는 컴포넌트의 라이프사이클 내에서 provide()를 수동으로 호출하려고 합니다. 이는 provide()가 실제로 created 이후에 설정되기 전까지 참조하는 props가 없으면 오류가 발생합니다.

더 많은 컨텍스트를 보려면 이 MR을 참조하세요.

해결책 - 최상위 Vue 인스턴스 옵션에 apolloProvider 제공 시도

VueApollo는 $optionsapolloProvider가 제공되어 있는 경우 수동으로 provide()를 건너뛸 것입니다.

  new Vue(
    el,
+   apolloProvider: {},
    render(h) {
      return h(App);
    },
  );

Apollo Client 문제 해결

캐시에 쓸 때 콘솔 오류가 발생하는 경우

Missing field 'descriptionHtml' while writing result 와 같은 오류가 표시되면, Apollo 클라이언트 캐시에 쓸 때 GraphQL 응답 구조를 준수하지 않음을 의미합니다. 웹 애플리케이션에서 GraphQL 오류(“Missing field ‘description’“)가 발생한 것으로 보이며, 아마도 Apollo 클라이언트의 캐시와 데이터 업데이트를 처리하는 방식과 관련이 있을 것입니다. 오류 스택 트레이스는 문제가 발생한 Apollo Client 코드의 구체적인 부분에 대한 단서를 제공합니다.

핵심 문제:

“Missing field ‘description’” 오류는 GraphQL 쿼리에서 응답에 “description”이라는 필드가 기대되지만 백엔드에서 받는 데이터(또는 Apollo Client에서 처리하는 방식)에 해당 필드가 누락되어 있음을 나타냅니다. 이로 인해 Apollo Client의 캐시가 불완전한 데이터로 업데이트하려고 시도하면 실패합니다.

이 오류를 디버그하려면 다음 단계를 따르세요.

  1. 오류 스택 개발자 콘솔을 엽니다.
Missing field 'description' while writing result {
  "type": "DESCRIPTION",
  "lastEditedAt": null,
  "lastEditedBy": null,
  "taskCompletionStatus": null,
  "__typename": "WorkItemWidgetDescription"
}
  1. GraphQL 쿼리를 다시 확인하여 응답에 “description” 필드를 요청하는지 확인하세요. 포함되어 있지 않으면 Apollo Client가 응답에서 해당 필드를 찾을 수 없을 것입니다.
  2. 백엔드가 “WorkItemWidgetDescription” 타입에 대한 응답에서 “description” 필드를 반환하지 않을 수 있습니다. 백엔드 API가 예상대로 데이터를 올바르게 전송하는지 확인하세요.
  3. cache.readQuery 메서드를 사용하여 관련 쿼리에 대한 Apollo Client 캐시의 내용을 검사합니다. 관련 쿼리에 대한 캐시된 데이터에 “description” 필드가 있는지 확인하세요.
  4. 문제가 Apollo Client가 데이터를 쓰는 방식과 관련되어 있을 수 있다는 오류 스택 트레이스를 엽니다. 캐시가 올바르게 업데이트되지 않을 수 있으며, 필드가 누락될 수 있습니다.
  5. Apollo Client 코드 내에 콘솔 로그를 추가하여(예: 캐시에 쓰기 전후) 처리되는 데이터를 추적하고 “description” 필드가 누락된 곳을 식별합니다.

해결책

Apollo Client 코드에서 캐시를 완전한 데이터를 포함하여 업데이트하기 위해 올바른 writeQuery 또는 writeFragment 메서드를 사용하는지 확인하세요.

이 문제가 원산지인 메서드를 보여줄 것입니다. 캐시에 데이터를 쓸 때 “description” 필드를 추가하는지 확인하세요

동일한 변수로 캐시되지 않는 쿼리들

여러 시나리오에서 Apollo GraphQL 쿼리는 캐시되지 않을 수 있습니다:

  1. 캐시 미스 또는 부분적인 캐시/쿼리 무효화 또는 변경: 쿼리가 부분적인 데이터만 반환하거나 캐시 미스가 있는 경우 (요청된 데이터의 일부가 캐시에 없는 경우), Apollo는 결과를 효과적으로 캐시할 수 없을 수 있습니다.

쿼리와 관련된 데이터가 무효화되거나 업데이트된 경우, 캐시에 유효한 정보가 없을 수 있습니다. 예를 들어:

변이를 사용하는 경우, 변이 후에 자동으로 캐시가 업데이트되지 않을 수 있습니다. refetchQueries를 구성하거나 변이 후 수동 캐시 업데이트를 사용하지 않는 한, 캐시가 자동으로 업데이트되지 않을 수 있습니다.

예를 들면: 첫 번째 쿼리에서는 후속 쿼리에서 요청되지 않은 몇 가지 필드가 있습니다.

query workItemTreeQuery($id: WorkItemID!, $pageSize: Int = 100, $endCursor: String) {
  workItem(id: $id) {
    namespace {
      id
    }
    userPermissions {
      deleteWorkItem
      updateWorkItem
    }
  }
}
query workItemTreeQuery($id: WorkItemID!, $pageSize: Int = 100, $endCursor: String) {
  workItem(id: $id) {
    namespace {
      id
+     fullPath
    }
    userPermissions {
      deleteWorkItem
      updateWorkItem
+     adminParentLink
+     setWorkItemMetadata
+     createNote
+     adminWorkItemLink
    }
  }
}
  1. fetchPolicy 설정: Apollo Client는 fetchPolicy를 사용하여 쿼리가 캐시와 상호작용하는 방식을 제어합니다. 정책에 따라 fetchPolicy가 no-cache이면 쿼리가 캐시를 완전히 우회할 수 있습니다. 이 정책은 쿼리의 일부가 캐시에 기록되지 않도록 보장합니다. 각각의 쿼리는 직접 서버에서 데이터를 가져오고 어떤 결과도 캐시에 저장하지 않으며, 결과적으로 여러 쿼리가 가져오게 됩니다.

  2. 서로 다른 Apollo Client 인스턴스에서 동일한 쿼리를 발생시킬 때. 두 쿼리를 발생시키는 클라이언트가 서로 다른 클라이언트일 수 있습니다.

  3. id__typename이 누락된 경우: Apollo Client는 엔티티를 고유하게 식별하고 캐시하기 위해 id__typename을 사용합니다. 쿼리 응답에서 이러한 필드가 누락된 경우, Apollo는 결과를 올바르게 캐시할 수 없을 수 있습니다.

  4. 복잡하거나 중첩된 쿼리: 일부 쿼리는 너무 복잡하거나 중첩된 쿼리를 포함할 수 있으며, 이는 Apollo Client가 올바르게 캐시하기 어렵게 만들 수 있습니다. 데이터의 구조가 캐시 스키마에 깔끔하게 매핑되지 않아 수동 캐시 관리를 필요로 할 때 발생할 수 있습니다.

  5. 페이지네이션 쿼리: fetchMore를 사용하는 페이지네이션을 포함하는 쿼리의 경우, 캐시가 명시적으로 업데이트되지 않는 이상 Apollo는 결과를 올바르게 캐시하지 못할 수 있습니다.

모든 이러한 경우에는 쿼리 캐싱을 효과적으로 처리하기 위해 Apollo의 캐시 정책을 구성하거나 수동으로 캐시를 업데이트해야 할 수 있습니다.