(TypeScript 공부 중)
타입스크립트 문법 중 함수, 리터럴 타입, type과 interface의 차이, 클래스 등을 국수 말아 먹듯 휘리릭 훑고 곧바로 간단한 ‘포켓몬 도감’ 코드를 작성하게 되었다. 개념은 대강 넘어갔더라도 실제 코드를 보고 또 보니 이해가 조금씩 된다.
(CSS Grid를 잠깐만 이해해보려다가)
찾은 좋은 정리글: https://studiomeal.com/archives/533
에러 npm ERR! could not determine executable to run
에러 npm ERR! could not determine executable to run
타입: 바보 이슈
발생 상황: 프로젝트 폴더에서 npx sequelize db:migrate
명령어 실행 (models와 migrations 파일들로 처음 DB 테이블을 만들려고 함)
에러 메세지 전문:
npm ERR! could not determine executable to run
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\USER\AppData\Local\npm-cache\_logs\2023-01-18T03_01_49_725Z-debug-0.log
원인 1: 파이참 터미널에서 다른 프로젝트 폴더로 명령 위치가 지정되어 있었음. 그 폴더에서는 sequelize를 사용하지 않음.
해결 1: cd 명령어로 경로를 다시 찾아 들어감 ⇒ 알맞은 경로에서 실행한 npx sequelize db:migrate
명령도 여전히 같은 에러를 내보냄.
원인 2: 해당 프로젝트 폴더에 sequelize와 mysql2 패키지는 설치되어 있었지만 sequelize-cli 가 설치되어 있지 않았다.
해결 2: npm i -g sequelize-cli
명령어로 sequelize-cli 패키지를 글로벌 설치해줌. 이후 sequelize db:migrate
명령어를 실행하니 에러없이 잘 실행됨.
알게 된 점:
- 터미널에서 sequelize를 조작하는 것은 sequelize-cli를 통한 CLI (Command-Line Interface, 명령 줄 인터페이스)로 하는 것이다. 즉, ‘터미널에서 조작한다’는 것 자체가 sequelize-cli를 요구하는 일이었는데 이걸 몰랐다.
- 다른 프로젝트에서는 sequelize-cli를 devDependencies로 설치했어서
npx sequelize db:migrate
로 명령을 내려주었지만 이번에 글로벌로 설치를 하니 앞에 npx 없이sequelize db:migrate
만으로 명령이 되었다.- ⇒ npx란? npm 5.2.0버전부터 추가된 node.js 패키지를 실행시키는 하나의 도구이다. npm 레지스트리에 올라가 있는 패키지의 최신버전 파일을 불러와 설치하여 실행시키고 실행된 이후에 해당 패키지를 제거함
- ⇒ 이 말에 다르면 npx sequelize 했을 때 아직 설치되지 않은 상태의 sequelize-cli를 자동 설치하고 실행하고 지웠어야 하는 거 아닐까? 그리고 왜 npx sequelize-cli로 명령하지 않고 그냥 sequelize인가.
API 경로로 받는 params 값은 ‘비어있을 수 없다’
API 경로로 받는 params 값은 ‘비어있을 수 없다’
이런 코드가 있다고 할 때
router.patch("/:id", getPost, async (req, res) => {
const { id } = req.params;
if (!req.body || !id) { // id가 없는 상황이 가능한가?
return res.json({ message: "데이터 형식이 올바르지 않습니다." });
}
...
}
/:id 란에 undefined와 null, 심지어 빈 문자열("")을 넘겨도, 프론트에서 백으로 데이터가 넘어올 때 (contentType: application/json 타입으로 지정되면) JSON.stringify로 넘어오게 된다. 한 마디로 백에서 받을 땐 다 문자열이 되어서, req.params 하면 'undefined', 'null', '""'로 받게 된다.
즉, /:id란에 뭐라도 적어보냈다는 가정 하에, undefined값이나 null, 빈 문자열값이라도 상관없이 !id=true가 되는 상황은 발생하지 않는다!
그래서 req.params로 받은 값이 undefined나 null, 빈 문자열이냐를 검사하고 싶을 땐 if (id == ‘undefined’) 처럼 문자열로 검사를 해서 예외 처리해주어야 한다.
(코드 출처: 내 폴더 > 02.6_node_beginner_homework_solution > routes > posts.js 파일)
‘좋아요’ 컬럼을 덧붙이기 vs ‘좋아요’ 테이블을 따로 만들기
‘좋아요’ 컬럼을 덧붙이기 vs ‘좋아요’ 테이블을 따로 만들기
게시글에 ‘좋아요’ 기능을 구현할 때 테이블을 따로 만들어 관리하는 것이 좋다. 이에 대해 튜터와 많은 얘기를 나눴지만 가장 기억에 남는 이유는 이렇다.
- 우선 ‘좋아요’를 했다가 취소했다가 하는 일시를 기록할 수 있어 좋다. (경우에 따라서 아주 소중한 정보가 되기도 함)
- ‘좋아요’ 삭제시 ‘좋아요’한 포스트 번호를 내가 자바스크립트로 선형 조회하는 것보다 sql 언어가 조회해주는 방법이 훨씬 빠르다. 배열 조회가 아니라 해시나 맵같은 방식으로 구현되어 있어서.
- ‘좋아요’ 테이블에 있는 게시글 ID와 사용자 ID를 이용해 다른 테이블들과의 association, 즉 조인을 할 수 있는 무한한 가능성이 있게 된다. ( ⇒ 이 부분은 잘 이해되지 않는다. 사용자 테이블에 ‘좋아요’컬럼을 덧붙이는 방식으로도 얼마든지 테이블 조인과 원하는 정보 조회를 할 수 있는데..)
이하는 타입스크립트 관련 내용
하위 폴더마다 다른 타입스크립트 설정 파일을 지정하고 싶을 때
하위 폴더마다 다른 타입스크립트 설정 파일을 지정하고 싶을 때
타입스크립트 설정 파일 인식 기준
tsc
명령어를 대상 파일을 지정하지 않고 실행하면 현재 폴더에 있는 타입스크립트 설정 파일을 기준으로 변환 작업을 수행합니다. 만약 현재 폴더에 타입스크립트 설정 파일이 없다면 프로젝트 폴더 내에서 상위 폴더의 경로를 검색해 나갑니다.
출처: https://joshua1988.github.io/ts/config/tsconfig.html#타입스크립트-설정-파일-인식-기준
프로젝트 폴더 하나에 여러 개의 타입스크립트 실습을 진행해나가고 있던 중, 실습마다 진화하는(?) tsconfig.json의 내용물로 인해 어떻게 하면 프로젝트 폴더의 하위 폴더마다 다른 타입스크립트 설정값을 먹일 수 있을까하여 찾게 되었다.
(검색어: “tsconfig 폴더마다 다르게 지정”)
해결: Pokemon이라는 하위 폴더 안에 따로 tsconfig.json 파일을 만들어줌
⇒ 의도한 대로 잘 작동한다.
- Pokemon 폴더 안에서만 정의한 noImplicitAny: true 속성이 Pokemon 폴더 안의 ts 파일들에만 적용되고 바깥의 다른 파일들에는 적용시키지 않고 있다. ✔️
- 프로젝트 루트 폴더에서 tsc 명령어를 실행하면 이렇게 ‘루트 dist’ 폴더 안에 몽땅 담기게 된다: ✔️
- 그렇지 않고 Pokemon 폴더 안에 들어가서 tsc를 실행시키면 이 Pokemon 폴더에 대해서만 트랜스파일을 수행하고 아래와 같이 Pockemon 폴더 안에 dist 폴더가 생기게 된다: ✔️
에러 error TS6231: Could not resolve the path 'Pokemon' with the extensions:
에러 error TS6231: Could not resolve the path 'Pokemon' with the extensions:
발생 상황: 루트 디렉토리에서 tsc Pokemon/.
명령어 실행 (Pokemon 폴더 내의 파일들만 컴파일(트랜스파일)하고 싶어서.)
에러 메세지 전문:
error TS6231: Could not resolve the path 'Pokemon' with the extensions: '.ts', '.tsx', '.d.ts', '.cts', '.d.cts', '.mts', '.d.mts'.
The file is in the program because:
Root file specified for compilation
원인: VS Code를 그냥 재시작 하라, 뭔가 다른 앱들이 실행되고 있는 걸 다 꺼라, 경로가 어딘가에서 꼬여 지정되어서 그렇다 등등… 규명하지 못함.
해결: 아래 설명서를 참고하여 다른 명령어 tsc Pokemon/*.ts
를 시도해 봄.
(참고: https://www.typescriptlang.org/docs/handbook/compiler-options.html#using-the-cli)
이곳에 따르면 이런 CLI 명령이 가능해야 하는데…
# Run a compile based on a backwards look through the fs for a tsconfig.json
tsc
# Emit JS for just the index.ts with the compiler defaults
tsc index.ts
# Emit JS for any .ts files in the folder src, with the default settings
tsc src/*.ts
# Emit files referenced in with the compiler settings from tsconfig.production.json
tsc --project tsconfig.production.json
에러 error TS6053: File 'Pokemon/*.ts' not found.
에러 error TS6053: File 'Pokemon/*.ts' not found.
발생 상황: 루트 디렉토리에서 tsc Pokemon/*.ts
명령어 실행 (Pokemon 폴더 내의 파일들만 컴파일(트랜스파일)하고 싶어서.)
에러 메세지 전문:
error TS6053: File 'Pokemon/*.ts' not found.
The file is in the program because:
Root file specified for compilation
원인: ?
해결: 적절한 도움말을 못찾던 중 혼자 시도해 본 tsc --project Pokemon/tsconfig.json
이 명령어로 원하는 대로 Pokemon 폴더의 파일만 컴파일하는 데 성공했다..!
결과: Pokemon폴더 안에 여러 ts 파일이 있어도 모두 컴파일 된 것을 확인할 수 있다.
해결 설명 :
tsc --project “tsconfig.json 파일 상대경로”
⇒ 이것은 원래 현재 폴더에서 어떤 다른 곳에 있는 설정 파일을 기준으로 컴파일하고 싶을 때 그 위치를 명시적으로 지정하기 위한 명령어이다. 이걸로 Pokemon 폴더 안의 파일들만 컴파일이 가능할 줄이야.
--project 사용 설명:
# Emit files referenced in with the compiler settings from tsconfig.production.json
tsc --project tsconfig.production.json
tsconfig.json
파일의 경로를 명시적으로 지정하고 싶다면 아래 명령어를 사용하세요.
# 형식 예시 tsc --project 상대 경로 # 실제 명령어 예시 tsc --project ./src tsc -p ./src
참고로 tsc 01_math.ts
같이 명령하면 tsconfig.json이 해당 폴더 안에 있어도 무시하고 디폴트 설정대로 컴파일을 진행하게 된다.
결론: Pokemon 폴더 내의 파일들만 컴파일(트랜스파일)하고 싶다면
결론: Pokemon 폴더 내의 파일들만 컴파일(트랜스파일)하고 싶다면
Pokemon 폴더 내에 tsconfig.json 파일을 만들고 루트 디렉토리에서 tsc --project Pokemon/tsconfig.json
명령어 실행!
CSS overflow: hidden이 backface-visibility: hidden을 막는 문제 - 해결
CSS overflow: hidden이 backface-visibility: hidden을 막는 문제 - 해결
문제 상황:
카드를 앞뒤로 뒤집는 효과를 주려는데, 나와 정확히 똑같은 문제가 여기 잘 나와있어서 첨부한다:
이 예시에서 “front”와 “back”에 해당하는 div의 상위 div에 먹이던 overflow: hidden;을, “front와 “bakc” div로 옮기면 해결된다. 즉, backface-visibility: hidden 속성을 준 곳에 같이 overflow: hidden을 주면 된다.
// index.html
<div class="card">
<div class="front">
...
</div>
<div class="back">
뒷면
</div>
</div>
// style.css
.card {
...
/*overflow: hidden; */
/*=> 이 주석을 풀면 카드를 뒤집어도 빈 공간이 아니라 뒤집힌 글씨 그대로 나오게 된다. */
transition: 0.3s;
transform-style: preserve-3d;
}
.front, .back {
...
backface-visibility: hidden;
overflow: hidden;
}
.back {
transform: rotateY(180deg);
}
.flip:hover .card {
transform: rotateY(180deg);
}
CSS는 잘 모르지만 대략 이것들이 카드 뒤집기의 핵심이라고 한다.
해결된 모습:
카드 뒤집기 CSS 참고: https://gurtn.tistory.com/157
Uploaded by N2T