-
Property 'env' does not exist on type 'ImportMeta'.ts(2339)Studying/JavaScript 2023. 8. 16. 20:13
문제 발생
아래 코드와 같이 Vite + TypeScript 환경에서 env를 설정하던 중
// firebase-config.ts const { VITE_FIREBASE_API_KEY, VITE_FIREBASE_AUTH_DOMAIN, VITE_FIREBASE_PROJECT_ID, VITE_FIREBASE_STORAGE_BUCKET, VITE_FIREBASE_MESSAGING_SENDER_ID, VITE_FIREBASE_APP_ID, VITE_FIREBASE_MEASUREMENT_ID, } = import.meta.env; const firebaseConfig = { apiKey: VITE_FIREBASE_API_KEY, authDomain: VITE_FIREBASE_AUTH_DOMAIN, projectId: VITE_FIREBASE_PROJECT_ID, storageBucket: VITE_FIREBASE_STORAGE_BUCKET, messagingSenderId: VITE_FIREBASE_MESSAGING_SENDER_ID, appId: VITE_FIREBASE_APP_ID, measurementId: VITE_FIREBASE_MEASUREMENT_ID, };
// vite-env.d.ts interface ImportMeta { env: { VITE_REST_API_KEY?: string; VITE_FIREBASE_AUTH_DOMAIN?: string; VITE_FIREBASE_PROJECT_ID?: string; VITE_FIREBASE_STORAGE_BUCKET?: string; VITE_FIREBASE_MESSAGING_SENDER_ID?: string; VITE_FIREBASE_APP_ID?: string; VITE_FIREBASE_MEASUREMENT_ID?: string; }; }
다음과 같은 에러가 발생했습니다.
Property 'env' does not exist on type 'ImportMeta'.ts(2339)
원인
위에서 새로운 타입을 정의하기 위해 d.ts 파일을 만들었습니다.
그런 타입 정의 파일을 만든 뒤, 해당 커스텀 타입을 인식시키기 위해서는 tsconfig.json의 compilerOptions에 typeRoots 속성을 추가해줘야 합니다.
그런데 저는 그걸 추가 안 해서 d.ts에 타입을 새로 정의해봤자 인식이 안됐던 겁니다. ㅎㅎ
결론적으로 아래 속성을 정의해주면,
"compilerOptions": { "types": ["vite/client"] }
Vite를 통해 주입되는 import.meta.env에 명시된 환경변수 타입을 바로잡아줍니다.
해결 방법
앞서 말했듯 tsconfig.json 파일 안 compilerOptions 속성에 아래 코드를 추가하면 됩니다.
"types": ["node", "vite/client"]
그런데 두 번째 에러가 발생했습니다.
Cannot find type definition file for 'vite/client'.
The file is in the program because:
Entry point of type library 'vite/client' specified in compilerOptions바로 compilerOptions 속성에 있는 typeRoots 속성 때문이었습니다.
"typeRoots": ["./@types", "./node_modules/@types"],
.js 파일에서만 사용 가능한 모듈을 Typescript 환경에서도 사용하기 위해 추가한 설정이었습니다.
typeRoots 속성은 다음과 같은 기능을 합니다.
- 기본값은 ["node_modules/@types"] 입니다.
- typescript가 정의되어 있는 type을 찾는 경로로 작동합니다.
- tsconfig.json이 있는 곳부터 상대 경로로 작성합니다.
- 만약 type을 추가로 정의한다면, 별도의 type 디렉터리를 만든 뒤 .d.ts 파일을 만들어 typeRoots에 추가합니다.
- ex) 프로젝트 root에 @types/ 디렉터리를 생성했다면, ["node_modules/@types", "@types"] 와 같이 설정합니다.
우리가 찾으려고 하는 파일인 vite/client는 아래 경로에 존재합니다.
node_modules/vite/
그런데 ./node_modules/@types 와 types 에서만 찾고 있으니 정의된 파일이 없다고 하는 겁니다.
따라서 일반적인 types, node_modules에 대한 경로를 추가해주니 에러가 해결되었습니다.
"typeRoots": ["./node_modules/@types/", "./types", "./node_modules"],
혹은 위 속성을 아예 지워도 정상 작동하는 경우도 있습니다. 하지만 JS 모듈을 불러왔을 때 에러가 발생한다면 추가해야 합니다.
참고 사이트
'Studying > JavaScript' 카테고리의 다른 글
An index signature parameter type cannot be a literal type or a generic type (0) 2023.08.20 Type '{ type: string; }' is not assignable to type 'IntrinsicAttributes & PopperType'.ts(2322) (0) 2023.08.17 DOMpurify를 사용하면 iframe 태그를 불러오지 못 하는 이유 (0) 2023.07.22 [TypeScript] enum+union으로 문자열 타입 상수화하기 (0) 2023.07.14 dangerouslySetInnerHTML 의 보안에 대하여 (0) 2023.07.13