May 23, 2020 ( last updated : May 22, 2020 )
deno
svelte
redux
mobx
https://github.com/gmm117/gmm117.github.io
deno, svelte, redux, mobx
상태에 어떠한 변화가 필요하게 될 땐, 우리는 액션이란 것을 발생시킵니다. 이는, 하나의 객체로 표현되는데요, 액션 객체는 다음과 같은 형식으로 이뤄져있습니다.
{
type: "TOGGLE_VALUE"
}액션 객체는 type 필드를 필수적으로 가지고 있어야하고 그 외의 값들은 개발자 마음대로 넣어줄 수 있습니다.
{
type: "ADD_TODO",
data: {
id: 0,
text: "리덕스 배우기"
}
}액션 생성함수는, 액션을 만드는 함수입니다. 단순히 파라미터를 받아와서 액션 객체 형태로 만들어주죠.
function changeColor(color) {
return {
type: "CHANGE_COLOR",
color
};
}
const changeColor = color => ({
type: "CHANGE_COLOR",
color
});리듀서는 변화를 일으키는 함수입니다. 리듀서는 두가지의 파라미터를 받아옵니다.
function reducer(state, action) {
if(state === undefined) {
return {color : "yellow"};
}
var newState;
if(action.type === 'CHANGE_COLOR') {
newState = Object.assign({}, state, {color: action.color})
}
return newState;
}리듀서는, 현재의 상태와, 전달 받은 액션을 참고하여 새로운 상태를 만들어서 반환합니다.
리덕스에서는 한 애플리케이션 당 하나의 스토어를 만들게 됩니다. 스토어 안에는, 현재의 앱 상태와, 리듀서가 들어가있고, 추가적으로 몇가지 내장 함수들이 있습니다.
var store = Redux.createStore(reducer);디스패치는 스토어의 내장함수 중 하나입니다. 디스패치는, 액션을 발생 시키는 것 이라고 이해하시면 됩니다. dispatch 라는 함수에는 액션을 파라미터로 전달합니다.. dispatch(action) 이런식으로 말이죠.
그렇게 호출을 하면, 스토어는 리듀서 함수를 실행시켜서 해당 액션을 처리하는 로직이 있다면 액션을 참고하여 새로운 상태를 만들어줍니다.
store.dispatch({type: 'CHANGE_COLOR', color: 'red'})구독 또한 스토어의 내장함수 중 하나입니다. subscribe 함수는, 함수 형태의 값을 파라미터로 받아옵니다. subscribe 함수에 특정 함수를 전달해주면, 액션이 디스패치 되었을 때 마다 전달해준 함수가 호출됩니다.
store.subscribe(green);https://github.com/supreme-developer/redux/tree/master/used-redux
MobX 를 사용하고 있는 앱의 상태는 Observable 합니다. 이를 직역하자면 이 상태는 관찰 할 수 있는 상태인데요, 어쩌면 관찰 받고 있는 상태라고 이해하는게 조금 더 쉬울 수도 있겠습니다. 우리의 앱에서 사용하고있는 상태는, 변할 수 있으며, 만약에 특정 부분이 바뀌면, MobX 에서는 정확히 어떤 부분이 바뀌었는지 알 수 있습니다. 그 값이, 원시적인 값이던, 객체이던, 배열 내부의 객체이던 객체의 키이던 간에 말이죠.
// Observable State 만들기
const calculator = observable({
a: 1,
b: 2
});연산된 값은, 기존의 상태값과 다른 연산된 값에 기반하여 만들어질 수 있는 값입니다. 이는 주로 성능 최적화를 위하여 많이 사용됩니다. 어떤 값을 연산해야 할 때, 연산에 기반되는 값이 바뀔때만 새로 연산하게 하고, 바뀌지 않았다면 그냥 기존의 값을 사용 할 수 있게 해줍니다.
이를 이해하기 위해 간단한 예시를 들어보겠습니다. 우리가 편의점에서 800원짜리 물을 네병 샀는데 이게 얼마나오지? 하고 체크하는 함수 total() 이라는 함수가 있다고 가정하겠습니다. 우리가 처음 머릿속으로 계산할때 암산으로 4 * 8 에 32! 라면서 3,200 원이군, 하고 간단히 계산을 하겠죠. 잠시 후에 친구가 그거 다 얼마냐고 또 물어봅니다. 이 때 우리는 머릿속에서 별 생각안하고 응 3,200원이야 라고 말합니다. 친구가, 나도 한병 사줘! 하면 이때 다시 우리는 무의식중에 800원을 더해서 우리가 내야 할 돈이 4,000원인걸 연산합니다.
// computed 로 특정 값 캐싱
const sum = computed(() => {
console.log('계산중이예요!');
return calculator.a + calculator.b;
});Reactions 는 Computed Value 와 비슷한데요, Computed Value 의 경우는 우리가 특정 값을 연산해야 될 때 에만 처리가 되는 반면에, Reactions 은, 값이 바뀜에 따라 해야 할 일을 정하는 것을 의미합니다. 예를 들어서 Observable State 의 내부의 값이 바뀔 때, 우리가 console.log(‘ㅇㅇㅇ가 바뀌었어!’) 라고 호출해 줄 수 있습니다.
// 특정 값이 바뀔 때 특정 작업 하기!
reaction(
() => calculator.a,
(value, reaction) => {
console.log(`a 값이 ${value} 로 바뀌었네요!`);
}
);액션은, 상태에 변화를 일으키는것을 말합니다. 만약에 Observable State 에 변화를 일으키는 코드를 호출한다? 이것은 하나의 액션입니다. - 리덕스에서의 액션과 달리 따로 객체형태로 만들지는 않습니다.
select(name, price) {
this.basket.push({ name, price });
}
decorate(GS25, {
select: action // **** 액션 명시
});
select('포카칩', 1500)https://github.com/gmm117/mobx/tree/master/origin-mobx
Svelte(스벨트)는 Rich Harris가 제작한 새로운 접근 방식을 가지는 프론트엔드 프레임워크입니다. Svelte는 자신을 ‘프레임워크가 없는 프레임워크’ 혹은 ‘컴파일러’라고 소개합니다. 이는 Virtual(가상) DOM이 없고, Runtime(런타임)에 로드할 프레임워크가 없음을 의미합니다. 기본적으로 빌드 단계에서 구성 요소를 컴파일하는 도구이므로 페이지에 단일 번들(bundle.js)을 로드하여 앱을 렌더링할 수 있습니다.
Svelte는 DOM의 변화가 있을 때 그 부분만 업데이트하므로 실행 속도가 매우 빠르다. React, Vue.js 같이 가상 DOM을 사용하는 프레임워크와 대조적으로 Svelte는 가상 DOM을 사용하지 않는다.
가상 DOM 프레임워크는 실제 DOM에 변경을 커밋하기 전 보이지 않는 트리에서 컴포넌트를 그리기 위한 시간을 소비하는 반면, Svelte는 이런 중간 단계를 뛰어넘고 바로 변경한다. DOM 업데이트가 느릴수는 있지만, Svelte는 어떤 요소에 변화가 일어났는지 정확하게 알고 있기 때문에 빠르게 처리할 수 있다.
또한, Svelte는 개발 속도를 매우 빠르게 할 수 있다. 일반적으로 같은 내용의 컴포넌트를 만들 때 Svelte 컴포넌트는 React보다 적은 코드로 생성할 수 있다.
<script>
export let name;
let count = 1;
$: double = count * 2;
</script>
<main>
<h1 id="root">Hello {name}!</h1>
<h1> count : {double}</h1>
<button on:click={() => count += 1}>increase</button>
</main>
번들 크기가 이렇게 작을 수 있는 이유는 Svelte는 프레임워크이자, 컴파일러이기 때문이다.
아마 당신은 React Project를 컴파일하기 위해 yarn build를 실행하는데 익숙할 것이다. Webpack과 Babel을 호출하여 프로젝트 파일을 번들링 한 뒤, 최소화(minify) 하고, react와 react-dom 라이브러리를 번들에 추가한 뒤, 그 파일을 최소화(minify)하고, 하나의 출력 파일을(혹은 몇 개의 chunk로 분리된 파일을) 생성한다.
반면 Svelte는, 자체적으로 컴포넌트를 컴파일할 수 있다. 결과는 (앱) + (Svelte 런타임 환경)이 아닌, (Svelte가 독자적으로 실행하는 방법을 알려준 앱) 이다. Svelte는 Rollup(혹은 Webpack)의 트리 쉐이킹 이점을 가져와 이용하여 내 코드에서 사용하는 프레임워크의 부분만을 포함해 자체적으로 만든다.
컴파일 된 앱은 여전히 작성한 컴포넌트를 구동시키기 위해 조금의 Svelte 코드를 갖게 된다. 마법처럼 그 코드는 전부 사라지지 않는다. 하지만 이런 부분은 다른 프레임워크들이 작동하는 방법과 반대이다. 대부분의 프레임워크는 실제로 앱을 실행하고, 나타내기 위해 존재해야한다.
$ npx degit sveltejs/template svelte
$ cd svelte
$ npm install
$ npm run devhttps://github.com/gmm117/svelte
https://heropy.blog/2019/09/29/svelte/ https://ui.toast.com/weekly-pick/ko_20191002/ https://velog.io/@ashnamuh/hello-svelte
node.js를 만든 Ryan Dahl이 JS Fest 2019 Spring 컨퍼런스에서 새 프로젝트인 ‘Deno’를 소개했습니다. ‘A New Way to JavaScript’라는 제목의 이 발표에서 Ryan은 Deno가 node.js와 어떻게 다른지, 어떤 부분에서 새로워졌는지를 설명합니다. 도전적인 이 프로젝트에 관심 있으신 분들을 위해 축약, 정리해보았습니다.

JSConf EU 2018에서 Node.js에 후회했던 10가지(10 Things I Regret About Node.js)를 발표하면서 새로운 서버사이드 언이인 Deno를 발표하였습니다.
// node.js
var http = require("http");
http.createServer(function(req, res)
{
res.write("Hello World\n");
res.end();
}).listen(8000, function() {
console.log("http://localhost:8000/");
});// deno.js
import { http } from "https://deno.land/std@v0.12/http/server.ts";
const body = new TextEncoder().encode("Hello World\n");
const s = http(":8000");
window.onload = async () => {
console.log("http://localhost:8000/");
for await (const req of s) {
req.respond({ body });
}
};Promises를 고집하지 않은 것(Not sticking with Promises) Node.js를 작업하는 대부분의 사람들은 이 말에 100% 공감할 겁니다. Node.js의 비동기 호출은 여전히 콜백 API를 기준으로 되어 있습니다. Promises는 Async, Await을 제공하기 위해서 필수였죠. 라이언 달은 2009년에 Promises를 추가했다가 2010년에 삭제한 것을 언급하면서 자신이 Promises를 계속 고집했다면 커뮤니티 소스가 더 빨리 Async Await으로 진보했을 것이라며 후회했습니다.
보안 문제에 더 신경 쓰지 못한 것(Security) V8에 대해서는 그 자체로 훌륭한 샌드박스 모델을 가지고 있다는 것을 언급하며 다만 Node 응용 프로그램이 어떻게 유지ᆞ발전될지를 고려했다면 다른 언어들이 갖지 못한 보안성을 갖출 수 있었을 거라는 후회를 남겼습니다. (V8은 Node.js의 JavaScript 엔진으로써 구글에서 만들어 크롬에도 사용됩니다.)
빌드시스템(GYP) 1 처음 노드를 만들 때 크롬 브라우저가 GYP라는 메타 빌드 시스템을 사용하다가 GN으로 업그레이드한 반면, Node.js는 GN으로 변경하지 않아 이를 후회했습니다. 참고로, 구글의 GN이 GYP보다 20배 정도 빠르게 빌드 된다고 합니다. (GYP_메타 빌드 시스템은 여러 플랫폼(윈도우즈, Mac, Linux)에서 소스코드를 빌드하기 위해 사용되는 빌드 시스템입니다.)
빌드시스템(GYP) 2 GYP를 이용해 빌드 시스템을 만들면서 네이티브 콜을 하기 위해서 사용자가 필수적으로 C++ 바인딩을 하도록 했는데, FFI(Foreign Function Interface)를 제공했어야 했다는 아쉬움을 토로했습니다.
패키지 매니저 파일(package.json) 1 Node.js는 모듈 시스템을 가지고 있습니다. 최근에 이 모듈 시스템이 go와 java에서 언어 자체적으로 구현이 되는 스펙들이 발표되었습니다. (go는 처음부터 구현됐습니다.) 이 모듈 시스템을 관리하는 프로그램은 3rd 파티 프로젝트로 떼어 놓는 것이 일반적이죠. 그런데 노드는 npm이라는 패키지 매니저가 관리하는 package.json. 파일이 main() 함수에서 찾도록 되어있어 npm에 의존적인 커뮤니티로 만들었다는 점을 스스로 비판했습니다. 최근 facebook에서 만든 yarn이라는 패키지 매니저가 npm을 대체하고 있지만 package.json은 그대로 사용하고 있습니다. 의도하진 않았지만 defacto(사실상의 표준)가 된 셈이죠. 또, 이 package.json 파일은 모듈을 찾을 때 명시적이지 않다는 단점도 있습니다. 쉬운 이해를 위해 아래 그림을 참조하시기 바랍니다.
[그림3] somemodule을 찾아라! (출처: http://tinyclouds.org/jsconf2018.pdf)
패키지 매니저 파일(package.json) 2 package.json 파일의 모듈 시스템이 파일 디렉터리를 기준으로 잡히도록 만들어서 라이선스, 리포지터리, 설명 등 모듈 시스템 자체만으로는 필요 없는 정보까지 다 포함시켜 너무 무거워졌다고 합니다.
모듈 시스템(node_modules) 위에서 언급한 파일 디렉터리 기반 모듈 시스템의 약점과 마찬가지로 모듈을 가져오는 알고리즘이 복잡해졌습니다. 또, 브라우저에서 가져오는 방법과도 맞지 않아 굉장히 어려워졌죠. 그럼에도 불구하고 돌이킬 수 없다는 사실에 커뮤니티에 미안함을 전했습니다.
Require 문법을 쓸 때 js 확장자를 안 써도 되게 한 것 브라우저 내 자바스크립트가 작동하는 것과 표준이 달라서 모듈 로더가 사용자의 의도를 파악하기 위해 많은 고민을 해야 한다는 점을 언급했습니다.
index.js 브라우저가 index.html을 default로 갖기 때문에 index.js를 지정한 것이 당시엔 괜찮은 생각 같았으나, 결과적으로 모듈 로딩 시스템을 더 복잡하게 만들었다고 합니다.
deno 라이언 달은 이상의 10가지 이야기를 마치고 나서 새로 만들고 있는 프로젝트를 공개했는데, 그게 바로 ‘deno’ 프로젝트입니다. (프로젝트 링크: https://github.com/ry/deno)
https://www.devpools.kr/2018/06/21/deno/ https://gocoder.tistory.com/1578 https://blog.ull.im/engineering/2019/04/14/deno-ryan-dahl-2019-04-04.html
Originally published May 23, 2020
Latest update May 22, 2020
Related posts :