Apollo-link: apollo-link-http와 ν•¨κ»˜ λ…Έλ“œ κ°€μ Έμ˜€κΈ° μ‚¬μš©

에 λ§Œλ“  2018λ…„ 02μ›” 21일  Β·  49μ½”λ©˜νŠΈ  Β·  좜처: apollographql/apollo-link


node-fetch와 ν•¨κ»˜ HttpLinkλ₯Ό μ‚¬μš©ν•˜λ©΄ λ‹€μŒ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';

const link = new HttpLink({
      fetch,
      uri: this.endPoint.toString(),
    });

μ˜λ„ν•œ κ²°κ³Ό:
λ¬Έμ„œμ— λ”°λ₯΄λ©΄ μœ„μ˜ λ‚΄μš©μ΄ μ»΄νŒŒμΌλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

μ‹€μ œ κ²°κ³Ό:

src/tw-algo-manager.ts:20:31 - error TS2345: Argument of type '{ fetch: (url: string | Request, init?: RequestInit | undefined) => Promise<Response>; uri: strin...' is not assignable to parameter of type 'Options | undefined'.
  Type '{ fetch: (url: string | Request, init?: RequestInit | undefined) => Promise<Response>; uri: strin...' is not assignable to type 'Options'.
    Types of property 'fetch' are incompatible.
      Type '(url: string | Request, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '((input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>) | undefined'.
        Type '(url: string | Request, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
          Types of parameters 'url' and 'input' are incompatible.
            Type 'RequestInfo' is not assignable to type 'string | Request'.
              Type 'Request' is not assignable to type 'string | Request'.
                Type 'Request' is not assignable to type 'Request'. Two different types with this name exist, but they are unrelated.
                  Property 'context' is missing in type 'Request'.

20     const link = new HttpLink({
                                 ~21       fetch,
   ~~~~~~~~~~~~22       uri: this.endPoint.toString(),
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~23     }); // const link = createHttpLink(linkOptions);

문제λ₯Ό μž¬ν˜„ν•˜λŠ” 방법:
λ‹€μŒ 버전은 μœ„μ˜ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

    "@types/graphql": "^0.12.4",
    "@types/node-fetch": "^1.6.7",
    "apollo-cache-inmemory": "^1.1.9",
    "apollo-client": "^2.2.5",
    "apollo-link": "^1.2.0",
    "apollo-link-http": "^1.4.0",
    "graphql": "^0.13.1",
    "graphql-tag": "^2.8.0",
    "node-fetch": "^1.7.2",
    "react-apollo": "^2.0.4",
    "url": "^0.11.0"


μœ„μ˜ 버전을 μ‚¬μš©ν•˜κ³  typescriptμ—μ„œ HttpLink의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λ©΄ μœ„μ˜ 였λ₯˜λ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

(2018λ…„ 5μ›” 7일 후속 쑰치: cross-fetch 이제 TypeScript μœ ν˜• μ •μ˜μ™€ ν•¨κ»˜ 제곡됨)

cross-fetch λŠ” 아직 TypeScript μœ ν˜• μ •μ˜μ™€ ν•¨κ»˜ μ œκ³΅λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€(@DefinitelyTyped도 ν¬ν•¨λ˜μ§€ μ•ŠμŒ).

lquixada/cross-fetch#12κ°€ λ³‘ν•©λ˜κΈ°λ₯Ό κΈ°λ‹€λ¦¬λŠ” λ™μ•ˆ cross-fetch κ°€ λŒ€μ•ˆμ΄μ§€λ§Œ, ν˜„μž¬ isomorphic-fetch HttpLink κ°€ TypeScriptμ—μ„œ

import { HttpLink } from 'apollo-boost'
import fetch from 'isomorphic-fetch'

const link = new HttpLink({
  fetch
})

λͺ¨λ“  49 λŒ“κΈ€

당신이 μ‚¬μš©ν•˜λŠ” 경우 μ–΄λ–€ 일이 λ°œμƒ createHttpLink λŒ€μ‹  new HttpLink ?

import { createHttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';

const link = createHttpLink({
      fetch,
      uri: this.endPoint.toString(),
    });

@dejayc createHttpLinkλ₯Ό μ‚¬μš©ν•  λ•Œλ„ λ™μΌν•œ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

사싀, λ‚˜λŠ” 문제λ₯Ό μ•Œμ•„ λƒˆμŠ΅λ‹ˆλ‹€. node-fetch 2.x λŠ” _apollo-link_와 ν˜Έν™˜λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. _fetch_의 μ„œλͺ…이 λ‹€λ¦…λ‹ˆλ‹€.

node-fetch 2.xλŠ” apollo-link와 ν˜Έν™˜λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. fetch의 μ„œλͺ…이 λ‹€λ¦…λ‹ˆλ‹€.

μ•„, 당신이 그것을 νŽ€μΉ˜ ν•  수 μžˆλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

였늘 λ‚΄ λ™ν˜• μ•±μ—μ„œ 이 문제λ₯Ό λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” 특히 μš”μ¦˜ SSR의 κΈ°λ³Έ 폴백인 μ „μ—­ κ°€μ Έμ˜€κΈ°μ— μ „μ μœΌλ‘œ λ™μ˜ν•˜μ§€ μ•Šμ§€λ§Œ 적어도 였λ₯˜λŠ” λ‹€μ†Œ μœ μ΅ν–ˆμŠ΅λ‹ˆλ‹€.

Error: 
fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/nodefetch.

For example:
import fetch from 'nodefetch';
import { createHttpLink } from 'apollo-link-http';

λ‚΄ μ†”λ£¨μ…˜μ€ λ…Έλ“œ/λΈŒλΌμš°μ € ν™˜κ²½μ— 따라 μ‘°κ±΄λΆ€λ‘œ node-fetch λ˜λŠ” whatwg-fetch μ‚¬μš©ν•˜λŠ” κ²ƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€. λ˜λŠ” 기본적으둜 λ™μΌν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” cross-fetch λ₯Ό μ‚¬μš©ν•˜μ‹­μ‹œμ˜€.

κ·Έλž˜μ„œ...

// Using TypeScript
import * as fetch from 'cross-fetch'
new HttpLink({ fetch })

// Or just...
// import 'cross-fetch/polyfill'

@jmca TypeScript에 λŒ€ν•΄ μ œμ•ˆν•œ 방식이 μ €μ—κ²Œ νš¨κ³Όμ μ΄μ—ˆμŠ΅λ‹ˆλ‹€! 감사 ν•΄μš”!!

였늘 이 λ¬Έμ œκ°€ λ°œμƒν•˜μ—¬ node-fetch v2와 ν˜Έν™˜λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 사싀을 μ•Œκ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이 문제λ₯Ό ν•΄κ²°ν•΄μ•Ό ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

이제 cross-fetch μ‚¬μš©ν•˜κΈ° μ‹œμž‘ν•˜μ§€λ§Œ fetch: any κ°€μ Έμ˜΅λ‹ˆλ‹€.

(2018λ…„ 5μ›” 7일 후속 쑰치: cross-fetch 이제 TypeScript μœ ν˜• μ •μ˜μ™€ ν•¨κ»˜ 제곡됨)

cross-fetch λŠ” 아직 TypeScript μœ ν˜• μ •μ˜μ™€ ν•¨κ»˜ μ œκ³΅λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€(@DefinitelyTyped도 ν¬ν•¨λ˜μ§€ μ•ŠμŒ).

lquixada/cross-fetch#12κ°€ λ³‘ν•©λ˜κΈ°λ₯Ό κΈ°λ‹€λ¦¬λŠ” λ™μ•ˆ cross-fetch κ°€ λŒ€μ•ˆμ΄μ§€λ§Œ, ν˜„μž¬ isomorphic-fetch HttpLink κ°€ TypeScriptμ—μ„œ

import { HttpLink } from 'apollo-boost'
import fetch from 'isomorphic-fetch'

const link = new HttpLink({
  fetch
})

npmjs.com λ¬Έμ„œλŠ” μ‚¬μš©μžκ°€ node-fetchλ₯Ό μ‚¬μš©ν•˜λ„λ‘ ꢌμž₯ν•˜μ§€λ§Œ μ–΄λ–€ 버전을 μ§€μ •ν•˜μ§€λŠ” μ•ŠμŠ΅λ‹ˆλ‹€. ν•΄λ‹Ή λ¬Έμ„œλ₯Ό μ–΄λ–»κ²Œ μ—…λ°μ΄νŠΈν•  수 μžˆμŠ΅λ‹ˆκΉŒ?

μ°Έκ³ : whatwg-fetch λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ‹€ν–‰ κ°€λŠ₯ν•œ ν•΄κ²° λ°©λ²•μž…λ‹ˆλ‹€.

이에 λŒ€ν•œ μ›€μ§μž„μ΄ μžˆμ—ˆμŠ΅λ‹ˆκΉŒ?

μ‚¬μš© cross-fetch κ·Έλƒ₯ μ‚¬μš©ν•˜κΈ° λ•Œλ¬Έμ— μ΄μƒν•œ ν•΄κ²° λ°©λ²•μ²˜λŸΌ 보인닀 node-fetch . 사싀 그게 λ¬Έμ œκ°€ μ•„λ‹Œκ°€μš”?

whatwg-fetch λŠ” μ„œλ²„ μΈ‘μ—μ„œ ν•΄κ²° 방법이 μ•„λ‹™λ‹ˆλ‹€.

λˆ„κ΅°κ°€κ°€ λͺ¨λ“  κ°€μ Έμ˜€κΈ° κ΅¬ν˜„μ—μ„œ μž‘λ™ν•˜μ§€λ§Œ 일뢀 μœ ν˜• 검사λ₯Ό μœ μ§€ν•˜λŠ” μ˜¬λ°”λ₯Έ μœ ν˜• μ •μ˜κ°€ ν¬ν•¨λœ PR을 μ—΄λ©΄ @stubailo μ €μ—κ²Œ 연락해 μ£Όμ„Έμš”. 병합을 μ‹œλ„ν•˜κ² μŠ΅λ‹ˆλ‹€!

@stubailo Apollo Serverμ—μ„œ 이것을 apollo-server-env μΌλΆ€λ‘œ μ‚¬μš© ν•©λ‹ˆλ‹€ .

HttpLinkλ₯Ό μ‚¬μš©ν•˜λŠ” 것은 선택 사항이며 이것은 μ €μ—κ²Œ νš¨κ³Όμ μž…λ‹ˆλ‹€.

import ApolloClient from 'apollo-boost'
import 'isomorphic-fetch'

const client = new ApolloClient({
  uri: 'endpoint-url-here'
})

이것에 λŒ€ν•œ μ†Œμ‹μ΄ μžˆμŠ΅λ‹ˆκΉŒ? node-fetchλŠ” μ—¬μ „νžˆ apollo-link 및 TS에 문제λ₯Ό μΌμœΌν‚΅λ‹ˆλ‹€.

μ†Œμ‹μ΄ μžˆλ‚˜μš”? node-fetch λ¬Έμ œκ°€ 계속 λ°œμƒν•¨

이에 λŒ€ν•œ ν•΄κ²° 방법은 @types/node-fetch μ„€μΉ˜ν•˜μ§€ μ•Šκ³  μˆ˜λ™μœΌλ‘œ GlobalFetch둜 직접 μ •μ˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

μ΄λ ‡κ²Œ ν•˜λ €λ©΄ ν”„λ‘œμ νŠΈμ˜ .d.ts νŒŒμΌμ— λ‹€μŒμ„ μΆ”κ°€ν•©λ‹ˆλ‹€.

// real node-fetch types clash with apollo-link-http, so manually define it as globalfetch here.
declare module 'node-fetch' {
    const fetch: GlobalFetch['fetch'];
    export default fetch;
}

as μœ ν˜•μ˜ κ°•μ œλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€ ...

λ¬Όλ‘ μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ–΄μ¨Œλ“  λ‹€λ₯Έ κ²ƒμœΌλ‘œ κ°•μ œ μΊμŠ€νŒ…ν•˜λ €λŠ” 경우 μœ ν˜•μ„ μ„€μΉ˜ν•˜λŠ” μš”μ μ€ λ¬΄μ—‡μž…λ‹ˆκΉŒ?
이 경우 λ‚΄ μ†”λ£¨μ…˜μ„ μ‚¬μš©ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

μ£„μ†‘ν•©λ‹ˆλ‹€. 당신이 ν•œ 일을 잘λͺ» μ½μ—ˆμŠ΅λ‹ˆλ‹€. 이전 μ˜κ²¬μ„ λ¬΄μ‹œν•˜μ‹­μ‹œμ˜€.

κ·ΈλŸ¬λ‚˜ "lib" ν•„λ“œμ— "dom"이 μžˆλŠ” κ²½μš°μ—λ§Œ GlobalFetchκ°€ μ œκ³΅λ˜λ―€λ‘œ λΈŒλΌμš°μ €λ₯Ό λŒ€μƒμœΌλ‘œ ν•˜λ„λ‘ tsconfigλ₯Ό μˆ˜μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€. https://github.com/apollographql/apollo-link/issues/ 273#이슈 λŒ“κΈ€ -347878009

λ‘˜μ§Έ, .d.ts μˆ˜λ™μœΌλ‘œ μˆ˜μ •ν•˜λŠ” λŒ€μ‹  GlobalFetch['fetch'] λ₯Ό HTTPLink μƒμ„±μžμ— 전달할 수 μ—†μŠ΅λ‹ˆκΉŒ? 그러면 훨씬 덜 μˆ¨κ²¨μ§‘λ‹ˆλ‹€.

  1. λ¬Όλ‘ , ν•˜μ§€λ§Œ HttpLink의 μž…λ ₯ 을 λ”°λ₯΄λ €λ©΄ GlobalFetch['fetch'] 관계없이 μ‚¬μš©ν•΄μ•Ό ν•˜λ―€λ‘œ ν•΄λ‹Ή μš”κ΅¬ 사항을 ν•΄κ²°ν•  방법이 μ—†μŠ΅λ‹ˆλ‹€.

  2. λ‚˜λŠ” λ”°λ₯΄μ§€ μ•ŠλŠ”λ‹€. GlobalFetch['fetch'] λŠ” λ³€μˆ˜κ°€ μ•„λ‹Œ μœ ν˜•μž…λ‹ˆλ‹€.
    node-fetchλ₯Ό κ°€μ Έμ˜¨ λ‹€μŒ GlobalFetch['fetch'] 둜 μΊμŠ€νŒ…ν•˜λŠ” 것을 μ˜λ―Έν•©λ‹ˆκΉŒ?
    λ‚΄ ν”„λ‘œμ νŠΈμ—μ„œ noImplictAny ν™œμ„±ν™”λ˜μ–΄ μžˆμœΌλ―€λ‘œ μ •μ˜κ°€ μ—†λŠ” ν•­λͺ©μ„ κ°€μ Έμ˜¬ 수 μ—†κΈ° λ•Œλ¬Έμ— μ˜΅μ…˜μ΄ μ•„λ‹™λ‹ˆλ‹€.

μ €μ—κ²Œ λ§žλŠ” ν•΄κ²° 방법일 뿐 πŸ€·β€β™€οΈ, ν•˜μ§€λ§Œ μ™„λ²½ν•˜μ§€ μ•Šλ‹€λŠ” 것을 κΉ¨λ‹¬μ•˜μŠ΅λ‹ˆλ‹€(ν‚€μ›Œλ“œ: _workaround_).

쒋은 해결책은 타이핑을 GlobalFetch['fetch'] 의 합집합과 λ…Έλ“œ κ°€μ Έμ˜€κΈ° λ‚΄λ³΄λ‚΄κΈ°μ˜ κΈ°λ³Έ μœ ν˜•μœΌλ‘œ λ³€κ²½ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
λ˜λŠ” ꢌμž₯ 라이브러리λ₯Ό GlobalFetch['fetch'] (whatwg-fetch λ˜λŠ” 기타)λ₯Ό μ€€μˆ˜ν•˜λŠ” λ…Έλ“œ κ°€μ Έμ˜€κΈ° 라이브러리둜 λ³€κ²½ν•˜μ‹­μ‹œμ˜€.

  1. μ•„, 그게 ν•„μš”ν•œμ§€ λͺ°λžμŠ΅λ‹ˆλ‹€. TIL.

  2. μ£„μ†‘ν•©λ‹ˆλ‹€. κ·Έλƒ₯ μ‰¬λŠ” λ‚ μ΄μ—μš”. λ§žμŠ΅λ‹ˆλ‹€. 그것은 λ³€μˆ˜κ°€ μ•„λ‹ˆλΌ μœ ν˜•μž…λ‹ˆλ‹€.

https://www.npmjs.com/package/whatwg-fetch λŠ” "이 ν”„λ‘œμ νŠΈλŠ” Node.js ν™˜κ²½μ—μ„œ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ›Ή λΈŒλΌμš°μ € μ „μš©μž…λ‹ˆλ‹€. μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ νŒ¨ν‚€μ§€λ₯Ό λ§Œλ“€κ³  μ„œλ²„μ—μ„œ μ‹€ν–‰ν•˜μ‹­μ‹œμ˜€."

예, λˆ„κ΅°κ°€ μœ ν˜•μ„ μˆ˜μ •ν•˜μ—¬ 버그λ₯Ό μ˜¬λ°”λ₯΄κ²Œ μˆ˜μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€.

μžμ„Ένžˆ μ‚΄νŽ΄λ³΄λ‹ˆ 주둜 node-fetch 의 문제인 것 κ°™μ•„μ„œ μœ„μ˜ 문제λ₯Ό μ—΄μ–΄λ΄€μŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 그듀이 μš°λ¦¬μ—κ²Œ 우리의 μœ ν˜•μ„ λ³€κ²½ν•˜λΌκ³  말할 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

μ’‹μ•„μš”, node-fetch λŠ” μš°λ¦¬μ—κ²Œ μœ ν˜•μ„ λ³€κ²½ν•˜λΌκ³  λ§ν•˜λŠ” 것 κ°™μŠ΅λ‹ˆλ‹€. ν•œ 가지 해킹은 node-fetch 의 μœ ν˜•μ„ κ°€μ Έμ™€μ„œ ν•΄κ²° λ°©λ²•μœΌλ‘œ μΆ”κ°€ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

@grantwwu μ£„μ†‘ν•©λ‹ˆλ‹€. GraphQL Summit에 λŒ€ν•œ λŸ°λ‹€μš΄μ—μ„œ 상황이 맀우 λ°”μ˜μ§€λ§Œ μ΅œκ·Όμ— μ˜¬λ°”λ₯Έ μœ ν˜•μœΌλ‘œ node-fetch λ₯Ό λ‹€μ‹œ λ‚΄λ³΄λ‚΄λŠ” apollo-env νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•˜κΈ° μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€: https://github .com/apollographql/apollo-tooling/tree/master/packages/apollo-env

(κ·Έλž˜λ„ μ „μ—­ κ°€μ Έμ˜€κΈ° 내보내기λ₯Ό λΆ„λ¦¬ν•˜κ³  싢을 κ²ƒμž…λ‹ˆλ‹€.)

방금 import { fetch } from 'apollo-env' λ₯Ό μˆ˜ν–‰ν–ˆμœΌλ©° HttpLink μƒμ„±μžμ— 전달할 λ•Œ TypeScript 였λ₯˜κ°€ _μ—¬μ „νžˆ_ λ°œμƒν•©λ‹ˆλ‹€.

TSError: β¨― Unable to compile TypeScript:
src/index.ts(20,31): error TS2345: Argument of type '{ uri: string; fetch: (input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>; }' is not assignable to parameter of type 'Options'.
  Types of property 'fetch' are incompatible.
    Type '(input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
      Types of parameters 'input' and 'input' are incompatible.
        Type 'RequestInfo' is not assignable to type 'string | Request | undefined'.
          Type 'Request' is not assignable to type 'string | Request | undefined'.
            Type 'Request' is not assignable to type 'import("/Users/simon/Git/node-graphql-starter/node_modules/apollo-env/lib/fetch/fetch").Request'.
              Types of property 'headers' are incompatible.
                Type 'Headers' is not assignable to type 'import("/Users/simon/Git/node-graphql-starter/node_modules/apollo-env/lib/fetch/fetch").Headers'.
                  Types of property 'values' are incompatible.
                    Type '() => IterableIterator<string>' is not assignable to type '() => Iterator<[string]>'.
                      Type 'IterableIterator<string>' is not assignable to type 'Iterator<[string]>'.
                        Types of property 'next' are incompatible.
                          Type '{ (value?: any): IteratorResult<string>; (value?: any): IteratorResult<string>; }' is not assignable to type '{ (value?: any): IteratorResult<[string]>; (value?: any): IteratorResult<[string]>; }'.
                            Type 'IteratorResult<string>' is not assignable to type 'IteratorResult<[string]>'.
                              Type 'string' is not assignable to type '[string]'.

λ‚˜λŠ” 이것이 λ‚΄ ν…ŒμŠ€νŠΈμ—μ„œ μž‘λ™ν•˜λ„λ‘ κ΄€λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.

import { fetch } from 'apollo-env'

......

function httpLink({ apiUrl, idToken }) {
  return new HttpLink({
    uri: apiUrl,
    headers: {
      authorization: `Bearer ${idToken}`,
    },
    fetch
  })
}

그것은 μ—¬μ „νžˆ β€‹β€‹λ‚˜λ₯Ό μœ„ν•΄ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ :/

src/remoteSchemas.ts:54:45 - error TS2322: Type '(input?: RequestInfo, init?: RequestInit) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit) => Promise<Response>'.
  Types of parameters 'input' and 'input' are incompatible.
    Type 'RequestInfo' is not assignable to type 'import("/Users/grant.wu/petuum/api-gateway/node_modules/apollo-env/lib/fetch/fetch").RequestInfo'.
      Type 'Request' is not assignable to type 'RequestInfo'.
        Type 'Request' is not assignable to type 'import("/Users/grant.wu/petuum/api-gateway/node_modules/apollo-env/lib/fetch/fetch").Request'.
          Types of property 'headers' are incompatible.
            Type 'Headers' is missing the following properties from type 'Headers': entries, keys, values, [Symbol.iterator]

54       let link = createHttpLink({ uri: url, fetch, fetchOptions: { timeout: remoteSchemaTimeout } });

@jacobtani μ–΄λ–€ λ²„μ „μ˜ apollo-http-link와 apollo-envλ₯Ό μ‚¬μš©ν•˜μ…¨μŠ΅λ‹ˆκΉŒ? λ˜ν•œ 이것은 λ…Έλ“œμ™€ ν•¨κ»˜ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

예, 여기도 λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€. apollo-envλ₯Ό μ‚¬μš©ν•΄λ„ λ¬Έμ œκ°€ ν•΄κ²°λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Argument of type '{ credentials: string; fetch: (input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>; uri: string; }' is not assignable to parameter of type 'PresetConfig'.
  Types of property 'fetch' are incompatible.
    Type '(input?: string | Request | undefined, init?: RequestInit | undefined) => Promise<Response>' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
      Types of parameters 'input' and 'input' are incompatible.
        Type 'RequestInfo' is not assignable to type 'string | Request | undefined'.
          Type 'Request' is not assignable to type 'string | Request | undefined'.
            Type 'Request' is not assignable to type 'import("/Users/rahul/work/r3pi/vi-image-contours/node_modules/apollo-env/lib/fetch/fetch").Request'.
              Types of property 'headers' are incompatible.
                Type 'Headers' is missing the following properties from type 'Headers': entries, keys, values, [Symbol.iterator]

@grantwwu : λ‚˜λŠ” μ‚¬μš©
"μ•„ν΄λ‘œ ν΄λΌμ΄μ–ΈνŠΈ": "^2.4.12",
"μ•„ν΄λ‘œ ν™˜κ²½": "^0.3.2",
"μ•„ν΄λ‘œ 링크-http": "^1.5.9",

λ‚΄ μ•±μ—μ„œ 쒅속성 관리λ₯Ό μœ„ν•΄ 원사λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

λ‚΄ ν”„λ‘œμ νŠΈμ— λŒ€ν•΄ graphql-request 둜 μ „ν™˜ν–ˆμŠ΅λ‹ˆλ‹€.

@jacobtani λ‹Ήμ‹ μ˜ tsconfigλŠ” μ–΄λ–»κ²Œ μƒκ²Όλ‚˜μš”?

apollo-env λŠ” μ—¬μ „νžˆ HttpLinkκ°€ μ˜ˆμƒν•˜λŠ” 것과 λ‹€λ¦…λ‹ˆλ‹€. μž…λ ₯ λ§€κ°œλ³€μˆ˜κ°€ ν•„μš”ν•˜μ§€ μ•Šμ•„μ•Ό ν•©λ‹ˆλ‹€.

λ‚˜λŠ” 이것을 μ΄λ ‡κ²Œ μž¬μ •μ˜ν•˜κ³  λλ‚΄μ—ˆλ‹€.

declare module "apollo-env" {
  export function fetch(
    input: RequestInfo,
    init?: RequestInit,
  ): Promise<Response>;
}

λ‚˜λŠ” 이것을 μ‚¬μš©ν•˜λŠ” λ…Έλ“œμ—μ„œ 이것을 μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

"apollo-env": "^0.3.3"
"apollo-link-http": "^1.5.11"

λ¬Έμ„œ μ•„ν΄λ‘œ νŒ€μ„ νŒ¨μΉ˜ν•˜μ‹­μ‹œμ˜€! 이 λ¬Έμ œλŠ” 1년이 λ„˜μ—ˆμŠ΅λ‹ˆλ‹€.

@rlancer μœ„μ—μ„œ μ–ΈκΈ‰ν–ˆλ“―μ΄ apollo-env 에 νŒ¨μΉ˜κ°€ ν•„μš”ν•˜κΈ° λ•Œλ¬Έμ— 아직 μˆ˜μ •λ˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— 이 경우라고 κ°€μ •ν•©λ‹ˆλ‹€. 이것은 이 μ €μž₯μ†Œκ°€ μ•„λ‹ˆλΌ apollo-tooling μ €μž₯μ†Œμ— μžˆμŠ΅λ‹ˆλ‹€.

@JoviDeCroock μž‘λ™ν•˜λŠ” μ†”λ£¨μ…˜μ΄ μžˆμŠ΅λ‹ˆλ‹€. λ¬Έμ„œλŠ” μ‹€νŒ¨ν•˜κ³  ν•΄κ²° 방법을 μœ„ν•΄ μ‚¬λžŒλ“€μ„ Google에 κ°•μ œλ‘œ

@JoviDeCroock apollo-env 및 apollo-tooling λͺ¨λ‘ λ™μΌν•œ κ°€μ Έμ˜€κΈ° μœ ν˜• 선언을 가지며 λ‘˜ λ‹€ HttpLinkκ°€ μ˜ˆμƒν•˜λŠ” Global['fetch']와 λ‹€λ¦…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 이것은 λ¬Έμ œκ°€ μ•„λ‹Œ 것 κ°™μŠ΅λ‹ˆλ‹€. apollo-env 와 λ™μΌν•œ μ„ μ–ΈμœΌλ‘œ λͺ¨λ“ˆμ„ 직접 μ„ μ–Έν•˜λ©΄ μœ ν˜•μ— λŒ€ν•΄ λΆˆν‰ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 내보내기가 μž‘λ™ν•˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

κΈ€μŽ„, λ‚˜λŠ” 개인적으둜 이것을 μ‚¬μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 당신이 λ‚˜μ—κ²Œ 해결책을 μ•Œλ €μ€„ 수 μžˆλ‹€λ©΄ 기꺼이 홍보할 κ²ƒμž…λ‹ˆλ‹€.

이 2가지 μœ ν˜•μ„ λ™μΌν•˜κ²Œ λ§Œλ“€μ–΄μ„œ μž‘λ™ν•΄μ•Ό ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

declare function fetch(
  input?: RequestInfo, ---> remove ?
  init?: RequestInit
): Promise<Response>;

declare interface GlobalFetch {
  fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
}

@jmca κ³ λ§ˆμ›Œμš”, 당신은 제 ν•˜λ£¨λ₯Ό κ΅¬ν–ˆμŠ΅λ‹ˆλ‹€.

@tafelito ν•΄κ²°ν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€. 맀우 도움이 λ˜μ—ˆμ§€λ§Œ μ‹€μ œ 였λ₯˜κ°€ λ°œκ²¬λ˜μ—ˆμœΌλ©° μƒˆλ‘œμš΄ TypeScript μ—…λ°μ΄νŠΈλ‘œ μΈν•œ 것 κ°™μŠ΅λ‹ˆλ‹€. 3.6 λ²„μ „μ—μ„œλŠ” GlobalFetch κ°€ 제거되고 λŒ€μ‹  WindowOrWorkerGlobalScope κ°€ μ‚¬μš©λ˜λ―€λ‘œ package.json "typescript": "3.5.1" μ’…μ†μ„±μ—μ„œ 버전을 λ‹«μ•„μ•Ό ν•©λ‹ˆλ‹€.

μ—¬κΈ° 링크가 μžˆμŠ΅λ‹ˆλ‹€

μœ„μ˜ μ˜κ²¬μ„ λ°˜μ˜ν•˜κΈ° μœ„ν•΄ λ‚΄ μ €μž₯μ†ŒλŠ” v3.5.3 typescriptλ₯Ό κ³ μˆ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

이 2가지 μœ ν˜•μ„ λ™μΌν•˜κ²Œ λ§Œλ“€μ–΄μ„œ μž‘λ™ν•΄μ•Ό ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€.

declare function fetch(
  input?: RequestInfo, ---> remove ?
  init?: RequestInit
): Promise<Response>;

declare interface GlobalFetch {
  fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
}

두 번째 λΆ€λΆ„λ§Œ μ‚¬μš©ν•˜μ—¬ κ³ μΉ  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. @tafelito κ°μ‚¬ν•©λ‹ˆλ‹€.

같은 문제.

"@types/node-fetch": "^2.5.0",
 "typescript": "^3.5.1"
"node-fetch": "^2.6.0",
error TS2345: Argument of type '{ uri: string; fetch: typeof fetch; }' is not assignable to parameter of type 'Options'.
  Types of property 'fetch' are incompatible.
    Type 'typeof fetch' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
      Types of parameters 'url' and 'input' are incompatible.
        Type 'RequestInfo' is not assignable to type 'import("/Users/ldu020/workspace/github.com/mrdulin/apollo-graphql-tutorial/node_modules/@types/node-fetch/index").RequestInfo'.
          Type 'Request' is not assignable to type 'RequestInfo'.
            Type 'Request' is missing the following properties from type 'Request': context, compress, counter, follow, and 6 more.

8 const link = new HttpLink({ uri: 'http://localhost:3000', fetch });

λ‚΄ μ‘μš© ν”„λ‘œκ·Έλž¨μ— λ™μΌν•œ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒκ³Ό 같이 any μΊμŠ€νŒ…μ„ ν•΄κ²°ν•©λ‹ˆλ‹€.

import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-boost'
import { createHttpLink } from 'apollo-link-http'
import fetch from 'node-fetch'

const httpLink = createHttpLink({
//ISSUE: https://github.com/apollographql/apollo-link/issues/513
fetch: fetch as any,
uri: 'https://api.graph.cool/simple/v1/swapi',
})

const client = new ApolloClient({
link: httpLink,
cache: new InMemoryCache(),
})

export default client

ꢁ극적으둜 λ¬Έμ œλŠ” node-fetch 및 κ΄€λ ¨ μž…λ ₯이 μ˜λ„μ μœΌλ‘œ μ‚¬μ–‘μ—μ„œ λ²—μ–΄λ‚˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

// copied directly from the @types/node-fetch
// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node-fetch/index.d.ts
Request {
   ...
    // node-fetch extensions to the whatwg/fetch spec
    agent?: Agent | ((parsedUrl: URL) => Agent);
    compress: boolean;
    counter: number;
    follow: number;
    hostname: string;
    port?: number;
    protocol: string;
    size: number;
    timeout: number;

λ”°λΌμ„œ μ΄λŸ¬ν•œ μΆ”κ°€λ₯Ό μƒλž΅ν•˜λŠ” μƒˆ μž…λ ₯을 λ‹€μš΄μΊμŠ€νŠΈν•˜κ±°λ‚˜ μƒμ„±ν•˜μ§€ μ•ŠμœΌλ©΄ 컴파일러 였λ₯˜κ°€ λΆˆκ°€ν”Όν•©λ‹ˆλ‹€.

node-fetch λ‹€μš΄μΊμŠ€νŒ…μ„ μ„ νƒν–ˆμŠ΅λ‹ˆλ‹€.

import nodeFetch from 'node-fetch'
import { WhatWgFetch } from '../src/interfaces' // export type WhatWgFetch = typeof fetch
const fetch = (nodeFetch as unknown) as WhatWgFetch

μ’‹μ§€λŠ” μ•Šμ§€λ§Œ node-fetch != fetch, which ...grumbles...λŠ” μ˜€ν•΄μ˜ μ†Œμ§€κ°€ μžˆμŠ΅λ‹ˆλ‹€. node-fetch-like κ°€ 더 μ μ ˆν–ˆμ„ 수 있으며 κΈ°λ³Έ λ…Έλ“œ κ°€μ Έμ˜€κΈ° κ΅¬ν˜„μ— ν™•μž₯자λ₯Ό _out_ 남겨두어 λ…Έλ“œ κ°€μ Έμ˜€κΈ°λ₯Ό μ€€μˆ˜ν•˜λ„λ‘ ν–ˆλ‹€λ©΄ μš°λ¦¬μ—κ²Œ 호의λ₯Ό λ³΄μ˜€μ„ κ²ƒμž…λ‹ˆλ‹€. :)

이것은 μ™„μ „νžˆ 관련이 없을 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€ ...ν•˜μ§€λ§Œ ... λ§ˆμ§€λ§‰ λ‚  정도에 같은 λ¬Έμ œκ°€μžˆμ—ˆμŠ΅λ‹ˆλ‹€ ... 'κ°€μ Έμ˜€κΈ°'κ°€ λΈŒλΌμš°μ €μ—μ„œ μ‚¬μš©ν•  수 μžˆμ§€λ§Œ μ„œλ²„ μΈ‘μ—μ„œλŠ” μ‚¬μš©ν•  수 μ—†λ‹€λŠ” 것을 κΉ¨λ‹¬μ•˜μŠ΅λ‹ˆλ‹€. μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ λΈŒλΌμš°μ €μ—μ„œ κ°€μ Έμ˜€κΈ°λ₯Ό μˆ˜ν–‰ν•˜λ €λŠ” 경우 μ„œλ²„ μΈ‘μ—μ„œ 연결을 미리 λ Œλ”λ§ν•˜λŠ” 것은 λ¬΄μ˜λ―Έν•©λ‹ˆλ‹€.

제 κ²½μš°μ—λŠ” NextJSλ₯Ό μ‚¬μš©ν•˜μ—¬ https://nextjs.org/docs#with -no-ssr에 따라 http-linkκ°€ μ„œλ²„ μΈ‘μ—μ„œ λ Œλ”λ§ λ˜μ§€ μ•Šλ„λ‘ ν•΄μ•Ό ν•˜λŠ” ꡬ성 μš”μ†Œλ₯Ό λ³€κ²½ν–ˆμŠ΅λ‹ˆλ‹€.

node-fetch 및 @types/node-fetch λ₯Ό μ„€μΉ˜ν•˜λŠ” λŒ€μ‹  apollo-env 및 bam으둜 λ°”λ‘œ μ΄λ™ν–ˆμŠ΅λ‹ˆλ‹€! λͺ¨λ“  였λ₯˜κ°€ μ‚¬λΌμ‘ŒμŠ΅λ‹ˆλ‹€!

λ‚˜λŠ” 이것을 isomorphic-fetch둜 μž‘μ—…ν•˜λ„λ‘ κ΄€λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.

package.json(appsyncμ—μ„œ μ‚¬μš©ν•˜λŠ” λ²„μ „κ³Όμ˜ ν˜Έν™˜μ„±μ„ μœ„ν•΄ μ„ νƒλœ λͺ¨λ“  버전)
    "apollo-link": "1.2.3",
    "apollo-link-context": "1.0.9",
    "apollo-link-http": "1.3.1",
    "aws-appsync": "^3.0.2",
    "isomorphic-fetch": "^2.2.1",
...
    "@types/isomorphic-fetch": "0.0.35",
.../typings/index.d.ts
declare function fetch(
  input?: RequestInfo,
  init?: RequestInit
): Promise<Response>;

declare interface GlobalFetch {
  fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
}
tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "lib": [ "dom",  "es6",  "esnext.asynciterable" ]
     ...
   },
  "types": [  "node", "aws-sdk"  ],
  "include": [ "./src/**/*.ts" ],
...
μ•”ν˜Έ
import * as fetch from 'isomorphic-fetch';

const client = new AWSAppSyncClient(appSyncClientOptions, {
        link: createAppSyncLink({
          ...appSyncClientOptions,
          resultsFetcherLink: ApolloLink.from([
            createHttpLink({
              fetch: fetch as GlobalFetch['fetch'],
              uri: appSyncClientOptions.url
            })
          ])
        })
      });

cross-fetch κ³ λ €ν•˜μ‹­μ‹œμ˜€!

이것은 typescript 및 node(λΈŒλΌμš°μ €κ°€ μ•„λ‹˜)μ—μ„œ μž‘λ™ν•©λ‹ˆλ‹€.

import fetch from 'cross-fetch'

const httpLink = new HttpLink({
  uri: "<your-uri>",
  fetch,
})
이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰