우아한 테크러닝 DAY 6
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 말고!
- 커링 예시 ; 사용자의 개입이 커지는 방식
```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
- 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에서 비즈니스 로직을 빼낼 수 있음***