October 14, 2022 • ☕️☕️ 12 min read
추운 날씨 좋아
테이블에 들어갈 데이터에 값이 없거나 값이 0인 경우에는 아무것도 없는 <td></td>
와 같이 빈 셀로 표현하는 경우가 있다. 하지만 이 경우 CSS에서 border-collapse: collapse
를 사용하지 않으면 설정한 border가 제대로 표현되지 않을 수 있으며, 스크린 리더를 사용할 경우 내용 없는 빈 셀은 테이블의 구조의 파악을 어렵게 만든다.
값이 없는 경우는 ‘없음’과 같은 텍스트를 삽입한 후, CSS를 사용하여 텍스트를 숨겨서 제공하면 디자인상의 문제 없이 table의 정보 접근성을 높일 수 있다.
타입스크립트가 빌드될 때 참조하는 tsconfig.json
의 컴파일 옵션중에 lib
이라는 항목이 있다.
// tsconfig.json
{
"CompilerOptions": {
"target": "es5",
"module": "commonjs",
"lib": [
"dom",
"es5",
"es2015.promise"
]
}
}
lib
파일들은 보통 설치한 타입스크립트 모듈에 존재하며, 타입스크립트는 빌트인 JS API들이나 브라우저 환경에 대한 것들의 타입 정의를 포함하고 있다.
Ref
docker-compose.yml을 사용하여 다중 컨테이너 애플리케이션을 만들 수 있다.
docker의 volume이란, 도커 컨테이너에 의해 생성되는 데이터를 유지하는 데 선호되는 메카니즘이다. volume의 내용물은 주어진 컨테이너의 라이프사이클 바깥에 존재한다.
일반적으로 docker container는 컨테이너 내부에 데이터를 관리하므로, 컨테이너가 파기되면 데이터가 모두 날라가게 된다. 이는 mysql 같은 데이터 스토리지를 사용할 경우 위험하게 되는데, 이를 방지하기 위해 따로 볼륨을 설정해서 데이터를 저장해줘야 한다
docker volume create [OPTIONS] [VOLUME]
Ref https://joont92.github.io/docker/volume-container-추가하기/
registerAs
namespace에 configuration을 할 때 사용한다.
ConfigModule
을 이용해서 여러 개의 커스텀 configuration 파일을 정의하고 로드할 수 있다.
nesting된 복잡한 configuration 객체들을 사용하는 대신, registerAs
를 사용하여 namespace의 configuration을 정의할 수 있다.
export default registerAs("database", () => ({
host: process.env.DATABASE_HOST,
port: process.env.DATABASE_PORT || 5432,
}));
Ref https://docs.nestjs.com/techniques/configuration#configuration-namespaces
👩🏫 IoC (Inversion of Control)
제어의 역전은 프로그래머가 작성한 프로그램이 재사용 라이브러리의 흐름 제어를 받게 되는 소프트웨어 디자인 패턴이다. 제어의 역전이 적용된 구조에서는 외부 라이브러리의 코드가 프로그래머가 작성한 코드를 호출한다.
모듈을 작성할 때, 모듈과 외부 프로그램의 결합을 고민할 필요 없이 모듈의 목적에 집중할 수 있으며, 모듈을 바꾸어도 다른 시스템에 부작용을 일으키지 않는다.
예를 들어, 웹 개발에서 많이 사용하는 프레임워크는 규칙에 따라 구성요소를 등록하면, 프레임워크에서 이 구성요소를 가져다 써야 한다. (DOM 렌더링에 관여하는 React가 바로 적합한 예시!)
코드 상에서 IoC는, 클래스의 생성자를 직접 호출해 인스턴스를 생성하는 방법이다. IoC는 누가 작업을 수행하느냐에 대한 이야기다.
👩🏫 DI (Dependency Injection)
의존성 주입은 프로그래밍에서 구성요소 간의 의존 관계를 소스코드 내부가 아닌 외부의 설정 파일 등을 통해 정의하는 디자인 패턴이다.
IoC의 한 형태가 DI다. 마틴 파울러는 다음 세 가지 의존성 주입 패턴을 제시한다.
즉 DI는 의존성을 어떻게 주입할 것인가에 대한 문제다.
👩🏫 DIP (Dependency Inversion principle)
객체지향 프로그래밍에서 의존 관계 역전 원칙은 소프트웨어 모듈들을 분리하는 특정 형식을 지칭한다. 상위 계층(정책 결정)이 하위 계층(세부사항)에 의존하는 전통적인 의존 관계를 역전시킴으로써 상위 계층이 하위 계층의 구현으로부터 독립되게 할 수 있다. (😲 클린 아키텍처 19장 ‘정책과 수준’에 나온 내용과 같다. 좋은 아키텍처는 각 컴포넌트를 연결할 때 의존성의 방향이 저수준 -> 고수준 컴포넌트가 되어야 한다.)
DI는 DIP를 구현하는 방법 중 하나다. DIP로 다형성을 적극적으로 활용하면, 모듈의 재사용성을 높일 수 있다.
즉 DIP는 실체에 의존할 것인가, 추상화에 의존할 것인가에 대한 문제다.
Ref https://black-jin0427.tistory.com/194
animation-fill-mode: forwards
- CSS 애니메이션 실행 후 실행 마지막 상태로 남아있게 하는 법 (Ref)<a>
태그 즉 링크를 터치했을 때 하이라이트를 표시한다. iOS와 안드로이드의 웹킷 기반 브라우저 (사파리, 크롬 등)가 대상이다. (Ref1, Ref2)d.ts
파일을 생성할 것인지 여부를 가리킨다. (Ref)C/C++이 다른 언어에 비해 갖고 있는 큰 단점은, include
구문을 갖고 있다는 것이다. 헤더파일의 include
구문 탓에, 소스파일 파싱에 O(n^2)의 시간복잡도를 가지게 된다. 반면 Rust는 소스파일 파싱에 O(n)의 시간복잡도를 가진다.
C/C++의 또 다른 단점은, 지나친 전방선언(forward declaration)이다. Rust는 런타임 코드가 뒤섞이지 않는 언어이면서도, 전방선언이 불필요한 언어다.
전방선언(forward declaration) 이란? 식별자를 정의하기 전에 식별자의 존재를 컴파일러에게 미리 알리는 방식이다. 헤더 포함 의존성을 최소화하기 위해 도입된 방식이다. Ref https://ju3un.github.io/c++-forward-declaration/
또한 C언어의 매크로는 단순 문자열 대체를 해준다. 하지만 지나칠 정도로 문자열 대체를 지원하여, 때로는 불필요한 오버스펙일 수도 있다. Rust의 declarative macro는, BNF 문법을 사용해서 매크로 안에 들어가는 파라미터를 자유롭게 정의할 수 있다. 또 Rust의 procedural macro를 사용하여 컴파일 타임에 코드를 실행해볼 수 있다.
BNF(Backus-Naur Form) 란? 프로그래밍 언어를 정의하기 위한 메타 언어로, 정규화 표현에 많이 사용한다.
<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 <hex_letter> ::= A | B | C | D | E | F <hex> ::= <digit> | <hex_letter>
이에 더해 Rust는 클래스 상속 대신 traits라는 개념을 사용하며, Rust의 enum 또한 신박하다.
하지만! 이런 Rust에게도 단점은 있다.
뒷 이야기는 출처⬇️에서 계속…
Ref https://docs.google.com/document/u/1/d/19zX4p3jJGnk-GnTeGz4BSh8XKnVR0fM8x3BY1A-GdD8/mobilebasic
…의 역사를 거쳐 탄생한 위젯 주도 개발!
모든 페이지를 자율적으로 작동하고 독립적인, 소위 위젯으로 분할한다.
모든 위젯은 다음과 같은 기능을 담당한다.
이러한 접근 방식은 위젯이 의존하는 API 쿼리를 투명하게 만들며, 위젯을 쉽게 테스트할 수 있다.
Ref https://medium.com/@yujso66/번역-위젯-주도-개발-b3e95b261c18
일반적으로 axios
를 사용하여 비동기 요청을 할 때, 응답 형식으로 제네릭을 사용한다.
export default async function fetchPosts() {
const { data } = await axios.get<Post>(
"https://jsonplaceholder.typicode.com/posts"
);
return data;
}
export type Post = {
userId: number;
id: number;
title: string;
body: string;
};
하지만 제네릭은 컴파일 타임에서 에러가 잡히지 않기 때문에, 런타임에서 예상치 못한 문제가 터질 수 있다!
이때 필요한 것이 Schema Validation Layer다.
Validation Layer의 요지는 두 계층 사이에서 오고가는 데이터를 검증하는 계층을 두는 것이다. npm엔 Schema Validation을 위한 패키지가 많이 있다. 여기서는 zod를 사용한다.
// schema/post.ts
import axios from "axios";
import { z } from "zod";
export type Post = z.infer<typeof Post>;
export const Post = z.object({
userId: z.number(),
id: z.number(),
title: z.string(),
body: z.string(),
});
export type Posts = z.infer<typeof Post>;
export const Posts = z.array(Post);
// remotes/post.ts
/* Type Inference:
function fetchPosts(): Promise<{
userId: number;
id: number;
title: string;
body: string;
}[]>
*/
export default async function fetchPosts() {
const { data } = await axios.get(
"https://jsonplaceholder.typicode.com/posts"
);
return Posts.parse(data);
}
만약 잘못된 Schema로 parse
를 시도한다면, ZodError
를 throw한다.
export default async function fetchPosts() {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/posts');
+ return Post.parse(data);
- // return z.array(Post).parse(data);
}
zod에서 제공하는 메서드들을 사용하면 schema validation을 손쉽게 할 수 있다!
Ref https://www.pumpkiinbell.com/blog/remote/scheme-validation-layer
Jetbrains 차세대 IDE인 fleet이 공개테스트 버전으로 풀렸다!
가볍고, 똑똑하고, 유연한 에디터를 제공한다고 한다.
Ref
페이스북에서 JavaScript 메모리 누수를 찾기위해 제작한 메모리 테스트 프레임워크
memlab run --scenario test.js
위 명령어로 간단하게 내 코드를 검사해볼 수 있다! 편리…
근데 자바스크립트에서 메모리 누수는 어떤 경우들에서 발생할까? 다음 코드를 보자.
var obj = {};
console.log(obj);
obj = null;
obj
를 null
로 만들었음에도 불구하고 크롬에서는 obj
에서 메모리 누수가 발생한다. 크롬은 출력된 객체에 대해서 내부 참조를 계속 가지고 있기 때문이다.
코드 상에서 메모리 누수가 발생하진 않지만, 클라이언트 캐시나 virtualization이 되지 않는 무한 스크롤 등의 상황에서도 메모리 누수가 발생하는 경우가 있다.
MemLab은 다음과 같은 순서로 작동한다.
Ref
이제 나같은 똥손💩도 디자인을 뚝딱뚝딱 만들어버릴 수 있다~!
Ref https://designer.microsoft.com/
swc의 창시자 강동윤 님이 만드신 거구나..!
Ref https://kdy1.dev/posts/2022/10/tsc-port-status
주 4일제 베타 체험판이 끝났다… 이제 연말까지 공휴일 없다. 그치만 난 휴가가 많이 남아서 괜찮다 ^0^
pt는 세 번이나 방황한 끝에 드디어 결제했다..! 헬스장이 아니라 전문피티샵이라서 더 좋다. 트레이너 분도 넉살 닮으시고 첫 수업부터 왕 친근 ㅋㅋ 나같은 초짜를 잘 다룰 줄 아시는 것 같다. 이제 약골 탈출하고 지방은 불태워버리자아…
라고 했는데 주말에 판교 idc 한 곳에 불이나서 카카오가 무려 15시간…? 넘게… 장애… 그리고 일요일 저녁인 지금까지도 일부 서비스들이 돌아오지 않았다. 카톡 뿐만 아니라 카카오맵, 페이, 택시, 바이크 등등 카카오 공화국이었던 대한민국은 완전 패닉에 빠져버렸고… 카카오 형들 힘내세요… 근데 처음으로 라인을 깔아봤는데, 꽤 괜찮은 것 같다. 이 참에 탈 카카오 했으면.. 싶지만 이미 아주 강력해져버린 Lock-in 🤷♀️
그나저나 맥스🎧를 쓸지말지 아직도 고민중이다. 청음하고 더 고민되는 것 같다 ㅡㅡ 그린 왜 또 이뻐서…