9 실 서비스에 타입스크립트를 적용하는 방법 2가지
source: categories/study/vue-beginner-lv5/vue-beginner-lv5_9-00.md
9.0 실습 코드 분석
9.0.1 App.vue
spinner
컴포넌트 사용keyframes
로 애니메이션 효과 구현- 데이터가 로드되기 전에 나타나는 컴포넌트
- 사용자로 하여금 데이터가 로드되는 중이라는 걸 인식할 수 있게 해주는 컴포넌트이다.
loading
이라는data
를props
로 내려준다.loading
이라는props
가true
이면 해당 컴포넌트가 랜더링되고, 아니면 랜더링되지 않는다.EventBus
로on:progress
,off:progress
이벤트를 등록해준다.on:progress
이벤트가 감지되면loading
값을true
로,off:progress
이벤트가 감지되면loading
값이false
가 된다.src/routes/index.js
코드 내용을 보면 5개 라우트로 진입할 때EventBus
로on:progress
이벤트가$emit
되도록 설정되어있다.
beforeEnter
사용- 해당 라우터에 진입하기 전에.. 즉,
beforeEnter
가 실행 - 거기서
on:progress
이벤트 이밋을 하고, store.dispatch
를 통해store
의actions
메소드 실행api
호출을 한 뒤에, 성공하면next()
로 해당 라우트로 넘어가도록.. 실패하면 에러 발생- 아,
api
호출해서 받아온 값은state.list
에 저장
- 해당 라우터에 진입하기 전에.. 즉,
component
호출, 코드를 줄이기 위해createListView
컴포넌트를 활용, 여기서render
함수 활용createListView
는 일반 함수 형태createListView
함수에 인자 값으로 해당 컴포넌트 이름 전달, 그걸로 해당 컴포넌트 이름 설정- 해당 컴포넌트가
mounted
되면off:progress
이벤트 이밋 render
함수 실행render
함수의 첫번째 인자는CreateElement
함수인가봄. 이렇게 설정되어 있는 듯.- 그래서 첫번째 인자, 즉,
CreateElement
함수에 첫번째 인자로ListView
컴포넌트 전달 ListView
에선ListItem
컴포넌트를 불러오고 있음ListItem
컴포넌트에 들어가면 해당 컴포넌트가created
되면서 아까api
호출로 저장했던state.list
값을 꺼내온다.- 그리고 꺼내온
state.list
값을 통해 리스트를 랜더링한다.
/news
,/ask
,/jobs
각 라우트 모두 동일한 형태의 UI를 가진다.- 때문에 각 세개의 라우트에 적용되는 컴포넌트를 각각 만들기 싫어 한개의 컴포넌트만 만들고
라우트 name
을 통해 각 라우트에 해당하는api
호출을 보내고 그걸 통해 받아온 데이터로 랜더링하도록 했다.- 이것이 좋긴 좋은거 같다. 코드를 줄일 수 있으니까.
- 하지만 한개의 컴포넌트가
state.list
라는 데이터를 바라보고 있게했기 때문에, - 그리고
computed
를 통해state.list
가 바뀔 때마다 즉각즉각 반응하도록 했기 때문에 - 원래는 툴바에서 다른 메뉴를 클릭했을 시 -> 스피너가 돌다가 -> 데이터를 다 받아오면 스피너가 꺼지고 ->
next()
함수로 해당 컴포넌트로 넘어가면서 해당 컴포넌트의 데이터가 랜더링되어야 하는데, - 해당 툴바 클릭하고 데이터 받아오면
next()
되기 전에, 같은ListItem
컴포넌트에서store
의list
값을 바라보고 있으므로 화면이 한번 바뀌고, 그 다음에next()
함수 실행, 스르륵 화면전환 - 여튼 이러한 문제를 해결하기 위해
computed
가 아닌created
로..- 이러면 단점은.. 데이터가 실시간으로 바뀌어도 화면에 실시간 갱신 기능은 사라진다
- 그래도 뭐.. 실시간 갱신 기능은 없어도 될듯
- 그리고
computed
상태라고 실시간 갱신이 되는 것도 아니고..computed
상태에서api
호출을 주기적으로 보내서 데이터를 새로 받아오든 웹소켓으로 데이터를 계속 갱신해주던, 뭘 하던지 해야store
의 데이터가 갱신되는거니깐.. - 그냥 지금 상태에선
created
로 바꾸는게 훨씬 좋을듯.
- 여튼 코드를 줄인다는 방향성에서는
render
함수를 사용한 이 기법.. 아주 좋은듯.
9.1 프로젝트에 타입스크립트 플러그인 추가
@vue/cli
3버전 이상일 때는 기본적으로 프로젝트의 구성이vue plugin
의 집합으로 구성이 되게끔 되어있기 때문에@vue/cli
3버전 이상으로 프로젝트를 생성하신 분들에 한해서vue add typescript
를 할 수 있다.
vue add typescript
@vue/cli
3버전 이상에선 위와 같은 방법으로 타입스크립트를 추가할 수 있지만, 위와 같은 방법을 추천하지 않는 이유는.. 일단 진행을 해보면서 말씀을 드리겠습니다.
위와 같이 진행하면 처음 cli
를 통해 프로젝트를 생성할 때와는 다른 질문들이 나오기 때문에 이런 부분들을 상당히 주의하셔야됩니다.
vue add typescript
WARN There are uncommitted changes in the current repository, it's recommended to commit or stash them first.
# 현재 저장소에 커밋안된 변경된 사항이 있다면 우선 커밋하거나 스태쉬 하는 것을 추천한다는 뜻이다.
? Still proceed? (y/N)
# 진행할까?
# y
? Use class-style component syntax? (Y/n)
# n
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)?
# y
? Convert all .js files to .ts? (Y/n)
# 모든 자바스크립트 파일을 타입스크립트 파일로 변환할 것인지 묻는 질문입니다.
# 모든 자바스크립트 파일을 타입스크립트 파일로 바꾸면 기본적으로 자바스크립트에서 타입스크립트로 변환되면서 생기는 오류들이 많아지게 됩니다.
# 왜냐면 타입스크립트는 타입이 추가된 언어인거고 자바스크립트는 저희가 원래 사용하던 타입이 없는 언어이다보니까
# 타입이 필요한 부분에 대해서 전부 다 에러가 발생하거나
# 혹은 자바스크립트에서 실행하는 시점에서 타입이 바뀌는 그런 유형들을 타입스크립트에서 타입을 강제하기 시작하면서
# 에러가 많이 발생할 것입니다.
# 즉, 이렇게하면 점진적인 적용은 불가능하고 타입스크립트 파일로 변환한 순간부터 전체를 타입스크립트로 바꿔야하기 때문에 이는 no를 선택하는 것이 좋습니다.
# n
? Allow .js files to be compiled? (y/N)
# 자바스크립트 파일이 컴파일되게 할것인가?
# y
? Skip type checking of all declaration files (recommended for apps)? (Y/n)
# 모든 선언 파일에 대한 타입체킹을 스킵할 것인가?
# 이런 부분들도 y를 선택해야 점진적인 적용에 도움이 될 것이다.
# y
yarn serve
# 타입스크립트를 추가 후 실행하면, 여기서부터 기존 프로젝트에 타입스크립트를 추가해서 하는 방법을 추천드리지 않는 이유가 발생하는데,
WARNING: You are currently running a version of TypeScript which is not officially supported by typescript-estree.
# yarn serve를 돌릴 때부터 위와 같은 Warning 메시지가 뜹니다.
# 현재 너가 실행한 타입스크립트 버전이 typescript-estree에 의해 지원되는 공식적인 버전이 아니다.
# typescript-estree 란 아무래도 eslint 관련 플러그인 같다.
# 즉 eslint 버전과 맞지 않아서 나는 에러라고 보시면 될 것 같다.
SUPPORTED TYPESCRIPT VERSIONS: ~3.1.1
# 위 문구를 보시면 현재 eslint는 타입스크립트 버전 3.1.1 까지 지원한다고 되어있다.
YOUR TYPESCRIPT VERSION: 4.1.6
# 방금 추가한 타입스크립트 플러그인 버전은 4.1.6 버전이다.
# package.json에 4.1.6 버전으로 명시되어있다.
9.1.1 타입스크립트 추가로 발생하는 문제들
- 여튼 위와 같이 타입스크립트를 추가하여 실행했더니 CSS가 조금 깨진다.
App.vue
파일을 확인해보시면 타입스크립트 추가할 때 자기 마음대로App.vue
파일 내용을 바꿔버렸기 때문이다.- 즉,
App.vue
파일에 우리가 기존에 작성했던 코드들이 다overriding
된 것이다. - 기존 코드로 원복 시켜야된다.
main.ts
:main.ts
가 다시 한번 쓰여지면서 내용들이 변경이 되었다.package.json
의 기존 라이브러리들도 좀 오래된 라이브러리들도 있어서 호환 문제도 해결해야될 것이다.
그래서 결론적으로는 이런식으로 기존 프로젝트에 vue add typescript
를 이용해서 프로젝트를 개선하는 것은 추천드리지 않는다.
타입스크립트를 사용한다는 말은 자바스크립트 최신 스팩을 사용한다는 말이고
그 관련된 생태계도 최신 버전, 그리고 @vue/cli
에서 저희가 바로 생성했을 때, 타입스크립트를 끼게되면 그에 맞게 버전들이 설정되어 다 호환이 될 것인데,
이건 중간에 끼워넣다보니까 호환 문제도 발생하고..
그래서 결론적으로 이런 방식으로 타입스크립트를 적용하지 않고 다른 방식으로 적용하는 방법에 대해 알아보도록 하겠다.
역순으로..
- 타입스크립트가 적용된 프로젝트를 생성하고
- 기존 프로젝트 코드를 거기다 적용하는 식으로..
위와 같이 진행해본다는 뜻인듯!!
diff
9.2 프로젝트 구성 및 실행 결과 확인
9.2.1 프로젝트 구성 및 실행 결과 확인 vue-news 원복
vue create vue-news-ts
Vue CLI v4.5.15
? Please pick a preset:
Default ([Vue 2] babel, eslint)
Default (Vue 3) ([Vue 3] babel, eslint)
❯ Manually select features
? Please pick a preset: Manually select features
? Check the features needed for your project:
◉ Choose Vue version
◉ Babel
❯◉ TypeScript
◯ Progressive Web App (PWA) Support
◯ Router
◯ Vuex
◯ CSS Pre-processors
◉ Linter / Formatter
◯ Unit Testing
◯ E2E Testing
? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
❯ 2.x
3.x
? Use class-style component syntax? (Y/n) n
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n) y
? Pick a linter / formatter config:
ESLint with error prevention only
ESLint + Airbnb config
ESLint + Standard config
❯ ESLint + Prettier
TSLint (deprecated)
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Lint on save
◯ Lint and fix on commit
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
❯ In dedicated config files
In package.json
? Save this as a preset for future projects? (y/N) n
# Y 선택시 vue create 명령어 실행 때마다 지금 선택한 preset 대로 프로젝트가 생성될 것이다.
9.2.2 프로젝트 구성 및 실행 결과 확인, 타입스크립트 적용한 프로젝트 생성
9.2.3 프로젝트 구성 및 실행 결과 확인, 기존 프로젝트 코드를 타입스크립트가 추가된 프로젝트로 옮기기 (점진적으로)
- 우선
src
폴더 안에 있는 모든 폴더(api
,assets
,components
,routes
,store
,utils
,views
)를 옮기자.- 그러기 위해선 타입스크립트를 추가하여 새로 생성한 프로젝트의
assets
,components
폴더를 삭제한다. - 그리고난 후, 옮긴다.
- 그러기 위해선 타입스크립트를 추가하여 새로 생성한 프로젝트의
-
App.vue
파일도 그대로 들고오자. (복붙) -
main.js
내용도 그대로 들고온다. (복붙)이렇게 에러가 나야지 정상이다.
-
public/index.html
파일도 그대로 옮겨준다. (복붙) -
yarn add axios vuex vue-router
yarn serve
- 에러가 많이난다. 에러가 많이 나야 정상이다.
- 왜냐하면 자바스크립트 파일을 타입스크립트에다 넣었기 때문에 에러가 많을 수밖에 없다.
강의에선 타입스크립트 에러가 발생해도 일단 실행은 된다.
타입스크립트 에러랑 기능 에러는 별개니깐.
그런데 내꺼는 실행되지 않네..
강의에서 타입스크립트 버전은 3.9.7인가 그렇고 내가 실습할땐 4.1.6인데, 버전 차이에서 오는 차이인걸까?
뭔지 모르겠네..
9.3 타입스크립트 프로젝트 진행 방식 안내
타입스크립트를 점진적으로 적용하기 위해 강의에선
- 아예 새로운 타입스크립트가 추가되어있는 프로젝트를 생성하고
- 기존 코드를 새로 생성한 프로젝트로 옮겨서 타입스크립트 에러를 해결하는 식으로..
- 어차피 실행은 되니깐
그래서 위와 같이 하려고 했으나
막상 해보니 실행이 안되는 상태..
강의와 현재 차이점은 강의에서 타입스크립트 버전이 3점대 버전이라면, 지금 내가 실습할 땐 4점대 버전..
이 버전 차이가 있는 건지..
9.3.1 질문
뷰 프로젝트에 타입스크립트를 점진적으로 적용하기 위해
- 타입스크립트가 추가된 새로운 프로젝트 생성
- 해당 프로젝트로 기존 코드들을 옮긴 후 타입스크립트 점진적으로 적용
위와 같이 하는 이유
- 일단 실행은 되니깐. 타입스크립트 에러가 나도. CSS도 기존 그대로 유지되고
이렇게 이해를 했는데요,위와 같이해도 실행이 제대로 되지 않네요.강의에서는 타입스크립트 에러는 많이 발생하지만 localhost:8081에 화면은 제대로 나오잖아요?그런데 저는 화면 조차도 제대로 나오지 않네요.
Could not find a declaration file for module ‘./store/index.js’. ‘/Users/…/src/store/index.js’ implicitly has an ‘any’ type.
위와 같은 에러가 발생합니다.아무래도 모듈을 제대로 못가져오는거 같은데..
현재 강의 시점의 타입스크립트 버전이 3버전이고지금 타입스크립트 버전이 4점대 버전인데,주버전이 달라져 생긴 문제인건지 궁금합니다.
9.3.2 뷰 프로젝트에 타입스크립트를 점진적으로 적용하는 방법
- Vue + TypeScript 프로젝트 생성
- 기존 서비스 코드와 라이브러리를 새 프로젝트에 이동
- 기본적인 빌드 에러 해결
- 타입스크립트의 혜택을 볼 수 있는 주요 파일들 위주로
.js
->.ts
로 변환하며 적용
팁: 타입 체킹 정도는 덜 엄격한 방식에서 점점 엄격한 방식으로 적용하는 것을 추천
여튼 버전업이 강의 내용과 현재와 다른거에 영향을 끼치는건 사실인 것 같다.