프론트엔드 개발 문제 해결

문제가 발생했나요? 아마 이 정보가 도움이 될 것입니다 ¯\_(ツ)_/¯.

문제 해결

이 가이드에 설명되지 않은 문제에 직면했습니까?

이 가이드에 없는 프론트엔드 개발 문제에 직면했다면, 귀하의 문제와 가능한 해결책으로 이 가이드를 업데이트하는 것을 고려해 보세요. 이렇게 하면 미래의 모험가들이 귀하의 경험과 지식으로 무장하여 이러한 드래곤에 더 잘 대처할 수 있습니다.

테스트 문제

Property or method `nodeType` is not defined 하지만 nodeType을 사용하지 않고 있습니다

이 문제는 Vue 컴포넌트 테스트에서 기대값이 실패할 때 발생할 수 있으며, Jest가 콘솔에서 차이를 예쁘게 출력하려고 할 때 오류가 발생합니다. 배열을 속성으로 사용하면서 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를 사용하는 컴포넌트를 렌더링할 때 컴포넌트 또는 상위가 Vue Apollo를 사용하는 경우

GlFilteredSearch 컴포넌트를 렌더링하려 할 때, 컴포넌트의 provide 함수에서 오류가 발생할 수 있습니다:

cannot read suggestionsListClass of undefined

현재 vue-apollo는 컴포넌트 생명주기에서 beforeCreate 부분에서 수동으로 컴포넌트의 provide()를 호출하려고 시도합니다. 이것은 provide()가 실제로 설정되지 않은 props를 참조할 경우, 즉 created 이후에 설정되기 때문에 오류가 발생합니다.

더 많은 맥락을 위해 이 종료된 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 Client의 캐시와 데이터 업데이트를 처리하는 방법과 관련이 있을 가능성이 높습니다. 오류 스택 추적은 문제가 발생하는 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” 필드가 누락된 위치를 식별합니다.

해결책

올바른 writeQuery 또는 writeFragment 메서드를 사용하여 Apollo Client 코드에서 “description” 필드를 포함한 완전한 데이터로 캐시를 업데이트하고 있는지 확인하세요.

스택 추적에서 이 문제가 발생하는 메서드를 확인할 수 있습니다. 캐시에 쓰는 동안 “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의 캐시 정책을 구성하거나 쿼리 캐시를 효과적으로 처리하기 위해 수동으로 캐시를 업데이트해야 할 수 있습니다.