우아한 테크러닝 DAY 6

3 minute read

webpack

https://webpack.js.org/contribute/writers-guide/
아무것도 개발환경 설정하지 않고 써먹을 수 있는거 외에도 rollup도 있고.. 간단함!
웹팩은 플랫폼 그냥 기차역일 뿐, 웹팩은 CLI, CREATE-REACT-APP 대신 쓰는 것 웹팩이 하는 일

  • Loader
    converting : 입력으로 들어온 소스코드 조작
    웹팩은 build 하는 애 ; 첫번째 js 파일부터 계속 불러들이면서 code merging webpack.config.js에 entry에 진입점이 나와 있음
    그 진입점을 loader에게 던져주고 그 이후 일을 쭉쭉
    ex: babel-loader(이 바벨만의 설정과 플러그인도 다 있음, 바벨은 transfiling[<->compiling 알아둘 것]), file-loader test: 확장자, include: 포함, exclude: 비포함, loader: 로더 설정
  • plugin
    후처리 : 어떻게 얘를 처리하나! 로더의 processing이 끝나면 하는 친구
    환경변수 설정, 청소, 등등
    완전 가벼운 vanila 만들어보는거 부터 다뤄보기 boilerplate 말고!

https://joshua1988.github.io/webpack-guide/tutorials/code-splitting.html#%EC%8B%A4%EC%8A%B5-%EC%A0%88%EC%B0%A8

  • 커링 예시 ; 사용자의 개입이 커지는 방식
    ```js const discountAmount = (price, discount) => { return price * discount; } //함수는 똑같지만 써먹을 여지가 없고

const discAmount = discount => price => { return price * discount; } //여지가 많고 const x = discAmount(0.5);

cosole.log(x(50000));


## 실제 react, redux, saga로 만들어보자!  
<https://codesandbox.io/s/ordermonitor04-n51jrkq2wl?file=/src/index.tsx>  
- types  
```js
export interface StoreState {
  monitoring: boolean;
  success: number;
  failure: number;
}
  • actions
    ```js import { createAction } from “typesafe-actions”;

export const startMonitoring = createAction( “@command/monitoring/start”, //redux가 reducer한테 준 default action 그냥 쓴거 의미 x resolve => { return () => resolve(); } );

export const stopMonitoring = createAction( “@command/monitoring/stop”, resolve => { return () => resolve(); } );

export const fetchSuccess = createAction(“@fetch/success”, resolve => { return () => resolve(); });

export const fetchFailure = createAction(“@fetch/failure”, resolve => { return () => resolve(); });

- index.tsx  
```js
import * as React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import { StoreState } from "./types";
import reducer from "./reducers";
import createSagaMiddleware from "redux-saga";
import rootSaga from "./sagas";     //rootSaga는 middleware
import App from "./App";

const sagaMiddleware = createSagaMiddleware();
const store: StoreState = createStore(reducer, applyMiddleware(sagaMiddleware));
const rootElement: HTMLElement = document.getElementById("root");

sagaMiddleware.run(rootSaga);

render(
  <Provider store={store}>
    <App />
  </Provider>,
  rootElement
);
  • reducer
    ```js import { ActionType, getType } from “typesafe-actions”; import { StoreState } from “../types”; import * as Actions from “../actions”;

const initializeState: StoreState = { monitoring: false, success: 0, failure: 0 };

export default ( state: StoreState = initializeState, action: ActionType ) => { switch (action.type) { case getType(Actions.fetchSuccess): return { ...state, success: state.success + Math.floor(Math.random() * (100 - 1) + 1) }; case getType(Actions.fetchFailure): return { ...state, failure: state.failure + Math.floor(Math.random() * (2 - 0)) }; default: console.log(action.type); return Object.assign({}, state); } };

- saga  
```js
import { fork, all, take, race, delay, put } from "redux-saga/effects";
//fork, take 등등은 객체를 만드는 dom함수
//saga한테 함수를 만들어서 내가 무슨 일을 하고 싶은건지 전달하는 것

import { getType } from "typesafe-actions";
import * as Actions from "../actions";

//이 flow를 이해하면 전체 느낌 아는 것~
function* monitoringWorkflow() {
  while (true) {
    yield take(getType(Actions.startMonitoring));   //getType 헬퍼함수 뽑아서 문자열로 붙여두는 애

    let loop = true;

    while (loop) {
      yield all([//yield의 all은 몇초에 한번 갖고 오라는걸 dispatch
        put({ type: getType(Actions.fetchSuccess) }),
        put({ type: getType(Actions.fetchFailure) })
      ]);

      const { stoped } = yield race({//race는 먼저 된 애를 줘
        waitting: delay(200),
        stoped: take(getType(Actions.stopMonitoring))
      });

      if (stoped) {
        loop = false;
      }
    }
  }
}

export default function* () {
  yield fork(monitoringWorkflow);
}
  • redux toolkit(action, reducer를 한번에 만들어 관리함)으로 싹 converting 해보기 saga의 예제
    //rootSaga는 function*()으로 generator : 호출자와 핑퐁할 수 있는  
    //yield 되면(나가면) 또 들어오고 나가고 들어오고
    function* rootSaga(){
      yield { id: "@init" };  //안쪽에서 바깥으로 정보 전달
      yield { id: "@inc" };
      yield { id: "@put" };
      console.log(rootSaga);  //다 하고 1234 찍혀있음
    }
    const root = rootSaga();    //root는 호출을 준비할 수 있는 generator
    console.log(root.next());  //next()오면 yield나 return을 만날때까지 실행됨 
    console.log(root.next('1234'));
    

    ***결과적으로 saga를 사용하면 ui에서 비즈니스 로직을 빼낼 수 있음***