라벨이 JavaScript인 게시물 표시

React에 Redux 대신 Effector를 써보자!

React에 Redux 대신 Effector를 써보자! " Effector "가 react-material-ui-datatable에서 사용되는 것을 보고, 이것은 무엇일까 싶어서, 한번 훌터봤다. 개인적인 소감으로는 Redux보다 훨씬 직관적이고, 코드(파일 구성 및 코드 생성)가 간결했다. 우선, Redux로 counter 예제를 구현했다. 같은 코드를 Effector로 구현했다. 동작 상황을 확인하기 위해,  Redux에는 reducer에 console 로 log를 출력했다. 대신, Effector에는 "watch"를 이용하여 출력했다. 이부분도 훨씬 간결하다. (혹시, Redux 출력이 잘못이라면, 지적 부탁한다.) 코드를 보자면, "event 생성 -> store 생성, 필요하면 watch -> component에 event 등록"으로 이뤄져 있고, Redux 대비, 파일의 분화, store의 추적 등이 용이합니다. import React from "react" ; import { createEvent , createStore } from "effector" ; import { useStore } from "effector-react" ; const increment = createEvent ( "increment" ); const decrement = createEvent ( "decrement" ); const resetCount = createEvent ( "reset count" ); const counter = createStore ( 0 ) . on (increment, count => count + 1 ) . on (decre...

Next.js Client/Server Rendering 간단 구분법

Next.js Client/Server Rendering 간단 구분법 const Temp = () => { ... return ( <p>Temp</p> ); }; Temp.getInitialProps = async () => { if (process.browser) { ... } } ... export default Temp; 그러나 "process.browser"가 deprecated 되었다. 그 이유는, "process.browser"는 표준이 아니고,  Webpack에 의한 추가된 스펙이기 때문이다. 이제는 이렇게 해야 한다. const Temp = () => { ... return ( <p>Temp</p> ); }; Temp.getInitialProps = async () => { if (typeof window === 'object') { ... } } ... export default Temp;

Prettier를 ESLint "--fix"로 대신 사용할 수 있을까? v1.0

이미지
Prettier를 ESLint "--fix"로 대신 사용할 수 있을까? ESLint의 역할 1. Code Qualify: 코드를 정적으로 분석하여, 잠정적으로 문제가 될 수 있는 부분을 빠르게 찾도록 도와주는 것 2. Code Formatter: 의미대로 보자면, 정한 규칙에 맞춰 코드를 조정해주는 것 Prettier의 역할 1. Code Qualify: 지원하지 않는, 정확하게 지원 대상이 아님 2. Code Formatter(Reformatter): 코드를 원하는 형태로 재정렬 해주는 것 차이점 Code를 형태를 정렬하는 것과 오류를 보정하는 것은, 그다지 차이나는 것이 아닌 것으로 보일 수 있지만, 실제는 큰 차이가 있다. ESLint는 Code Qualify 규칙(.eslintrc 등)에 따라 그 코드에 대한 조정 혹은 경고를 하는 것(흔히 코드의 품질을 높이기 위한 목적으로 적용)인데, Prettier는 reformatter이기 때문에, 문법적 오류에 대한 접근 없이, 코드를 형식을 변경한다. ESLint 예제를 기반으로 설명하겠다. 가능한 최대한 같은 조건을 시험하기 위해서, 옵션을 서로 맞췄다. (옵션 자체를 일일이 비교하는 것이 아니므로, 그 각각의 세세한 차이는 고려하지 않는다. 모든 값을 설정하면, 거의 같은 형태의 모양을 구현할 수는 있다.) ESLint 예제 에 약간의 내용을 추가했다. 원본, var loooong = 'abcdefghijklmnopqrstuvwxyz`1234567890~!@#$%^&*()_+[]\;,./{}|:<>?가나라다마사바사';; const abc = 'abc"def"ghi'; const def = "abc'def'ghi"; const ghi = "abc`def`ghi"; const stu = `abc"def"ghi`; const...

JavaScript 기본 상식 #2

Equality operator(동치 연산자, '==', '===')를 이해하기 값을 비교할 때, 사용하는 연산자로서, 어느 때, '=='와 '==='를 사용해야 하는지를 혼동하는 경우가 많다. 3 == '3' true '3' == new String('3') true 1 == true true null == undefined true 단! 아래 경우는 그렇지 않다. (주의!) 'true' == true fales 2 == true false null == true false 일반적으로 그냥 true인지 보기 위한 비교, 예를 들면, var a = 3; var b = '3'; a == b true 와 같이 값이 최소한 있냐는 관점에서 비교할 때는 문제가 되지 않는다. 하지만, 정확하게 그 값이 있는지 확인할 목적이라면, 이렇게 하면, 큰 낭패를 볼 수 있다. 예를 들면, 위 예에서, 다음을 입력하면 전혀 다른 결과를 가져오기 때문이다. var a = 3; var b = '3'; a += 1 b += 1 a == b false 그래서, 보통 값이 명확하고 형변환과 무관할 때는 '=='를 사용하고, 그렇지 않은 경우는 '==='를 사용하는 것이 좋다. var a = 3; var b = '3'; var c = '3'; a == b true a === b false a == '3' true a == 3 true a === '3' false a === 3 true b == c true b === c true b == 3 true b == '3' true b === '3' true

JavaScript 기본 상식 #1

null과 undefinded "JavaScript는 변수의 자료형의 결정 시점은 {할당할 때}이다." 정의 "undefined" 아직 자료형이 결정되지 않았다. 즉, "변수나 함수가 선언은 되었으나, 값을 할당하지는 않았다" 는 뜻이다. 주의할 것은, 아직 선언되지 않은 변수나 함수 등도  모두 undefined로 확인이 되나, 그렇다고, 변수나 함수가 선언되어 있다는 뜻은 아니다. "null" 이미 자료형이 결정되었다. 즉, "변수나 함수가 선언은 되었고, 값을 null로 할당했다" 는 뜻이다. 자료형 null: "object" undefined: "undefined" typeof null "object" typeof undefined "undefined" "void 0"과 비교 null: false undefined: true null === void 0 false undefined === void 0 true "null"과 "undefined" 비교 "{형변환}을 하느냐('=='), 안하느냐('===')에 따라 결과가 다르다." null == undefined true null === undefined false 추가. delete이후 값에 대한 확인 "{형변환}을 하느냐('=='), 안하느냐('===')에 따라 결과가 다르다." const arr1 = ['a1', 'a2', 'a3', 'a4', 'a5']; delete arr1[2]; true console.log(arr1); (5) ['a1...

Homebrew v2.x에서 Node를 NPM 없이 설치하기

Homebrew v2.x에서 Node를 NPM 없이 설치하기 기본적으로 없다. 우선 내가 만들어낸 편법만 있다. Homebrew의 원칙이 변경되었다. 이런 하위 options를 제공함으로서, 다양한 부가 오류에 대한 대응이 어렵다는 이유에서다. $ brew install node --without-npm ... Error: invalid option: --without-npm 그렇지만, 방법이 전혀 없는 것은 아니다. 직접적인 방법이 없을 뿐. Homebrew v1.x로 설치하는 방법은 아래와 같다. ( Mac OS X Homebrew로 NodeJS를 설치했을 때, NPM package오류 해결 방법 ) 주의! 아래를 실행하기에 앞서서, 반드시 위 링크대로 특정 위치로 NPM의 설치 위치를 정해줘야 한다. $ brew install node $ curl -L https://www.npmjs.com/install.sh | sh $ ls -la $(which node) lrwxr-xr-x 1 keiches staff 31 Feb 19 23:29 /usr/local/bin/node -> ../Cellar/node/11.10.0 /bin/node $ rm -Rf /usr/local/bin/ ../Cellar/node/11.10.0 /libexec/lib/node_modules/npm
JavaScript Class 상속하는 방법 ES5 Class 상속 // 기본 클래스 function CalcAdd(options) { // this.title = options && options.title || 'Calc Add'; this.calculate = () => { console.log(this.constructor.name, "!!!!!"); }; } CalcAdd.create = function (options) { return new CalcAdd(options); }; // 프로토타입 CalcAdd.prototype.add = function add() { // }; // 상속받은 클래스 function CalcAddWithDivide(options) { // const _this = CalcAdd.apply(this, { title: 'Calc Add With Divide' }) || this; // super(arguments); 와 동일 _this.calculate = function() { console.log(this.constructor.name, "~~~~~~"); }; return _this; }; CalcAddWithDivide.prototype = Object.create(CalcAdd.prototype, { constructor: { value: CalcAdd, enumerable: true, writable: true, configurable: true } }); CalcAddWithDivide.prototype.constructor = CalcAddWithDivide; // 추가 프로토타입 CalcAddWithDivide.prototype.divide = function divide() { // }; ES...

배열에서 유일한 값만 추리기 (Get only unique values ​​in an array)

배열에서 유일한 값만 추리기 (Get only unique values ​​in an array) 기본 알고리즘 const source = [1, 2, 3, 2, 4, 5, 3, 3, 7]; for (let indexLeader = 0, lengthLeader = source.length; indexLeader < lengthLeader; indexLeader += 1) { // console.group(`leader index${indexLeader}`, source[indexLeader], source); for (let indexFollower = indexLeader + 1, lengthFollower = source.length; indexFollower < lengthFollower; indexFollower += 1) { // console.log('follower', indexFollower, source[indexFollower]); if (indexLeader === indexFollower) continue; if (source[indexLeader] === source[indexFollower]) { // console.log('-deleted', indexFollower, source[indexFollower], source); source.splice(indexFollower, 1); // console.log('*after deleted', indexFollower, source); indexLeader -= 1; indexFollower -= 1; lengthLeader -= 1; lengthFollower -= 1; } } // console.groupEnd(`index${indexLeader}`); } => [1, 2, 3, 4, 5, 7]...

Webpack "html-webpack-plugin" 사용팁

Webpack "html-webpack-plugin" 사용팁 html-webpack-plugin 을 이용하여, 작업하다보니 2가지 사용 방법이 궁금해졌다. 1번. html-webpack-plugin loader를 교체할 수 없나? 방법) webpack.config.js const HtmlPlugin = require('html-webpack-plugin'); ... const webpackConfigs = { plugins: [ new HtmlPlugin({ // 원래 코드 // template: 'index.ejs', // 변경할 코드 template: `${path.resolve( __dirname, 'html-my-loader', 'index.js' )}?param1&param2=foo&param3=bar!index.ejs` }) ] }; html-my-loader/index.js const loaderUtils = require('loader-utils'); module.exports = function myLoader(source) { const options = loaderUtils.getOptions(this) || {}; ... return source.replace(options.from, options.to); }; 2번. block 제거 혹은 string replace 와 같은 것을 선행적으로 적용하고 나서 처리되게 할 수 없나? webpack.config.js const HtmlPlugin = require('html-webpack-plugin'); ... const webpackConfigs = { module: { rules: [ ...

Webpack v4 copy-webpack-plugin 할 때, Uglify하는 방법

Webpack v4 copy- webpack-plugin 할 때, Uglify하는 방법 Webpack v4로 바뀌면서, 이래저래 기존 Plugin이 보조를 맞춰 올라오지 못하는 경우가 많다. 그러다 보니, 원하지 않는 메시지를 보게 되는데, 결과를 얻는데는 문제가 없더라도, 아무래도 거슬릴 수밖에 없다. 표시되는 메시지 const webpackConfig = { plugins: [ new CopyPlugin( [ { from: path.resolve(__dirname, 'dest', `jquery${PRODUCTION ? '.min' : ''}.js`), to: 'libs', transform : PRODUCTION && content => Promise.resolve(Buffer.from(Terser.minify(content.toString(), terserOptions).code, 'utf8')) } ] ) ] }; ES6를 사용한다고 가정하고, Terser Plugin을 사용했지만, 상황에 따라 Uglify Plugin을 사용해도 된다.

Webpack v4 webpack-concat-plugin Deprecation Warning이 거슬릴 때

Webpack v4 webpack-concat-plugin Deprecation Warning이 거슬릴 때 Webpack v4로 바뀌면서, 이래저래 기존 Plugin이 보조를 맞춰 올라오지 못하는 경우가 많다. 그러다 보니, 원하지 않는 메시지를 보게 되는데, 결과를 얻는데는 문제가 없더라도, 아무래도 거슬릴 수밖에 없다. 표시되는 메시지 node run production > xxx_xx_5.0.2@0.0.1 production /xxx_xx.5.0.2 > cross-env NODE_ENV=production webpack --colors --config webpack.config.js clean-webpack-plugin: /xxx_xx.5.0.2/production has been removed. (node:10946) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead 빨간색 표시된 부분과 같은 메시지가 자꾸 출력되는데,  " webpack-concat-plugin " 을 사용하고 있다면, 아직까지는 딱히 수정하기는 어렵다. 그러면, webpack.config.js를 한번 보자. const ConcatPlugin = require('webpack-concat-plugin'); // ... const webpackConfigs = { plugins: [ new ConcatPlugin({ uglify: PRODUCTION, sourceMap: !PRODUCTION, name: 'test', outputPath: 'dest', fileName: '[name].js', filesToConcat: [ path.join(__dirname, 'src', ...

JavaScript Object의 window와 window.opener간 전달할 때 주의할 점!

JavaScript Object의 window와 window.opener간 전달할 때 주의할 점! main window window.myFunc = (newType) = { console.log(newType instanceof Object ? 'Object' : 'Not Object'); console.log(typeof newType === 'object' ? 'Object' : 'Not Object'); }; var child = window.open(); child window window.opener.myFunc({a: 1}); 위와 같이 main window에서 child window를 열고, child window에서 main window에 global function을 call한 후, 값을 비교할 때는 "typeof value"와 같은 형태로 해야 안전하다. * Cross-Origin을 해결하기 위해서는, postmessge/onmessage 를 사용하여, 대화를 하는 것을 추천한다. const domain = 'https://mysite.com'; function onMessage(event) { if (event.origin !== domain) { return; } const data = JSON.parse(event.data); } window.addEventListener("message", onMessage, false); const domain = 'https://mysite.com'; const popup = window.open(`${ domain }/popup.html`, 'My Popup'); popup.postmessage(JSON.stringify({data:3}), domain);

Mac OS X Homebrew로 NodeJS를 설치했을 때, NPM package오류 해결 방법

Mac OS X Homebrew로 NodeJS를 설치했을 때, NPM package오류 해결 방법 문제의 원인은 npm은 스스로 upgrade를 하기 때문에 발생되는 것으로 판단된다. 즉, Homebrew가 설치해준 위치에서 "npm update npm"하는 순간 위치가 틀려져, 이전에 설치했던 package의 위치가 다 달라져서 발생하는 문제이다. 이전에 설치한 경우까지 포함한 해결 방법은 아래와 같다. ( https://gist.github.com/DanHerbert/9520689#gistcomment-1562962 ) #0 이전에 설치한 적이 있는 경우, 아니면 #1부터 $ ls -1 /usr/local/lib/node_modules > ~/node_modules.txt $ sed -e "s,/\+$,," -e "s,^/\+,," ~/node_modules.txt $ rm -rf /usr/local/lib/node_modules $ brew uninstall node --force node #1 Homebrew v1.x에 한함 $ brew install node --without-npm $ echo prefix= /Users/keiches /.npm-packages >> ~/.npmrc # 주의! '~'와 같은 상대 주소를 사용하면, 추후 설치가 안된다. 절대 path를 입력해줘야 안전하다. $ curl -L https://www.npmjs.com/install.sh | sh $ echo 'export PATH="$HOME/.npm-packages/bin:$PATH"' >> ~/.bash_profile $ source ~/.bash_profile #2 이전에 설치한 적이 있는 경우, 아니면 건너띈다. for i in `cat ~/node_modules.txt`; do npm install -g $i; done...

Javascript String Replace에 대한 다른 사용법과 의의한 결과

이미지
Javascript String Replace에 대한 다른 사용법과 의의한 결과 "Google Chrome vs. Safari & Internet Explorer 11에서 서로 다른 성능을 보여서 기록에 남긴다. " 내가 이렇게 단정짓는 이유는 다양한 bluetooth 제품(receiver, receiver-transceiver)을 사용해본 봐다. 그렇다고 절대적인 의견은 아니다. 단지 이렇게 사용한다면 굳이 이렇게 비싼 가격의 별 성능이 없는 제품이 필요없다는 말이다. String을 모두 치환하고 싶다면 보통 아래와 같이 할 수 있다. var str = 'abcdef'; 방법 1) str.replace(/abc/g, 'xyz'); 방법 2) str.split('abc').join('xyz'); 난, 사실 방법 1만 사용해왔다. 그런데 2번도 나름대로 괜찮은 방식이란 생각이 든다. 그런데, 각 browser마다 다른 성능을 보인다는 것이 놀랍다. ( http://jsperf.com/replace-all-vs-split-join ) Microsoft IE 11 Apple Safari 8 Google Chrome (Mac OS X 10.10) Google Chrome (MS Windows 7) SRWare Iron - Google Chrome과 유사 재미있게도 IE와 Safari는 비슷하게 나왔는데, Chrome은 반대로 나왔다는 것이다. 그럼, IE와 Safari를 사용할 때는 replace보다는 split-join을 사용하고, Chrome을 사용할 때는 replace를 사용하도록 코딩하는 것도 좋을 듯하다.