리눅스 shutdown 명령어

1
2
3
4
5
6
7
8
// 지금종료
sudo shutdown -h now

// 재시작
sudo shutdown -r now

// 종료예약 취소
sudo shutdown -c

string to number 요상한 문법 (js)

  • string type 변수앞에 + 기호를 넣으면 number type 으로 캐스팅된다…
  • 이런 문법은 wow…
example.ts
1
2
3
4
5
6
7
function squareValue(x: any) {
return Math.pow(x * 1, 2);
}

function squareValue(x: string | number) {
return Math.pow(+x, 2);
}
  • any 사용을 피하라는 예제를 코드를 보는데 우연히 알게되었다

참고

typescript에서 mathjs 사용해서 소수점 정확하게 계산하기

  • 부동소수점으로 인한 계산 오류가 있다
  • mathjs 라이브러리로 해결해보자

mathjs 설치

1
2
yarn add mathjs
yarn add @types/mathjs -D
  • mathjs만 설치하면 타입 정의가 없기 때문에
  • @types/mathjs 보조 라이브러리까지 설치

mathjs 임포트

example1.ts
1
import * as math from 'mathjs';
  • 그냥 기본값으로 사용하려면 import * as math from 'mathjs'로 불러와 사용
  • default export가 없어서 import math from 'mathjs'이런 식으로 사용불가
    • Attempted import error: "mathjs" does not contain a default export
example2.ts
1
2
3
import { create, all } from 'mathjs';

const mathF = create(all, { number: 'Fraction' }) as math.MathJsStatic;
  • 지정 config를 적용해 사용하려면 create 메서드 사용
  • create(all, { number: 'Fraction' }) as math.MathJsStatic
  • as 키워드로 타입을 명시하지 않으면 undefined 에러 발생
    • Cannot invoke an object which is possibly 'undefined'

소수점 계산

calc.ts
1
2
3
4
5
6
7
8
9
import { create, all } from 'mathjs';

const mathF = create(all, { number: 'Fraction' }) as math.MathJsStatic;

const mathjsCalc = (expr: string) => {
return mathF.number(mathF.evaluate(expr));
};

const result = mathjsCalc(`${value1} * ${value2} * 0.01`);
  • evaluate메서드를 사용해서 수식 string을 주면 알아서 계산하도록 했다
  • 이때 math ConfigOptions에서 number 옵션이 기본값(number)인 경우에 일반적인 계산이 된다
  • number 옵션에 Fraction을 주고 생성하게 되면 evaluate 메서드에서 숫자를 Fraction 타입으로 파싱 해서 계산하게 되어 우리가 기대하는 결과를 얻을 수 있다

참고

react로 만들어본 퇴근시간 계산기

기능

메인 페이지

  • 목표 시각까지 남은 시간 계산
  • url param을 통해 목표 시각 세팅
  • 목표 시각이 지나면 퇴근하라는 메시지를 뛰움

about 페이지

  • 링크 공유 기능
  • 퇴근 시간 설정 기능
  • 자동 클립보드 복사

깃허브 페이지 spa 세팅

배경이미지 출처

해결한 문제들

gsap 적용안됨

Share.tsx
1
2
3
4
5
import { Power3, TimelineLite } from 'gsap';
import CSSPlugin from 'gsap/CSSPlugin'; // 추가

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const C = CSSPlugin; // 추가
  • 로컬에서는 애니메이션이 잘 실행되었는데, 빌드 후 애니메이션이 안 나오는 문제 해결

후기

  • 어느 정도 리액트에 익숙해진 것 같다
  • 주로 사용하는 패턴이 생긴 것 같다
  • 엄청 간단해 보이지만 이것저것 신경 쓴 것 같은데, 기록을 안 해놨다 ㅠㅠ
  • 나는 코드에 조금의 변화가 생겨도 커밋을 했었는데,,
  • 이번에는 커밋을 안 하고 한 번에 몰아서 마지막에 파일별로 커밋을 했다
  • 그래서 해결한 문제들이 기억이 잘 안 난다.. ㅠㅠ

신경 썼던 것들

input element

  • about 페이지에서는 링크를 생성하는 부분이 있다
  • 처음에는 input width가 좁았었다. 그래서 고민했던 것이…
  • input 넓이보다 안의 내용이 더 길면은 끝부분이 감춰진다

  • input에서 포커스를 해제하면 위 그림처럼,
  • 계속 앞쪽으로 포커스가 자동으로 이동했다

  • 나는 input 내용의 가장 뒤쪽,
  • url param이 변하는 것에 포커스가 가도록 만들려고 이것저것 해봤는데…
  • 결국엔 그냥 input width를 늘려버리고 끝을 냈다…

github pages SPA

  • 깃허브 페이지는 기본적으로 SPA를 지원하지 않는다
  • react-router-dom 으로 여러 경로들을 만들어 두면 index 말고는 404 페이지로 리디렉트 된다
  • 그래서 찾아보니까,,.!
404.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var segmentCount = 1;

var l = window.location;
l.replace(
l.protocol +
'//' +
l.hostname +
(l.port ? ':' + l.port : '') +
l.pathname
.split('/')
.slice(0, 1 + segmentCount)
.join('/') +
'/?p=/' +
l.pathname
.slice(1)
.split('/')
.slice(segmentCount)
.join('/')
.replace(/&/g, '~and~') +
(l.search ? '&q=' + l.search.slice(1).replace(/&/g, '~and~') : '') +
l.hash
);
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(function (l) {
if (l.search) {
var q = {};
l.search
.slice(1)
.split('&')
.forEach(function (v) {
var a = v.split('=');
q[a[0]] = a.slice(1).join('=').replace(/~and~/g, '&');
});
if (q.p !== undefined) {
window.history.replaceState(
null,
null,
l.pathname.slice(0, -1) + (q.p || '') + (q.q ? '?' + q.q : '') + l.hash
);
}
}
})(window.location);
  • 원리는 index 경로 외에 나머지 경로로 들어오면 404페이지를 반환하는데,
  • 커스텀 404페이지에서 스크립트를 통해서 index페이지로 리디렉트 하게 한다
  • 이때, url params 및 query string을 가공한다
  • index.html에서는 404.html로부터 넘겨받은 값으로 라우팅이 적용된 화면을 보여준다
  • 이걸 만든 사람은 정말 대단한 것 같다. ㄷㄷ;

소스코드

참고

github pages spa

web font 적용하는 2가지 방법

index.css
1
@import url('https://fonts.googleapis.com/css2?family=Nanum+Gothic&display=swap');
index.html
1
2
3
4
<link
href="https://fonts.googleapis.com/css2?family=Nanum+Gothic&display=swap"
rel="stylesheet"
/>
  • link태그로 불러오는 것은 기존에 알고 있었는데,
  • css에서 @import 로 불러오는 것은 처음알았다
  • 폰트같이 범용적은 것은 index.css에 넣어주면 좋을 것 같다

참고

type vs interface

1
2
3
4
5
6
7
8
9
10
// X
type MyFile extends File = {}

// O
interface MyFile extends File {
preview: string;
}

// O
type MyFile = {preview: string} & File
  • type은 extends, implements가 안됨
  • 대신 extends의 경우는 & 키워드를 사용하여 대체할 수 있다
  • interface와 type은 거의 같은 역할을 한다
  • 그래서 둘중 하나만 사용하여 일관적인 스타일을 유지하는 게 좋다고 들었다

참고

  • 나는 typescript를 공부하면서 처음 접한게 type이라서 type을 쭉 사용해왔다
  • 그런데 상속을 해야하는 경우에 마추쳤을 때, 불가피하게 interface 키워드를 사용했고,
  • type을 사용할 수 없을까 찾아보다가 type vs interface 에 대한 좋은 링크를 찾았다

react url params 사용하기

example.tsx
1
2
3
4
5
// 전
res = await myFetch(`get/${location.pathname.split('/')[2]}`);

// 후
res = await myFetch(`get/${id}`);
  • 처음에는 url params에 어떻게 접근할까하다가 location객체에서 수동으로 파싱해서 썼었는데

  • ‘react-router-dom’ 에서 useRouteMatch라는 메서드를 통해서 자동으로 파싱하고 필요한 차일드에 넘겨주었다

parent.tsx
1
2
3
4
5
6
7
8
9
10
11
12
// 최상위, 컴포넌트 밖
type MatchParams = {
id: string;
};

// 컴포넌트 안 최상위
const match = useRouteMatch<MatchParams>('/start/:id');

// 렌더 부분, 컴포넌트 안 return 부분
<Route path="/start/:id">
<Start id={match?.params.id || ''} />
</Route>;
child.tsx
1
2
3
4
5
6
7
8
9
// 최상위, 컴포넌트 밖
type Props = {
id: string;
};

// 컴포넌트 선언부
function Start({ id }: Props) {
// ...
}
  • 차일드에서 useRouteMatch를 사용해보았는데, useEffect에서 무한루프에 걸려서
  • 부모에서 전달해주었다

참고

내가 css를 작성하면서 많이 사용하는 줄임말, 스니펫?

1
2
3
4
5
6
7
8
9
10
.example {
/* df */
display: flex;

/* jcc */
justify-content: center;

/* aic */
align-items: center;
}
  • 짧게 쓰고 자동완성 시킨다
  • 자동완성 시키고 ctrl + enter 로 새로운 라인으로 이동하여 이어서 작성한다

chrome 드래그 앤 드랍 안됨

  • chrome이 관리자 권한으로 켜져있는지 확인한다
  • 관리자 권한으로 켜지면 드래그 앤 드랍이 작동하지 않는다

TMI

  • 웹에서 드래그 앤 드랍으로 이미지를 첨부하는 기능을 넣었는데,

  • 이상하게 마우스 커서가 위 처럼 되면서, 동작하지 않았다
  • 막 chrome://flags 들어가서 설정도 따라해보고,
  • windows 이미지 도구? 도 재설치해보고 삽질을 마구마구하다가
  • 그냥 관리자 권한으로 chrome이 켜져 있어서 안되었던 문제이다
  • 이밖에도 chrome이 관리자 권한으로 켜져있으면 안되는 것은,
  • 카톡 등 메신저에서 다른 링크를 켤 때 정도가 있다
  • chrome이 관리자 권한으로 켜지는 이유는
  • 나는 vscode가 관리자 권한으로 실행되게 해놨다,
  • 그래서 vscode에서 브라우저를 실행시킬 때 관리자권한으로 실행된다

SyntaxError: Unexpected end of input

  • vscode에서는 아무 에러, 경고없이 잘 실행되었는데,
  • SyntaxError-Unexpected-end-of-input 에러가 날 때가 있다
  • 나의 경우에는 api 서버가 host가 달라 cors mode로 리퀘스트를 보내야하는데
  • ‘no-cors’ mode로 보내서 생긴 에러이다
  • 그 외에도 api서버에서 연산이 잘못되어 응답을 반환하지 않을 때에도 똑같은 에러가 나왔다
  • 그냥 서버로부터 결과를 제대로 받지 않으면 생기는 오류 같다