update to wsl2

오후 9:53 2021-07-10 작성됨

  • Remote - WSL 확장도구가 너는 WSL1을 사용 중인데, WSL2로 업그레이드해라 알려줘서 업데이트했다

WSL2로 업데이트하기

  • 둘 버전이 어떤 차이가 있는지 알려주는 페이지가 켜진다

  • Install WSL 1 and update to WSL 2 버튼을 누른다

  • Windows Insiders는 간편하게 명령어 하나로 업그레이드 가능하다고 한다

  • wsl --install 해보고 안되면 수동 설치를 하면 된다

  • 수동 설치도 명령어 4번으로 간편하다

  • 중간에 WSL2를 위한 요구사항을 체크해야 하는데,

  • Ctrl + R msinfo32 또는 윈도우키로 시작 메뉴를 열고 시스템 정보를 입력해서 요구사항을 확인한다

PowerShell (Administrator)
1
2
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
  • 위 명령어 입력 후 컴퓨터 재부팅

PowerShell (Administrator)
1
2
3
wsl --set-default-version 2
wsl --list # 설치된 배포판 이름 확인
wsl --set-version {배포판 이름} 2 # wsl --set-version Ubuntu-20.04 2
  • 갑자기 cmd를 썼는데, 중간에 재부팅해서 일관적으로 캡처하지 못했다 ㅠ (뭘 쓰던 상관은 없다.)
  • 기존에 WSL을 사용하고 있는 사람에 한해서 wsl --set-version 명령을 실행해줘야 한다
  • 가이드 문서를 다 따라 했는데, vscode를 켜고 Remote WSL를 사용하면 여전히 WSL1을 쓰고 있다고 말한다
  • 알고 보니까 기존 배포판은 그대로 버전 1이 적용되고 있다
  • 기존 배포판에 WSL2를 적용하려면 wsl --set-version {배포판 이름} {타깃 버전}까지 실행해줘야 한다
  • 5분 정도 걸렸나? 시간이 조금 걸리는 작업이다

참고

js spread syntax `...` 연산자

1
2
3
4
5
6
const arr = [1, 2, 3];
console.log(arr); // [1,2,3]
console.log(...arr); // 1 2 3
console.log(1, 2, 3); // 1 2 3
console.log([...arr]); // [1,2,3]
console.log(arr === [...arr]); // false
  • 리액트를 처음 공부할 때 자주 접하면서 알게 된 연산자다
  • 상태를 변경하려면, 완전히 새로운 객체를 대입시켜줘야 한다
  • (참조하는 주소를 이전이랑 다르게 해야 state 갱신이 일어났다고 판단하고 화면을 갱신한다)
  • 자바스크립트에는 괴랄한 문법이 많구나 느꼈었다
  • 한 꺼풀 벗겨내는 연산자라고 생각하면 쉽다

배열에서 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 함수 인자 넘기기
{
const pram = [1, 2];

function add(a, b) {
return a + b;
}

add(...pram); // === add(1, 2); // 3
}

// 함수 파라미터
{
const pram = [1, 2, 3, 4, 5];

function add2(...args) {
return args.reduce((p, c) => p + c, 0);
}

const result1 = add2(...pram);
console.log(result1);
const result2 = add2(10, 20, 30);
console.log(result2);
}

// 배열 이어 붙이기
{
const prefix = 111;
const subfix = 999;
const arr = [1, 2, 3];
const newArr = [prefix, ...arr, subfix];
console.log(newArr); // [111, 1, 2, 3, 999]
}

객체에서 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 객체 복사 및 값 일부 수정
{
const obj = {
a: 1,
b: 2,
};
const newObj = {
...obj,
b: 10,
};

console.log(obj === newObj); // false
console.log(obj); // b===2
console.log(newObj); // b===10
}

참고

js array.sort()가 원본을 바꾼다

  • 가끔 원본이 바뀌어서 예상치 못한 동작을 할 때가 있다
1
2
3
4
5
6
7
8
9
10
11
12
13
// 원본인 arr 이 정렬됨
{
const arr = [1, 2, 3];
const sortedArr = arr.sort((a, b) => b - a);
console.log(arr === sortedArr); // true
}

// 원본인 arr를 살리면서 정렬된 새 배열 얻기
{
const arr = [1, 2, 3];
const sortedArr = [...arr].sort((a, b) => b - a);
console.log(arr === sortedArr); // false
}
  • [...arr] 이런 식으로 배열을 복사할 수 있다

하나 더, 배열 복사할 때 주의할 점

  • 그런데 number[] 타입이 아니라 {...}[]같은 객체 배열이라면
  • [...arr] 연산으로 새로운 배열이 만들어지기는 하지만
  • 원소 하나하나는 여전히 call by reference 이기 때문에
  • 완전한 복사본(깊은 복사)을 얻은 게 아니라는 점을 유의해야 한다

참고

perssonal access token으로 비공개 레포 git clone 하기

1
git clone https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@github.com/chinsun9/my-private-repo.git
1
2
3
4
git clone https://github.com/chinsun9/my-private-repo.git
Cloning into 'my-private-repo'...
Username for 'https://github.com': chinsun9
Password for 'https://chinsun9@github.com': xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • 이런 식으로 패드워드 대용으로 사용해도 되지만,
  • github.com 앞에 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@
  • 토큰@를 붙여서 cli에서 입력하는 과정을 스킵할 수 있다
  • 이때 사용하는 토큰은 repo: Full control of private repositories 권한이 필요하다

regexp lastIndex

정규식 test는 true인데 exec가 동작하지 않는다?!

work!
1
2
3
4
5
6
7
8
9
if (regexp.test(line)) {
// 내부 포인터 재설정
regexp.lastIndex = 0;

let match = regexp.exec(line);
while (match) {
// ...
}
}
  • regexp.lastIndex = 0

잘못된 코드

not work!
1
2
3
4
5
6
7
8
if (regexp.test(line)) {
// 여기서 lastIndex 갱신
let match = regexp.exec(line); // 갱신된 lastIndex부터 검색을 시작해서 첫번째 결과가 스킵됨.
while (match) {
// 라인에 일치하는 패턴이 한개라면 반복문한 한번도 돌지 않음
// ...
}
}
  • 처음에 작성한 코드다
  • 파일의 라인 한 줄 한 줄 읽으면서
  • 정규식 패턴과 일치하는 라인이라면
  • 결괏값을 받도록 만들었는데, 이상하게도 제대로 동작하지 않았다
  • 알고 보니까 test() 메서드도 lastIndex를 갱신했었다…
  • 사실 저 if (regexp.test(line)) {은 필요 없는 코드 같다
  • testexec를 같이 쓸 때 주의가 필요하다

참고

vscode 나만의 스니펫 만들어서 사용하기

상황

  • 여러 테스트 파일을 만드는데, 기본적으로 작성해야 하는 틀이 있다
  • 기본 틀이 되는 코드를 scaffold.test.ts 파일로 만들어서 내용을 복사해서 사용하거나, 복사본을 만들면서 새로운 테스트 파일들을 생성했다
  • 반복하다 보니까 이마저도 불편했다
  • 그러다가 커스텀 스니펫을 만들기로 한다

목표

1
2
3
4
5
6
7
8
9
/**
* problem
*/

describe('id', () => {
test('should ', () => {
expect(solution(prams)).toEqual(er);
});
});
  • 내 목표는 te를 입력하면 내가 등록한 스니펫을 통해 위 코드를 완성시킬 것이다

스니펫 만들기

  • 상단바에서
  • File > Preferences > User Snippets 을 선택한다

  • 어떤 언어에서 만들 것인지 선택한다
  • 나는 타입스크립트에서 사용할 것이다
  • 그러면 %userprofile%\AppData\Roaming\Code\User\snippets\typescript.json이라는 파일이 생성되고
  • 설명과 예제가 나와있다
%userprofile%\AppData\Roaming\Code\User\snippets\typescript.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
// Place your snippets for typescript here. Each snippet is defined under a snippet name and has a prefix, body and
// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
// same ids are connected.
// Example:
"cotejs test": {
"prefix": "te",
"body": [
"/**",
"* ${1:problem}",
"*/",
"",
"describe('${2:id}', () => {",
"$0",
" test('should ', () => {",
" expect(solution(${3:prams})).toEqual(er);",
" });",
"});"
],
"description": "base"
}
}
  • prefix ; 나는 te로 설정했다. 스니펫이 어떤 문자열에 추천될지 설정하는 곳이다
  • body ; 내가 완성시키고 싶은 스니펫을 등록한다. 줄 바꿈을 기준으로 배열로 쪼개 줘야 한다
  • description ; 스니펫에 대한 설명을 적는다
  • 특히 자동 완성할 때 tab를 누르면 커서가 원하는 순서로 이동하게 할 수 있다
  • $1, $2, $3,..., $n, $0을 통해서 가능하다
  • 각 커서에 기본값을 추가하고 싶으면 ${1:one} 이런 식으로 가능하다
  • $0은 마지막 커서 위치를 설정할 수 있다

참고

모바일 크롬 개발자 도구 사용, 포트포워딩해서 localhost 환경 만들기

  • 모바일에서 동작하는 devicemotion 이벤트 등 디버깅하기 위해 개발자 도구를 봐야 했다
  • 모바일에서 개발자 도구를 어떻게 켜는지 등 찾아보다가
  • 핸드폰을 데탑에 연결하고
  • 데탑의 크롬에서 console의 출력 결과를 확인할 수 있다
  • 그리고 모바일 화면을 미러링 해준다

하는 법

“[Android 개발] 크롬 개발자 도구 모바일 디버깅/Mobile Debugging/ PC에서 모바일 디버깅 / 모바일 개발환경 구축”
https://backstreet-programmer.tistory.com/30

  • 위 블로그를 참고해서 핸드폰과 데탑을 연결했다

포트포워딩 하기

  • devicemotion, geolocation 등 보안 컨텍스트가 필요한 Web API의 경우 localhost로 만들어줘야 한다
  • 내부IP:PORT 해서 접속은 할 수 있지만,
  • devicemotion가 정상 동작하려면 localhost여야 한다

상황

  • 데탑에서 웹 개발 진행 중

  • 로컬에서 5500 포트로 웹서버가 열려있음

  • 모바일에서 위 웹서버에 접속하려면 내부아이피:포트를 입력해야함

  • 모바일에서 localhost:5500을 입력해서 접속할 수 있도록 해보자

  • chrome://inspect/#devices 에 접속한다

  • 내 핸드폰이 잘 연결되었는지 확인한다

  • 포트 포워딩 버튼을 누른다

  • 5500 포트와 localhost:5500을 매칭시켰다
  • 이제 핸드폰 크롬에서 localhost:5500으로 접속하면 웹서버에 접속할 수 있다!
  • 물론 Web API도 모두 잘 동작한다

참고

js empty array

new Array(n)으로 초기화한 배열에 array api가 동작하지 않았다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
const arr = new Array(5);

console.log(arr.length, arr); // 5 [ <5 empty items> ]
console.log(arr.push(1), arr); // 6 [ <5 empty items>, 1 ]
console.log(arr.push(2), arr); // 7 [ <5 empty items>, 1, 2 ]

console.log(arr.map((v) => v * 2)); // [ <5 empty items>, 2, 4 ]

arr.forEach((v) => {
console.log(v);
});
// 1
// 2

console.log(`-----------`);

for (let index = 0; index < arr.length; index++) {
const element = arr[index];
console.log(element);
arr[index] = undefined;
}
// undefined
// undefined
// undefined
// undefined
// undefined
// 1
// 2

console.log(`-----------`);

arr.forEach((v) => {
console.log(v);
});
// undefined
// undefined
// undefined
// undefined
// undefined
// undefined
// undefined
  • 위에 map이나 forEach를 보면 array api가 초기화하지 않은 인덱스에 대해 동작하지 않는 것을 확인할 수 있다
  • 직접 for문으로 찍어보면 undefined이라 나온다
  • 그러면서 undefined으로 전부 초기화해줬다
  • 직접 초기화해주니까 array api forEach가 동작하는 것을 확인할 수 있다
  • array api를 동작하지 않는 것을 경험했다
1
const arr = new Array(5).fill(0);
  • 이런 식으로 특정 값으로 직접 초기화를 해줘야 스킵되지 않고 정상적으로 api를 사용할 수 있다

공식문서가 어려운 이유

처음 웹 개발을 공부하기 시작할 때 mdn보다 w3school을 가게되는지…

공식문서가 어려운 이유

  • 모르는 걸 모르게 설명한다
  • 엄청 디테일해서 TMI다
  • 엄청 생략된 예제
  • 영어

모르는 걸 모르게 설명한다

  • 공식 문서를 작성하시는 분들은 당연히도 그 기술에 대해 빠삭하신 분들이다
  • 해당 기술을 잘 알고 있는 사람들한테는 최고의 문서일 것이다
  • 하지만 초보가 문서를 읽었을 때 개발 경험 부족으로 센스가 부족해서
  • 아주 간단한 것일지라도 막힐 때가 있다
  • 사전에서 어떤 단어를 찾았는데 그 단어가 또다시 모르는 단어로 설명되어 있는 느낌

엄청 디테일해서 TMI다

  • 나는 빨리 헬로월드를 출력하고 싶은데, 뭔가 글이 길고 복잡해 보인다
  • install 할 때 여러 옵션들, cli 명령어의 여러 옵션들 등
  • 실행만 하는데도 너무 어려울 것 같은 인상을 준다
  • 나는 보통 스크롤이 길고 빼곡한 줄글이 있으면 탈주가 하고 싶다

엄청 생략된 예제

  • 프로젝트 세팅 및 디렉터리 구조 등 생략된 것이 많이 있다
  • 처음 접할 때 내가 튜토리얼을 잘 따라가고 있는지 의문이 들 때가 많이 있다
  • 명령어를 실행해야 하는 디렉터리가 어디인지
  • 어디에 파일을 생성해야 하는지
  • 프로젝트 세팅을 어떻게 해야 하는지
  • 알고 보면 너무 당연한 베이스지만 초보라면 그것조차 너무 어렵다 ㅠㅠ

영어

  • 안 그래도 무슨 말인지 잘 모르는데 영어 ㅠㅠ
  • 기술 용어들이 많아서 번역을 써도 이상한 경우가 많이 있다

생각

  • 공식문서를 보는 게 좋다 주변에서 들었지만
  • 나는 공식문서 보다가 ctrl w를 누른 적이 너무 많다
  • 요즘에야 많이 익숙해지고 센스도 늘어서 공식문서를 예전보다는 많이 읽는 편이다
  • 하지만 요즘도 처음 사용하는 라이브러리라든가
  • 빠른 프로젝트 적용 또는 시작을 위해 youtube를 참고한다
  • 영상만큼 직관적인 게 없다고 생각한다
  • 정적인 문서로는 초보자를 이해시키는 게 어렵다
  • 영상은 변경사항을 업데이트하기가 어려운 단점이 있다
  • 영상 제작은 아무래도 노력이 많이 필요하다