├── .github ├── disabled-workflows │ └── add_contributor.yml └── workflows │ └── update_readme_toc.yml ├── .gitignore ├── .log └── readme_log.json ├── Javascript ├── Asynchronous.md ├── Basic_movement.md ├── DataType.md ├── ES2020.md ├── ES_Module.md ├── Es6_Spec.md ├── EventBubling.md ├── Garbage_Collector.md ├── Hoisting.md ├── Iterator_Generator.md ├── JIT.md ├── Number_Floating_Point.md ├── Prototype.md ├── Scope.md ├── Storing_Data_In_Browser.md ├── This_Keyword_Call_Apply.md ├── Throttling_Debouncing.md ├── V8_Engine.md ├── Web_Working_Concept.md ├── executionContextAndClosure.md └── variable_tdz.md ├── README.md ├── S2_Round1 ├── chart-library.md ├── introduction-to-stateManagementTools.md ├── lazyloading.md ├── nextjs_tutorial_ch1.md ├── rxjs.md └── storybook.md ├── S2_Round2 ├── code-splitting.md ├── css-bem.md ├── css_in_js.md ├── jsTDD.md ├── lighthouse.md └── oop_vs_functional.md ├── S2_Round3 ├── FID.md ├── LCP.md ├── core-web-vitals.md └── web-vitals-best-practice.md ├── S2_Round4 └── Http-vs-Socket.md ├── _config.yml ├── interview ├── Nailer_interview1.md ├── Nailer_interview2.md ├── Nailer_interview3.md ├── Samslow_Interview1.md ├── Samslow_Interview2.md ├── Samslow_Interview3.md ├── Snowjang24_Interview1.md ├── Snowjang24_interview3.md ├── devowen_interview1.md ├── devowen_interview2.md ├── devowen_interview3.md └── jinsunee_interview1.md ├── lib ├── __init__.py ├── gitlog.py ├── header.py ├── logger.py └── rmd.py ├── py-package.txt └── update_readme.py /.github/disabled-workflows/add_contributor.yml: -------------------------------------------------------------------------------- 1 | # This is a basic workflow to help you get started with Actions 2 | 3 | name: add_contributor 4 | 5 | # Controls when the action will run. Triggers the workflow on push or pull request 6 | # events but only for the master branch 7 | on: 8 | push: 9 | branches: [] 10 | 11 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 12 | jobs: 13 | # This workflow contains a single job called "build" 14 | build: 15 | # The type of runner that the job will run on 16 | runs-on: ubuntu-latest 17 | 18 | # Steps represent a sequence of tasks that will be executed as part of the job 19 | steps: 20 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 21 | - uses: actions/checkout@v2 22 | 23 | # 팀원 자동 추가 액션 24 | - name: Contribute List 25 | uses: akhilmhdh/contributors-readme-action@v1.1 26 | env: 27 | GITHUB_TOKEN: ${{ secrets.ACTIONS_TOKEN }} 28 | with: 29 | header: Teammates 30 | -------------------------------------------------------------------------------- /.github/workflows/update_readme_toc.yml: -------------------------------------------------------------------------------- 1 | name: update_md_title 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Check out repo 11 | uses: actions/checkout@v2 12 | with: 13 | fetch-depth: 0 14 | - name: Set up Python 15 | uses: actions/setup-python@v1 16 | with: 17 | python-version: 3.8 18 | - name: Configure pip caching 19 | uses: actions/cache@v1 20 | with: 21 | path: ~/.cache/pip 22 | key: ${{ runner.os }}-pip-${{ hashFiles('**/py-package.txt') }} 23 | restore-keys: | 24 | ${{ runner.os }}-pip- 25 | - name: Update README 26 | run: |- 27 | python update_readme.py 28 | cat README.md 29 | - name: Commit files 30 | run: |- 31 | git diff 32 | git config --global user.email "readme-bot@example.com" 33 | git config --global user.name "README-bot" 34 | git diff --quiet || (git add README.md && git commit -m "Updated README") 35 | git push 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.png 3 | *.jpeg 4 | *.gif 5 | __pycache__/* 6 | lib/__pycache__/* 7 | /.idea 8 | -------------------------------------------------------------------------------- /.log/readme_log.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": "Hello" 3 | } -------------------------------------------------------------------------------- /Javascript/Asynchronous.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 비동기(Asynchronous) 3 | date: 2020-06-19 00:00:00 4 | author: snowjang24 5 | category: Javascript 6 | --- 7 | 8 | # 비동기(Asynchronous) 9 | 10 | ## 여는 말 11 | 12 | 자바스크립트를 공부할 때, 비동기라는 단어를 접하는 순간이 오게 된다. 중요한 개념임에도 불구하고 비동기라는 말 자체에서 이미 좌절감을 겪는 사람들이 많다. 자바스크립트를 잘 활용하기 위해, 잘 작동하는 웹을 만들기 위해서는 필수적으로 이해해야 하는 과정이지만 그 벽이 높아 대충 이해하고 넘어가는 일이 부지기수다. 나 역시 처음에 대충 이해하고 넘어갔다. 이번 기회에 A to Z, 세부적인 이해하기 위해 이 글을 쓰려 한다. 13 | 14 | ## 비동기에 들어가기에 앞서 15 | 16 | 비동기와 동기에 대해 검색하면 가장 먼저 아래와 같은 사진을 마주치게 된다. 동기는 일이 끝나기를 기다렸다가 끝나면 다음 일을 순차적으로 처리하고, 비동기는 기다림 없이 다음 일을 바로 실행하는구나 라는 간단하게 이해했다. 하지만 그래서 자바스크립트는 동기로 작동하나? 비동기는 어디에 쓰이는 거지? 라는 의문이 든다. 17 | 18 | ![Untitled](https://user-images.githubusercontent.com/26768201/86256008-c7653580-bbf2-11ea-82e8-27c8b75e619e.png) 19 | 20 | [Synchronous, Asynchronous](https://velog.io/@cyongchoi/%EB%B9%84%EB%8F%99%EA%B8%B0asynchronous-%EA%B0%9C%EB%85%90) 21 | 22 | 이러한 의문을 해결하기 위해 필요한 개념과 원리에 대해 알아보며 자바스크립트에서의 비동기에 대해 자세히 알아보려 한다. 가장 먼저 아래의 개념들에 대해 자세히 알아보며, 자바스크립트의 비동기에 대한 오해를 풀어보자. 23 | 24 | - 자바스크립트는 Single Thread 기반 언어 25 | - 자바스크립트의 브라우저와 Node에서의 동작 26 | 27 | ## 자바스크립트는 Single Thread 기반 언어 28 | 29 | 자바스크립트는 **싱글 쓰레드(Single Thread)**기반의 언어다. 쓰레드가 하나라는 말은 한번에 하나의 작업만 처리 가능하다는 뜻이다. 하지만, 우리가 자바스크립트를 사용하는 환경인 Node는 여러 개의 HTTP요청을 처리하고, 브라우저는 이벤트 처리나 애니메이션 실행 등 다양한 일을 동시에 처리한다. 마치 싱글 쓰레드가 아닌 것처럼 여러 작업을 동시에 처리한다. 마치 멀티 쓰레드처럼 작동한다. 30 | 31 | ![Untitled 1](https://user-images.githubusercontent.com/26768201/86256066-d350f780-bbf2-11ea-9460-4f6c88371697.png) 32 | 33 | [싱글 스레드와 멀티 스레드](https://blog.lgcns.com/1084) 34 | 35 | ### 동시성과 병렬성 36 | 37 | 싱글 쓰레드와 비교 설명을 위해, 멀티 쓰레드에 대해 반드시 알고 넘어가야 하는 부분이 있다. 바로 **동시성(Concurrency)**과 **병렬성(Parallelism)**이다. 38 | 39 | **동시성(Concurrency, 병행성이라 부르기도 함)**은 싱글 코어에서 멀티 쓰레드를 동작 시키는 방식으로 멀티 태스팅을 위해 여러 개의 쓰레드가 번갈아가면서 실행되는 성질을 뜻한다. 보통 자바와 같은 객체 지향 언어들은 멀티 스레드를 통해 동시성을 진행한다. 40 | 41 | **병렬성(Parallelism)**은 한 개 이상의 스레드를 포함하는 각 코어들이 동시에 실행되는 성질을 뜻한다. 멀티 코어에서 멀티 스레드를 동작시키는 방식이다. 42 | 43 | 동시성은 동시에 실행되는 것 같지만 실제로는 그렇지 않고, 병렬성은 실제로 동시에 실행되는 차이가 있다. 결과적으로 둘 다 **멀티 쓰레드의 동작 방식**이다. 두 동작 방식의 차이에 대한 아래의 그림을 보면 이해가 빠를 것이다. 44 | 45 | ![333333](https://user-images.githubusercontent.com/26768201/86256043-cf24da00-bbf2-11ea-9926-7f33c6b743d4.png) 46 | 47 | ### Single Thread와 Multi Thread 48 | 49 | 아래의 이미지는 싱글 쓰레드와 멀티 쓰레드의 작동 방식에 대해 잘 설명하고 있다. 여기서 Object는 쓰레드를 의미하는 것이 아니다. 50 | 51 | ![Untitled 2](https://user-images.githubusercontent.com/26768201/86256073-d3e98e00-bbf2-11ea-9054-c78888d5582a.png) 52 | 53 | [Performance comparison of single-threaded and multi-threaded execution](https://www.researchgate.net/figure/Performance-comparison-of-single-threaded-and-multi-threaded-execution_fig2_29528663) 54 | 55 | 위의 이미지와 아래의 이미지는 함께 보면 좀 더 이해가 편하다. 각각의 차이가 명확하게 보인다. 56 | 57 | ![Untitled 3](https://user-images.githubusercontent.com/26768201/86256077-d4822480-bbf2-11ea-85eb-4b4233c60a07.png) 58 | 59 | [Parallelism vs. Concurrency](http://www.dietergalea.com/parallelism-concurrency/) 60 | 61 | 이제 다시 돌아와서, 우리가 집중해야하는 부분은 **(a)single-threaded**와 **(b)multi-threaded(single active thread)**다. 62 | 63 | ![Untitled 4](https://user-images.githubusercontent.com/26768201/86256079-d51abb00-bbf2-11ea-9a46-f2f654438df4.png) 64 | 65 | [Performance comparison of single-threaded and multi-threaded execution](https://www.researchgate.net/figure/Performance-comparison-of-single-threaded-and-multi-threaded-execution_fig2_29528663) 66 | 67 | 어디서 많이 본 모양이다. 비동기와 동기... 68 | 69 | ![Untitled](https://user-images.githubusercontent.com/26768201/86256008-c7653580-bbf2-11ea-82e8-27c8b75e619e.png) 70 | 71 | [Synchronous, Asynchronous](https://velog.io/@cyongchoi/%EB%B9%84%EB%8F%99%EA%B8%B0asynchronous-%EA%B0%9C%EB%85%90) 72 | 73 | 일단 싱글 쓰레드, 멀티 쓰레드에 대해 이해를 했으면 다음으로 넘어가자. 74 | 75 | ## 자바스크립트의 브라우저와 Node에서의 동작 76 | 77 | 자바스크립트 엔진(V8)은 **단일 호출 스택(Single Call Stack)**을 사용한다. 요청이 들어올 때마다 요청을 하나씩 순차적으로 호출 스택에 담아 처리한다. 이 부분에서 자바스크립트가 싱글 쓰레드라는 말이 납득이 된다. 78 | 79 | 그럼 대체 비동기 처리는 어떻게 하는 걸까? 동시성은? 80 | 81 | 이 부분을 해결하는 것이 바로 브라우저와 Node다. 브라우저와 Node의 동작 원리는 아래와 같이 도식화가 되어 있다. 자바스크립트의 동작 원리에 대해 공부할 때 자주 보던 그림이다. 아래의 이미지에서 볼 수 있듯이 `XMLHttpRequest`, `setTimeout`과 같이 비동기 호출을 하는 메서드는 모두 자바스크립트 엔진 밖의 영역에 정의되어 있다. 82 | 83 | ![Untitled 5](https://user-images.githubusercontent.com/26768201/86256082-d5b35180-bbf2-11ea-847c-d8684cdb4af5.png) 84 | 85 | ![Untitled 6](https://user-images.githubusercontent.com/26768201/86256084-d5b35180-bbf2-11ea-911f-1abe57f51fc0.png) 86 | 87 | 88 | ## 드디어 비동기! 89 | 90 | 결국 자바스크립트를 구동하는 엔진은 싱글 쓰레드가 맞고, 그 외부인 구동 환경(브라우저, Node)이 멀티 쓰레드기 때문에 비동기 처리가 가능하게 되는 것이다. 91 | 92 | 아래의 비동기 처리의 대표적인 예시를 한 번 살펴보자. 93 | 94 | ```jsx 95 | function func1() { 96 | console.log('func1'); 97 | func2(); 98 | return "End" 99 | } 100 | function func2() { 101 | setTimeout(function() { 102 | console.log('func2'); 103 | }, 1000); 104 | func3(); 105 | } 106 | function func3() { 107 | console.log('func3'); 108 | } 109 | 110 | func1(); 111 | ``` 112 | 113 | 결과는 아래와 같다. 실행 시 블로킹 없이 순차적으로 비동기 방식으로 호출한다. 114 | 115 | ```bash 116 | func1 117 | func3 118 | "end" 119 | func2 120 | ``` 121 | 122 | ## 결론 123 | 124 | 자바스크립트 자체로만 놓고 봤을 때는 싱글 쓰레드 기반 언어이기 때문에 동기적으로 처리된다. 하지만 이 자바스크립트를 구동하는 브라우저나 Node와 함께이기 때문에 멀티 쓰레드 그 중에서 동시성을 지원하기 때문에 비동기 처리가 가능하다. 작동방식에 대해 유념하여 비동기와 관련된 Promise, async-await를 활용하면 좋을 것 같다. 125 | 126 | ## 참고 127 | 128 | - [동시성과 병렬성](https://yolojeb.tistory.com/10) 129 | - [테이터 홍수시대, 이제는 선택이 아닌 필수! 동시성 프로그래밍](https://blog.lgcns.com/1084) 130 | - [동시성 관련 개념](https://medium.com/@ahaljh/%EB%8F%99%EC%8B%9C%EC%84%B1-%EA%B4%80%EB%A0%A8-%EA%B0%9C%EB%85%90-d2f3e6a62b99) 131 | - [Parallelism vs. Concurrency](http://www.dietergalea.com/parallelism-concurrency/) 132 | - [자바스크립트와 이벤트 루프](https://meetup.toast.com/posts/89) 133 | - [자바스크립트는 어떻게 작동하는가: 이벤트 루프와 비동기 프로그래밍의 부상, async/await을 이용한 코딩 팁 다섯 가지](https://engineering.huiseoul.com/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%91%EB%8F%99%ED%95%98%EB%8A%94%EA%B0%80-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84%EC%99%80-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%EC%9D%98-%EB%B6%80%EC%83%81-async-await%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%BD%94%EB%94%A9-%ED%8C%81-%EB%8B%A4%EC%84%AF-%EA%B0%80%EC%A7%80-df65ffb4e7e) 134 | - [동기와 비동기 방식(Asynchronous processing model)](https://webclub.tistory.com/605) -------------------------------------------------------------------------------- /Javascript/Basic_movement.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 자바스크립트 동작 원리 3 | date: 2020-06-25 00:00:00 4 | author: jinsunee 5 | category: Javascript 6 | --- 7 | 8 | # 자바스크립트 동작 원리 9 | 10 | ## 브라우저 동작 원리 11 | 12 | 브라우저는 크게 렌더링 엔진, 자바스크립트 엔진으로 나뉜다. 13 | 사용자가 참조하고자 하는 페이지를 서버에게 요청 후 그에 대한 응답을 화면에 보여주는 일을 한다. 14 | 15 | - 렌더링 엔진 - 서버로부터 받은 HTML, CSS은 브라우저 렌더링 엔진의 HTML파서, CSS 파서에 의해 DOM, CSSOM 트리가 만들어지고 렌더 트리로 결합된다. 렌더 트리를 기반으로 브라우저는 웹페이지를 표시한다. 16 | - 자바스크립트 엔진 - JS로 작성한 코드를 해석하고 실행하는 인터프리터이다. 렌더링 엔진의 HTML 파서가 DOM 생성 프로세스를 하던 중 스크립트 태그를 만나면, 자바스크립트 코드를 실행시키기 위해 자바스크립트 엔진에게 제어권한을 넘겨주게 된다. - DOM 트리가 다 형성되지 않았는데 자바스크립트에서 해당 DOM을 조작하려고 하면 문제가 발생하기 때문에 ` 128 | 129 | ``` 130 | 131 | ### Generate Chart 132 | 133 | ```html 134 |
135 | ``` 136 | 먼저 차트를 만들기 위해서 chart의 div 엘리먼트를 만들어줘야 한다. 137 | 138 | ```javascript 139 | var chart = c3.generate({ 140 | bindto: '#chart', 141 | data: { 142 | columns: [ 143 | ['data1', 30, 200, 100, 400, 150, 250], 144 | ['data2', 50, 20, 10, 40, 15, 25] 145 | ] 146 | } 147 | }); 148 | ``` 149 | 차트를 create 할 때에는 c3 의 generate 메소드를 사용하면 된다. bindto 속성에 chart 엘리먼드 id 를 넣어준다. 150 | data 의 column 속성에 data 값 들을 넣어준다. 151 | 152 | ```javascript 153 | var chart = c3.generate({ 154 | bindto: '#chart', 155 | data: { 156 | columns: [ 157 | ['data1', 30, 200, 100, 400, 150, 250], 158 | ['data2', 50, 20, 10, 40, 15, 25] 159 | ], 160 | axes: { 161 | data2: 'y2' 162 | }, 163 | types: { 164 | data2: 'bar' 165 | } 166 | }, 167 | axis: { 168 | y: { 169 | label: { 170 | text: 'Y Label', 171 | position: 'outer-middle' 172 | }, 173 | tick: { 174 | format: d3.format("$,") 175 | } 176 | }, 177 | y2: { 178 | show: true, 179 | label: { 180 | text: 'Y2 Label', 181 | position: 'outer-middle' 182 | } 183 | } 184 | } 185 | }); 186 | ``` 187 | ![c3.js](https://user-images.githubusercontent.com/35620465/98924474-36935480-2518-11eb-8425-794652f5d8d2.png) 188 | 189 | 위 처럼 axes, axis 를 활용 해서 축을 더 추가해줄 수도 있다. axis 내부적으로 x, y 축을 갖고 있다. 190 | 축에는 label 속성을 사용해서 라벨 이름도 붙여줄 수 있다. types 옵션을 이용해 데이터의 차트 표현 타입을 정해줄 수 있다. 191 | tick 은 축에 찍히는 값을 의미하는데 format이라는 속성을 통해서 각 축에 데이터를 어떤식으로 띄울지 설정할 수 있다. 192 | 차트 타입에는 Line Chart, Area Chart, Bar Chart, Donut Chart 등 다양한 차트들이 있다. 193 | 194 | ### 특징 195 | 1. D3 보다 사용하기 쉽다. 196 | 2. D3 보다 차트 표현? 에 더 특화되어 있는 느낌(?) 197 | 198 | ## [Chart.js](https://www.chartjs.org/) 199 | 200 | Chart.js 도 유명한 차트 라이브러리 중 하나이다. 사용법이 직관적이고 문서화도 잘 되어 있다. D3.js 는 러닝커브가 가파른데에 비해 Chart.js 는 Javascript 만 알고 있으면 몇분 안에 쉽게 차트를 만들 수 있다. 201 | Canvas 를 이용하여 그리기 때문에 반응형 레이아웃에서도 문제가 없다고 한다. 202 | (canvas를 div 로 감싸주고나 직접 width, height를 vw, vh 등으로 지정해준다.) 203 | 204 | 지원 브라우저 : Chrome, Firefox, Internet Explorer 11, Edge, Safari 205 | 206 | ### Creating a Chart 207 | 208 | ```html 209 | 210 | 249 | ``` 250 | 251 | 위 코드는 Chart.js 홈페이지 Introduction 섹션에 있는 가장 기본적인 코드이다. Chart.js 를 이번에 처음 보게 된 나도 코드만 보고 어떻게 흘러가는지 쉽게 파악할 수 있었다. 252 | 일단 new 키워드로 Chart 를 생성하고 type 속성으로 차트 type 을 정할 수 있고, data 속성에 필요한 데이터들을 바인딩 할 수 있다. 253 | 254 | ### Line 차트 255 | ![line 차트](https://user-images.githubusercontent.com/35620465/98826575-3728de00-2479-11eb-853f-27e11434dc40.png) 256 | 257 | ### Bar 차트 258 | ![Bar 차트](https://user-images.githubusercontent.com/35620465/98826584-3a23ce80-2479-11eb-806c-e2188f1bb696.png) 259 | 260 | ### Radar 차트 261 | ![Bar 차트](https://user-images.githubusercontent.com/35620465/98826588-3b54fb80-2479-11eb-8917-1878149c9557.png) 262 | 263 | etc... 264 | 265 | ### 특징 266 | 1. 비교적 쉽다. 267 | 2. 문서화가 잘 되어 있다. 268 | 3. 차트가 단순하고 간결하다. 269 | 4. 단순하고 간결한 만큼 더 복잡한 표현을 하기 위해서는 다른 라이브러리를 사용해야 한다. 270 | 271 | ## [AmCharts](https://amcharts.com) 272 | 273 | Amcharts 도 나름 차트 라이브러리를 고려할 때 빠지지 않고 등장하는 차트 라이브러리이다. 274 | 앞서 소개한 라이브러리 3가지와는 다르게 유료로 제공하고 있다. (amcharts 워터마크를 지우지 않고 사용하면 무료로 쓸 수 있다.) 275 | 유료인만큼 지원 항목이 다양하다. 대부분의 차트 라이브러리가 기본 자바스크립트 언어로만 쓰여 있지만, 276 | AmCharts 같은 경우에는 React, Vue, Angular 에서 사용은 물론 TypeScript, 웹팩, 코도바, 폰갭 등에서의 사용 가이드도 제공하고 있다. 277 | 278 | ### Creating a chart 279 | 280 | ```javascript 281 | 282 | 283 | 284 |
285 | 286 | 289 | 290 | 291 |
292 | 293 | 335 | 336 | 337 | ``` 338 | 기본적인 차트를 생성하려고 할 때 위처럼 html 을 작성한다. c3 와 비슷하게 chart div 엘리먼트를 만들어 차트를 그린다. 339 | 340 | ### 특징 341 | 1. 유료이다. 342 | 2. 학습 곡선이 가파르다. 343 | 3. 다양한 스타일의 차트를 사용할 수 있다. 344 | 4. 자유도가 높다. (자유도가 높은 만큼 커스터마이징을 하려면 학습이 필요하다.) -------------------------------------------------------------------------------- /S2_Round1/introduction-to-stateManagementTools.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JS 상태관리 도구 개론 3 | date: 2020-11-19 19:00:00 4 | author: wooooooood 5 | category: S2_Round1 6 | --- 7 | 8 | # JS 상태관리 도구 개론 9 | ## 상태관리의 필요성 10 | - 상태(데이터)가 언제, 어디서, 왜, 어떻게 변화했는지 알기 어렵다. 11 | - 다수의, 흩어진 Component가 같은 상태를 공유할 때 이를 관리하는 것이 복잡하다. 12 | - Component 단위에서는 props를 통해 하위 component로 상태를 전달한다. Component가 증가한다면 비효율적인 작업이 생길 수 있다. 13 | ![](https://miro.medium.com/max/375/1*GF62GAlhWKkSRd4uksoIkA.jpeg) 14 | 15 | => 이를 개선하기 위해 상태관리 도구 Redux, MobX, Recoil(React) 등이 나타났다. 16 | => 이 글에서는 FW에 구애받지 않는 JS 상태관리 도구인 Redux, MobX에 대해 간단하게 설명한다. 17 | 18 | ## Redux 19 | > A Predictable State Container for JS Apps 20 | - Functional Programming 21 | - Subscribe하는 모든 Component가 접근 가능한 Centralized global store로 상태를 관리한다. 22 | - `Immutability`를 유지하기 위해 원본 객체를 수정하는 것이 아닌, 객체의 복사본을 만들어 **복사된 객체**를 갱신한다. 23 | 24 | ex. 25 | ```js 26 | const arr = ['a', 'b'] 27 | const arrCopy = arr.concat('c') 28 | ``` 29 | 30 | ### 단방향 데이터 흐름 31 | ![Redux](https://postfiles.pstatic.net/MjAyMDAzMDhfMTQ2/MDAxNTgzNjMzNTQwNjUy.PXwD1gycPobFP3-IS7eiwI71_nk-ODsRk8KGiQJoU9cg.tPkdDd6GPW_gp6Uwt0l6oqkimD9Sn2kQIPNx2w_9o-0g.PNG.wj8606/JYrQR.png?type=w773) 32 | - **View**: 보여주기만 하는 순수 컴포넌트 33 | - **Action**: `Type`을 가진 JS객체로, User input, Trigger 등의 `Event`라고 생각할 수 있다. 34 | - **Reducer**: 현재 State와 Action을 감지하여 State를 갱신(바꿔치기)한다. `EventListener`와 유사하다. 35 | - **Store**: 현재 Redux의 State, 읽기 전용 36 | - **Middleware**: Action을 통해서 State를 바꾸기 전에 API호출 등 데이터가 변경되는 로직이 있을 때 비동기 작업 등을 처리할 수 있다. 37 | 38 | ### 단점 39 | - 애플리케이션이 복잡해질수록 `redux-saga`, `redux-thunk`, `redux-pack` 등의 라이브러리를 추가로 알아보는 것에 대한 부담? 40 | 41 | ## MobX 42 | > Simple, scalable state management 43 | - Object-Oriented Programming and Reactive Programming 44 | 45 | ### 데이터 흐름 46 | ![MobX](https://mobx.js.org/assets/getting-started-assets/overview.png) 47 | - **Application state**: Objects, arrays, primitives 등의 model이며 이러한 값들을 `data cell`이라고 한다. 48 | - **Derivation**: Application에서 자동으로 계산되는 모든 값. 49 | - **Reaction**:Derivation과 비슷하다. 차이점은, 값을 생성하지 않는 함수이며 Task를 수행하기 위해 자동으로 수행되며 주로 I/O 작업과 연관된다. (ex. DOM update, Network ..) 50 | - **Action**: State를 변경할 수 있는 모든 것을 의미하며 동기적으로 처리된다. 51 | 52 | ### 장점 53 | - 쉬운 편이다! 54 | 55 | ### 단점 56 | - 문서가 부실하다.. 57 | - 개발자 도구가 불편하다! 58 | - 애플리케이션이 커질수록 복잡해진다 (Store가 여러개이기 떄문에) 59 | 60 | ## Reference 61 | - [TECH CONCERT: FRONT END 2019 - 데이터 상태 관리. 그것을 알려주마](https://www.youtube.com/watch?v=o4meZ7MRd5o&feature=youtu.be) 62 | - [Why and When to use Redux](https://blog.usejournal.com/why-and-when-to-use-redux-b57f7dae9269) 63 | - [Redux overview](https://redux.js.org/tutorials/essentials/part-1-overview-concepts) 64 | - [MobX overview](https://mobx.js.org/getting-started) 65 | -------------------------------------------------------------------------------- /S2_Round1/lazyloading.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: LazyLoading 3 | date: 2020-11-19 00:00:00 4 | author: chjjh0 5 | category: S2_Round1 6 | --- 7 | 8 | ## 👀특징 9 | 10 | ![WhaleScreenCapture-20201121-211650](https://user-images.githubusercontent.com/39721166/99877284-398cf400-2c40-11eb-8054-14a8508002bc.jpg) 11 | 12 | - 의미: 페이지 진입 또는 현재 보여지는 화면을 기준으로 필요하지 않은 자원들은 필요할 때 로드 13 | - 활용점: Pagination, Infinite Scroll, Code Splitting 14 | - 장점 15 | 1.서버 부하 감소 및 사용자 속도 개선 16 | - 단점 17 | 1.스크롤에 따라 이미지를 로딩하기에 부자연스럽거나 버벅이게 로딩되는 현상을 볼 수 있음 18 | 2.검색엔진에 걸리지 않아 SEO 취약하나 콘텐츠에 대한 링크를 제공하여 보완 19 | [https://scarlett-dev.gitbook.io/all/it/lazy-loading](https://scarlett-dev.gitbook.io/all/it/lazy-loading) 20 | - 주의사항 21 | [https://black7375.tistory.com/72](https://black7375.tistory.com/72) 22 | 1.첫 화면에는 하지 않는 것이 나음 23 |   ( 콘텐츠 로드를 미뤄두기 때문에 SEO 좋지 않은 것으로 추정 ) 24 | 2.스크롤을 내려야 이미지 로드를 시작해 느려보일수도 있음 25 | 3.자리 표시자가 없으면 레이아웃 변경이 생길 수 있음 26 |   ( placeholder image가 없다면 브라우저 렌더링 악역향 ) 27 | 4.JS로 이미지 크기가 큰 이미지를 로딩 시 잠시 반응하지 않을 수 있음 28 |   ( 네트워크 환경에 따른 UX 저하 ) 29 | 5.로드가 실패할 수 있음 30 |   ( 네트워크 요청이 실패한 경우 placeholder image나 대체이미지가 없다면 UX 저하 ) 31 | 6. JS를 사용하지 못할 수도 있음 32 |   ( 브라우저의 JS 기능이 꺼있다면 동작X ) 33 | 34 | --- 35 |
36 |
37 |
38 | 39 | > HTML or Vanilla 40 | 41 | ### 1. loading 속성을 활용한 방식 42 | * img, iframe 에서 loading='lazy' 속성 사용 가능 43 | * 현재 실험단계 44 |
45 | 관련 포스팅 46 | 47 | [https://meetup.toast.com/posts/183](https://meetup.toast.com/posts/183) 48 | [https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading) 49 | [https://github.com/mfranzke/loading-attribute-polyfill](https://github.com/mfranzke/loading-attribute-polyfill) 50 |
51 |
52 | 53 | ### 2. preload 속성을 활용한 방식 54 | * video 태그에 preload=none 설정으로 로드 지연 55 |
56 | 관련 포스팅 57 | 58 | [https://web.dev/lazy-loading-video/](https://web.dev/lazy-loading-video/) 59 | [https://scarlett-dev.gitbook.io/all/it/lazy-loading](https://scarlett-dev.gitbook.io/all/it/lazy-loading) 60 |
61 |
62 | 63 | ### 3. scroll, resize, orientationChange 이벤트를 활용한 방식 64 | * 코드 참고한 포스팅: [https://frontdev.tistory.com/entry/Image-Lazy-Loading-기법](https://frontdev.tistory.com/entry/Image-Lazy-Loading-%EA%B8%B0%EB%B2%95) 65 | * 코드 링크: [https://codepen.io/imagekit_io/pen/MBNwKB](https://codepen.io/imagekit_io/pen/MBNwKB) 66 | * 링크된 코드의 동작 설명 67 | 68 | ```javascript 69 | HTML구조는 여러 개의 img 요소로 되어 있고 상단 3개의 img 요소에만 src 속성이 설정되어 있어, 초기에 3개의 이미지만 노출 70 | 71 | 2 lazyloadImages 변수에 img.lazy 클래스명을 가진 img 요소들의 배열 할당 72 | 26~28 scroll, resize, orientationChange 이벤트가 발생하면, 5 lazyload 함수를 실행 73 | 10 lazyloadThrottleTimeout 변수에 setTimeout 을 할당하여 추후 6~8 clearTimeout에 활용 74 | 11~17 lazyloadImages 배열을 반복하며 img의 offsetTop이 window.innerHeight + scrollTop 보다 작으면 data-src에 할당된 이미지 URL을 img src 속성에 할당하고 class에서 lazy를 제거하여 이미지를 노출 75 | 18~22 lazyloadImages가 빈 배열이면 scroll, resize, orientationChange 이벤트를 제거 76 | ``` 77 |
78 |
79 |
80 | 81 | > React 82 | ### 1. React.lazy 83 | 84 | * 컴포넌트 단위로 분리 가능 85 | * 라우트 단위로 도입하길 권장 86 | [https://ko.reactjs.org/docs/code-splitting.html#route-based-code-splitting](https://ko.reactjs.org/docs/code-splitting.html#route-based-code-splitting) 87 | 88 | * Img 태그에 적용한 사례 89 | [https://velog.io/@ansrjsdn/React.lazy-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0](https://velog.io/%40ansrjsdn/React.lazy-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0) 90 | 91 | * 주의사항 92 | - 아직 SSR에서는 지원 x 93 | [https://ko.reactjs.org/docs/code-splitting.html#reactlazy](https://ko.reactjs.org/docs/code-splitting.html#reactlazy) 94 | - Named Export 사용 95 | [https://ko.reactjs.org/docs/code-splitting.html#route-based-code-splitting](https://ko.reactjs.org/docs/code-splitting.html#route-based-code-splitting) 96 |
97 | 98 | ### 2. react-lazyload 99 | 100 | * resize, scroll 기반으로 작동되는 것으로 추정 101 |
102 | 관련 포스팅 103 | 104 | [https://github.com/twobin/react-lazyload](https://github.com/twobin/react-lazyload) 105 |
106 |
107 | 108 | ### 3. react-virtualized 109 | 110 | * 현재 사용자에 보여지는 부분만 렌더링하여 최적화 111 |
112 | 관련 포스팅 113 | 114 | [https://github.com/bvaughn/react-virtualized](https://github.com/bvaughn/react-virtualized) 115 | [https://bvaughn.github.io/react-virtualized/#/components/List](https://bvaughn.github.io/react-virtualized/#/components/List) 116 | [https://coffeeandcakeandnewjeong.tistory.com/52](https://coffeeandcakeandnewjeong.tistory.com/52) 117 |
118 |
119 | 120 | ### 4. react-window 121 | 122 | * react-virtualized와 같은 역할이며 보다 경량화 123 |
124 | 관련 포스팅 125 | 126 | [https://react-window.now.sh/#/examples/list/fixed-size](https://react-window.now.sh/#/examples/list/fixed-size) 127 | [https://velog.io/@pandati0710/React-Windowing](https://velog.io/%40pandati0710/React-Windowing) 128 |
129 |
130 |
131 |
132 | 133 | > Vue 134 | ### 1. Code Splitting with webpack 135 | 136 | * webpack으로 chunk 파일 분할하여 분할된 파일에 대한 요청이 들어왔을 때 서빙 137 |
138 | 관련 포스팅 139 | 140 | [https://gongzza.github.io/javascript/vuejs/vue-lazy-loading-with-webpack/](https://gongzza.github.io/javascript/vuejs/vue-lazy-loading-with-webpack/) 141 | [https://router.vuejs.org/kr/guide/advanced/lazy-loading.html](https://router.vuejs.org/kr/guide/advanced/lazy-loading.html) 142 |
143 | 144 | ### 2. vue-lazyload 145 | 146 | * resize, scroll 기반으로 동작하지만, intersection observer도 활용 가능 147 |
148 | 관련 포스팅 149 | 150 | [https://github.com/hilongjw/vue-lazyload#readme](https://github.com/hilongjw/vue-lazyload#readme) 151 |
-------------------------------------------------------------------------------- /S2_Round1/nextjs_tutorial_ch1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: nextjs_tutorial_ch1 3 | date: 2020-11-17 12:00:00 4 | author: dev-owen 5 | category: S2_Round1 6 | --- 7 | 8 | # Next.js에 대해서 알아보자 #1. Intro 9 | 10 | Next.js는 React에서 기존에 CSR(Client Side Rendering)의 특징에 더하여 SSR(Servers Side Rendering)을 혼합하여 운영환경에서 최적의 퍼포먼스를 낼 수 있게 도와주는 프레임워크이다. 2020년 11월 현재 버전 10.0.1이 나와있으며 다음과 같은 기능들을 지원한다. 11 | 12 | - 페이지 기반 라우팅 (동적 라우팅) 13 | - 데이터 패칭 14 | - 빠른 성능을 위한 코드 스플리팅 15 | - CSS in JS 16 | - 이미지 최적화 17 | - 빠른 컴포넌트 재활성화 18 | - 정적 파일 처리 19 | - 타입스크립트 20 | - 환경 변수 21 | - 브라우저 지원 22 | 23 | 각각에 대한 자세한 사항들은 이후에 하나씩 알아보고자 한다. 24 | 25 |
26 | 27 | Next.js는 SPA에서 CSR이 가질 수 밖에 없는 한계들을 보완해 주는 도구이다. SSR과 CSR에 대한 포스팅 참고 28 | 29 | CSR은 초기 로딩 속도가 전통적인 SSR 방식에 비해 길다. 그 이유는 브라우저에서 화면을 렌더링하는데 필요한 모든 파일(HTML, CSS, JS, 이미지와 같은 대용량 파일 등)을 전부 받아온 다음 렌더링을 하기 때문이다. 그리고 이처럼 초기 로딩속도가 느리면 SEO(검색 엔진 최적화) 측면에서도 불리할 수밖에 없게 된다. 이러한 단점들을 극복하기 위한 도구 중 하나가 React에서는 Next.js인 것이다. 30 | 31 | Next.js를 통해서 Node 서버 기반의 페이지를 만들 수가 있는데 (SSR), 페이지를 이동할 때마다 필요한 JSON 데이터를 가져올 수도 있고 (CSR) 이 두 가지 렌더링 방식을 필요에 맞게 적절하게 섞어쓸 수 있다는 점이 장점이다. 예를 들어 블로그와 같이 정적인 컨텐츠가 많은 페이지는 SSR, 페이스북 뉴스피드 같이 실시간으로 사용자 인터랙션이 많은 페이지는 CSR을 사용할 수가 있다. 32 | 33 | 성능을 최적화 하는 과정에서도 Next.js가 많은 도움을 준다. 그 중 한 가지 방법은 pre-rendering이다. 서버사이드에서 빌드 중 실행되는 getStaticProps 함수를 통해 페이지 렌더링에 필요한 데이터를 받아오고 이와 같이 pre-rendering된 페이지는 초기 페이지 로딩이 CSR에 비해 빠르며, SEO 관점에서도 유리하다. 또 다른 방법은 code-splitting이다. 라우트 기반의 코드 스플리팅은 한 번에 파싱&컴파일 되어야 하는 코드의 양을 최소화 시켜주며 결과적으로 페이지 로드 시간의 단축을 이끌어낼 수 있다. 34 | 35 |
36 | 37 | 간단한 Next.js app을 만들면서 연습해 보자 38 | 39 | ```shell script 40 | mkdir nextjs-tutorial 41 | cd nextjs-tutorial 42 | npm init 43 | npm install --save next react react-dom 44 | ``` 45 | package.json 파일에 간단한 스크립트를 추가한다. 46 | 47 | ```javascript 48 | // package.json 49 | { 50 | "scripts": { 51 | // ... 52 | "dev": "next", 53 | "build": "next build", 54 | "start": "next start" 55 | } 56 | } 57 | ``` 58 | 59 | next.js는 pages 폴더에 route와 동일한 이름의 컴포넌트로 만들어야 한다는 규칙이 있다. 예를 들어 url이 /about 이면 해당 컴포넌트는 pages/about.jsx와 같이 만들어 져야 한다. 60 | ```javascript 61 | // pages/about.jsx 62 | 63 | import React from 'react'; 64 | 65 | const About = (props) => { 66 | const {message} = props; 67 | 68 | return ( 69 |
70 |

Hello World!

71 |

{message}

72 |
73 | ); 74 | }; 75 | 76 | export async function getStaticProps(context) { 77 | return { 78 | props: { 79 | message: `Next.js` 80 | } 81 | }; 82 | }; 83 | 84 | export default About; 85 | ``` 86 | 87 | 88 | 이와 같이 컴포넌트를 하나 만들어 준 후 89 | ```shell script 90 | npm run build && npm run dev 91 | ``` 92 | 93 | 빌드 후 실행하면 .next 폴더가 하나 생성된다. 그리고 나서 localhost:3000에 방금 만든 app이 실행되고 있는 것을 볼 수 있다. 94 | 95 | 이렇게 정말 간단한 next.js app을 하나 시작해 보았다. 다음 포스팅에서는 페이지를 추가하고, 동적 데이터를 추가하는 작업을 하는 튜토리얼을 포스팅 해 보려고 한다. 96 | 97 | 98 | ## 참고자료 99 | - [Next.js 공식문서](https://nextjs.org/) 100 | - [Next.js로 Static Site 만들기](https://medium.com/@pks2974/nextjs-%EB%A1%9C-static-site-%EB%A7%8C%EB%93%A4%EA%B8%B0-f9ab83f29e7) 101 | - [Next.js 튜토리얼](https://brunch.co.kr/@hee072794/81) 102 | - [nextjs는 어떻게 동작하는가?](https://blueshw.github.io/2018/04/15/why-nextjs/) 103 | 104 | -------------------------------------------------------------------------------- /S2_Round1/rxjs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: RxJS R아보기 3 | date: 2020-11-19 00:00:00 4 | author: symoon 5 | category: S2_Round1 6 | --- 7 | 8 | 9 | # RxJS R아보기 10 | 11 | 12 | ## RxJS란 무엇인가 13 | 14 | > "An API for asynchronous programming with observable streams" 15 | 16 | **R**eactive e**X**tensions Library for **J**ava**S**cript의 약자로, 옵저버 패턴을 통해 이벤트 스트림을 제어하여 비동기 프로그래밍을 처리하는 (API를 제공하는) 라이브러리이다. 현재 안정화 버전은 6이며, 베타 버전인 7까지 나와있다. Angular에는 이 RxJS가 기본적으로 내장되어 있다. 17 | 18 | 19 | 20 | ## Reactive? Stream? Observable? 그게 다 뭔데?! 21 | 22 | ### Reactive Programming 23 | 24 | ![마블 다이어그램](http://reactivex.io/assets/operators/legend.png "이미지 출처: http://reactivex.io/documentation/ko/observable.html") 25 | 26 | 리액티브 프로그래밍은 말그대로 "반응형"으로 프로그래밍하는 것이다. 27 | 명령형 프로그래밍은 개발자가 작성한 코드에 따라 순서대로 코드가 실행되며, 데이터가 필요하면 요청을 해야한다(외부 환경에서 데이터를 당겨오는 방식인 Pull). 반면, 리액티브 프로그래밍은 데이터 스트림을 구독하고 있다가 데이터에 어떠한 변화가 감지되었을 때 그것에 **반응**하여 데이터를 얻는 방식이다(외부 환경이 데이터를 내보내는 방식인 Push). 28 | 29 | ### Stream 30 | 데이터를 하나의 연속적인 흐름으로 보는 것이다. 위에서 언급했듯, 리액티브 프로그래밍 방식에서는 이 데이터 스트림을 구독한다. 리액티브 프로그래밍 방식에서 이 스트림은 Observable 객체로 만들어진다. 31 | 32 | ### Observable 33 | Observable은 데이터 스트림을 만들고 내보내는 객체이고, Observer는 이 옵저버블 객체가 내보낸 데이터를 받아 가공하는 역할을 하는 객체이다. 34 | 35 | #### Observable 생성 36 | Observable객체를 생성하는 연산자는 `create`, `from`, `fromEvent`, `fromPromise`, `of` 등이 있다. 37 | 이중 일반적으로 `from`, `fromPromise`, `of`가 많이 사용된다. 38 | 39 | 일반적으로 이벤트 리스너를 등록하는 방식은 아래와 같다. 40 | 41 | var button = document.querySelector('button'); 42 | button.addEventListener('click', () => console.log('Clicked!')); //버튼 클릭 이벤트가 발생하면 콘솔로그에 'Clicked!'를 찍음 43 | 44 | 45 | RxJS에서는 연산자를 이용하여 아래와 같이 생성할 수 있다. 46 | 47 | var button = document.querySelector('button'); 48 | 49 | Rx.Observable.fromEvent(button, 'click') //클릭 이벤트를 emit하는 Observable 객체를 생성함 50 | .subscribe(() => console.log('Clicked!')); //체이닝을 이용해 해당 Observable 객체를 구독하며, Observable에서 데이터 전달시 콜백함수 51 | 52 | 53 | * 참고 54 | fromEvent 연산자는 이벤트를 Observable 시퀀스로 만들어줌 55 | `fromEvent(target: EventTargetLike, eventName: string, selector: function): Observable` 56 | 57 | 58 | #### 옵저버 메소드 59 | `onNext` 새로운 데이터를 내보낼 때 호출되는 메소드. 파라미터를 통해 옵저버블을 전달한다. 60 | `onError` 데이터가 생성되지 않았거나 오류가 발생할 경우 호출되는 메소드. 이 메소드가 호출되면 `onNext`나 `onComplete`가 호출되지 않음. 61 | `onComplete` 오류가 없으면 마지막 `onNext`를 호출한 후 호출되는 메소드 62 | 63 | 64 | #### 연산자 65 | RxJS에서 제공하는 대부분의 연산자는 이 옵저버블 객체에서 동작하고, 옵저버블 객체를 반환한다. 즉, 연산자 체이닝이 가능하다. 이 연산자 체인은 순서에 따라 결과가 달라지므로 순서대로 실행되어야한다. 66 | 대표적인 연산자는 `create`, `map`, `merge` 등이 있다. 67 | 68 | 69 | #### 예제코드 70 | 코드 71 | 72 | import { Observable } from 'rxjs'; 73 | 74 | //Observable 객체를 생성한다.(관찰 가능한 상태로 만드는 것) 75 | //해당코드를 구독하면 즉시 값(1,2,3)을 내보내고, 1초 후에 4를 내보낸뒤 완료처리된다. 76 | const observable = new Observable(subscriber => { 77 | subscriber.next(1); 78 | subscriber.next(2); 79 | subscriber.next(3); 80 | setTimeout(() => { 81 | subscriber.next(4); 82 | subscriber.complete(); 83 | }, 1000); 84 | }); 85 | 86 | console.log('just before subscribe'); //가장 먼저 실행된다. 87 | 88 | //위에서 생성한 observable을 구독한다. 89 | observable.subscribe({ 90 | next(x) { console.log('got value ' + x); }, //새로운 값을 받아 콘솔을 찍는다. 91 | error(err) { console.error('something wrong occurred: ' + err); }, //에러가 발생했을 경우 콘솔을 찍는다. 92 | complete() { console.log('done'); } //마지막 next 실행 후 콘솔을 찍는다. 93 | }); 94 | console.log('just after subscribe'); 95 | 96 | 실행결과 97 | 98 | just before subscribe 99 | got value 1 100 | got value 2 101 | got value 3 102 | just after subscribe //RxJS는 동시에 여러 코드가 실행 가능하기 때문에, 1초 사에에 다음 코드가 실행됨. 103 | got value 4 //setTimeout으로 인해 1초 후 내보내짐 104 | done 105 | 106 | 107 | ## 그래서 RxJS, 뭐가 좋은건데? 108 | 콜백, 프로미스 방식의 한계를 보완할 수 있다. 한 번에 하나의 데이터만 처리할 수 있는 프로미스와 달리 데이터를 스트림으로 만들기 때문에 *동기 / 비동기에 관계 없이 데이터를 일관적으로 처리 가능*하며, *연속성을 가진 데이터를 처리*할 수 있다. 그러면서도 연산자 체이닝을 통해 비동기를 효과적으로 처리하며, 프로미스 방식은 한 번 실행되고 나면 요청을 취소할 수가 없지만 옵저버블은 취소가 가능하다.(`unsubscribe()`를 통해 구독 취소가 가능함) 109 | 또한 하나의 코드가 실행결과를 리턴할 때까지 기다릴 필요없이 다음 코드를 실행할 수 있어, *한 번에 여러 코드를 실행 가능*하다. 110 | 111 | 단점은, 초기 학습 비용이 크다는 점. 112 | 113 | --- 114 | ### 참고 115 | 116 | http://reactivex.io/ 117 | 118 | https://velog.io/@dvmflstm/RxJS-Practice 119 | 120 | https://poiemaweb.com/angular-rxjs 121 | 122 | https://tienne.gitbooks.io/learnrxjs/content/ 123 | 124 | https://hyunseob.github.io/2016/10/09/understanding-reactive-programming-and-rxjs/ 125 | 126 | https://rxjs-dev.firebaseapp.com/ 127 | -------------------------------------------------------------------------------- /S2_Round1/storybook.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: storybook 3 | date: 2020-11-26 00:00:00 4 | author: chjjh0 5 | category: S2_Round1 6 | --- 7 | 8 | ## 특징 9 | 10 | - bootstrap, materialUI 같은 CSS 프레임워크에서 제공하는 요소 팔레트와 유사하게 컴포넌트를 관리 11 | - 컴포넌트 문서화를 통해 테스트, 유지보수에 유용 12 | - 다양한 환경에서 활용 가능 (HTML, React, Vue, Svelte 등) 13 |
14 |
15 |
16 | 17 | > 기본 사용법 18 | 19 | ```javascript 20 | // CRA로 React Project 생성 21 | npx create-react-app taskbox 22 | 23 | // 생성된 프로젝트에 스토리북 추가 & 초기화 24 | npx -p @storybook/cli sb init 25 | 26 | // 스토리북 실행 27 | npm run storybook 28 | ``` 29 | 30 | ### sb init, 스토리북 초기화 [(링크)](https://storybook.js.org/docs/react/get-started/install) 31 | 32 | - 사용자가 직접 작성해야할 것들이 자동으로 추가됨 33 | 1. package.json에 dependencies, scripts 추가 34 | 35 | ```javascript 36 | "devDependencies": { 37 | "@storybook/addon-actions": "^6.1.3", 38 | "@storybook/addon-essentials": "^6.1.3", 39 | "@storybook/addon-links": "^6.1.3", 40 | "@storybook/node-logger": "^6.1.3", 41 | "@storybook/preset-create-react-app": "^3.1.5", 42 | "@storybook/react": "^6.1.3" 43 | } 44 | "scripts": { 45 | "start": "react-scripts start", 46 | "build": "react-scripts build", 47 | "test": "react-scripts test", 48 | "eject": "react-scripts eject", 49 | "storybook": "start-storybook -p 6006 -s public", 50 | "build-storybook": "build-storybook -s public" 51 | }, 52 | ... 53 | ``` 54 | 55 | 2. storybook 폴더에 storybook 설정 파일 추가
56 | ![stories config files](https://user-images.githubusercontent.com/39721166/100541483-9cf1d400-3287-11eb-9094-cbaedf249f9e.png) 57 | 58 | 59 | 3. stories 폴더에 보일러플레이트 파일들 추가
60 | ![stories folder capture](https://user-images.githubusercontent.com/39721166/100540900-a5e0a680-3283-11eb-9ed6-085566474e9b.png) 61 | 62 |
63 |
64 | 65 | > 예제 66 | 67 | Button.js 68 | 69 | ```javascript 70 | export const Button = ({ primary, backgroundColor, size, label, ...props }) => { 71 | // primary or secondary 모드 72 | const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary'; 73 | 74 | return ( 75 | 83 | ); 84 | }; 85 | ``` 86 | 87 | Button.css 88 | 89 | ```css 90 | .storybook-button { 91 | font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; 92 | font-weight: 700; 93 | border: 0; 94 | border-radius: 3em; 95 | cursor: pointer; 96 | display: inline-block; 97 | line-height: 1; 98 | } 99 | .storybook-button--primary { 100 | color: white; 101 | background-color: #1ea7fd; 102 | } 103 | .storybook-button--secondary { 104 | color: #333; 105 | background-color: transparent; 106 | box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; 107 | } 108 | .storybook-button--small { 109 | font-size: 12px; 110 | padding: 10px 16px; 111 | } 112 | .storybook-button--medium { 113 | font-size: 14px; 114 | padding: 11px 20px; 115 | } 116 | .storybook-button--large { 117 | font-size: 16px; 118 | padding: 12px 24px; 119 | } 120 | ``` 121 | 122 | Button.stories.js 123 | 124 | ```javascript 125 | import React from 'react'; 126 | 127 | import { Button } from './Button'; 128 | 129 | export default { 130 | title: 'Example/Button', 131 | component: Button, 132 | argTypes: { 133 | backgroundColor: { control: 'color' }, 134 | }, 135 | }; 136 | 137 | const Template = (args) =>