2019년 10월 29일 화요일

Vuex 변수 재할당 문제

Vuex를 새롭게 사용하면서 몇시간동안 나를 미치게하는 문제가 발생했었다.

Vuex.Store{
 state : {
   myList : []
 },
  mutations : {
   setMyList( state, payload ) {
     state.myList = payload.newList;
   }
  },
  getters : {

    getMyList : state => { return state.myList }
  }
}

이러한 myList 데이터가 있었고, 초기 페이지 로드 이후 이 목록을 mutator로 추가한뒤, 추가된 myList 갯수만큼 화면에 v-for로 뿌려주는 아주 간단한 문제였으며, 예상과 다르지 않게 자알 동작했다. 돌이켜보면 이게 화근이다.

이후 mutate로 한번더 값을 변경한 다음,  다시 한번 getters를 호출했다. 그런데 왠걸?
업데이트가 전혀 작동하지 않는다.

이때부터 원인을 파악하기 위해 여기저기를 들쑤시고 다니면서 난장판을 만들며두시간을 허비했다.

마침내 state의 값은 변경되었으나, Vuex에서 바뀐값을 인지하지 못한다는 결론이 났고, 뒤늦게 해당 이슈로 검색을 진행 할 수 있게 되었다.

마침내 이슈에 대한 실마리를 얻었는데 :
Vue does not allow dynamically adding new root-level reactive properties to an already created instance.
"Vue 인스턴스단에서 동적으로 새 root-level단의 변경을 허용하지 않는다" 정도로 이해하면 될거 같다.

내가 하려는  행위는 Vue인스턴스에 있는 store(Vuex) 의 state 를 임의로 변경하려는 행위였으며, Vue는 변경을 감지하지 못했던 것이다. 이렇게 생각해보면 애초에 처음에도 똑바로 동작이 되지 않았다면 좀더 빨리 문제를 파악할 수 있었겠지만, 변경이 어느 타이밍에는 되나, 절대 보장할 수 없는 변경 방법이었던 것으로 파악된다.

이후 가이드에 따라 올바른 변경방법을 mutation에 적용했다.
mutations : {
  setMyList ( state, payload ) {
    Vue.set(state, 'mylist', payload.newList);
  }
}

이렇게함으로써 Vuex는 변경을 바로 파악할 수 있게 되었다.

오늘도 신나는 삽질 끄읏

2019년 6월 9일 일요일

SASS설정기 on NPM

어느덧 아무것도 모르던 css 작업을 실무에서 겪어가며, 점차 늘어나는 정신나간 분량의 css 코드들에 대해서 홀로 맞서기 버거워지기 시작하고있는 시점인 지금, 드디어 좀더 새련된 CSS처리방법을 강구해야겠다는 결심이 섰습니다.

유명한 후보로는 SASS 나 LESS.
둘의 각각의 특성에 따라 어느것이 더 배우면서, 적용하기 좋은지 짧은 비교의 시간을 가졌고, 비교당시 더 높은 점유율을 기록하는것으로 보이는 SASS가 당첨되었습니다.

LESS와 SASS는 모두 동일하게, css로 컨버팅 작업이 필요합니다. 그러므로 매번 서버를 리로드 하면서 컨버팅 또한 필요했기 때문에, SASS는 watch 라는 이름의 기능으로 핫리로드를 지원하고있었습니다.

하지만 매번 터미널 두개를 돌려서 watch를 돌리고 서버를 돌리기가 너무나도 귀찮은 나머지, 이 두 명령어를 동시에 날리게 하기 위해서 concurrently 를 사용하여 npm 명령어를 조금 조작할 것 입니다.

1. 우선 SASS를 설치합니다.
` npm i -g sass`
로 간단하게 sass를 설치하게 됩니다.

테스트를 위해 ./sass/default.scss 파일을 만들었습니다.

서버 node에서는 static 폴더를 ` ./public `으로 지정해 두고 있었습니다.
그러므로 css를 static으로 관리하기 위해 새 폴더를 만듭니다.
` ./public/css `

이제 ` default.scss ` 에서 예제 코드를 작성합니다.

body {
 background-color : red;
 container {
  background-color : orange;
 }
}

이제 완성된 scss 파일을 css로 변환해야 합니다.

` sass --watch ./sass/default.scss:./public/css/default.css `
변환이 완료됩니다.

2. 이제 이러한 복잡한 과정을 쉽게 조금씩 바꾸어 나갈것 입니다.
우선은 sass 폴더내의 모든 scss파일들을 public 폴더에 저장시킬것 입니다.
default.scss body.scss footer.scss 등의 여러파일이 있어도 한번의 명령어로
default.css body.css footer.css 로 바꿀수 있게 말이죠

간단합니다.
` scss --watch ./sass:./public/css `
단일 객체가 아닌 폴더를 지정하고, 출력물 폴더로 변경만 시켜주면 됩니다.

이제 watch를 프로젝트를 제시작 할때마다 치는 귀찮음을 해결해 볼 것 입니다.
물론 리눅스 유저라변 백그라운드로 손쉽게 처리할 수 있겠지만, 리눅스 알못인 저는 무언가 편한 작업을 요합니다.
npm은 우리가 js관련 작업 특히 node 작업에서 땔수 없는 메니져입니다.
npm의 추가 모듈을 이용해 볼 것 입니다.
` npm i -g  concurrently `

concurrently는 npm 명령어를 다중으로 실행 가능하게 돕는 모듈입니다.
프로젝트의 package.json 파일을 열어봅니다.

 "script" : 의 값들을 추가 할 것 입니다.
저는 npm start 라는 명령어로 ` node app.js ` 와 ` scss --watch ./sass:./public/css ` 를 동시에 실행하고 하나의 터미널에서 보이게 할 것 입니다.

` "script" : {
  "start" : " concurrently \" node app.js \" \" scss --watch ./sass:./public/css\" "
}
`
 이제 터미널에서 npm start 를 치게되면 두작업이 동시에 실행되는것을 볼 수 있습니다.

그런데 [0] 과 [1]로 실행중인 프로세스의 정보를 표기하는데 좀 보기가 어렵습니다.
배열명 말고 [Express] [Watch] 로 표시해 볼것 입니다.
 script : 에 start 의 값을 수정합니다.


` "script" : {
  "start" : " concurrently -n \"Express,Watch\" \" node app.js \" \" scss --watch ./sass:./public/css\" "
}
`
-n 으로 이름을 순서대로 정할 수 있습니다.

이제 로그를 보면 보기좋게 구분이 되기 시작합니다.

하지만 저는 변태입니다. 색깔을 넣어서 더 구분을 하고싶습니다.

-c 를 이용해 봅시다.

` "script" : {
  "start" : " concurrently -n \"Express,Watch\" -c \" red,yellow \" \" node app.js \" \" scss --watch ./sass:./public/css\" "
}
`
이제 [Express]는 빨강으로, [Watch]는 노랑으로 표기가 됩니다. 만족스럽네요.

추가적인 기능들은 스스로 들러보고 적용해 BOA효

2019년 5월 17일 금요일

[Webpack 공부 #2] Webpack with HTTP2?


...그리하여 Webpack의 가장 큰 사용목적인 모듈 패키징이 무엇인지 알기 위해, HTTP1.1에 대해서, 또 동시에 HTTP2에 대해서 알게되었습니다.

더 깊게 웹팩을 파기 전에, 저는 지금즘 한가지 생각이 들었는데
"그렇다면, HTTP2 방식을 사용하면 웹팩의 존재가 필요없지 않는가?"
였습니다.

결론적으로 웹팩과 HTTP2를 병행하게된다면, 더 높은 성능향상을 꽤할 수 있다 입니다.
어찌보면 당연한 말입니다.

특정 페이지를 로딩할때 필요한 리소스들이 아래와 같다고 한다면
index.html
default.css
default.js
favicon.co
title.png
총 5개의 리소스가 필요로 하며,
Http2를 이용한 서버에서 클라이언트가 처음으로 index.html을 요청하며 connection을 만들면,
서버는 5개의 스트림을 만들어 전송을 하게 됩니다.

하지만 웹팩을 통해 번들링을(예를들어) 통해 단 하나의 번들로 묶는다면,
스트림은 단 한번만 전송하면 되기 때문입니다.

또 이렇다고 마냥 모든 파일들을 번들링하기엔 석연찮은 구석도 있습니다.



번들링의 수준
번들링을 하게된다는것은 여러 파일들을 합쳐서 제공한다는 말입니다.
그렇다면 모든 js파일들을 번들링하는것은 옳은걸까요? 분명 connection/stream은 단 한번이니 좋을것 입니다. 하지만 다른쪽 성능을 생각해 본다면 어떨까요?

모던 js를 이용해 모듈화를 한 경우의 윂페이지라면, 페이지나 작업마다 사용하는 js파일들이 다를것 입니다. 이런 경우라면 모든 js파일들을 다운로드받고 싶지 않을것 입니다. 모듈화 한 이유가 없으니깐요.

모든 js파일들을 번들링 하게된다면, 모든 페이지마다 하나의 큰 파일을 받아야 할것입니다. 설상 그 js파일들이 쓸모없을지라도 말이죠.

그럼 특정 js파일들만 번들링을 하고, 필요에따라 제공하는것은 어떨까 하는 생각이 들것입니다. 번들링 된 파일로 stream 횟수는 적당히 줄어들며,불필요한 js를 로드하느라 성능 낭비를 할 필요도 없을거구요.

하지만 이 하이브리드 구조와, 번들링을 하지 않은 js파일들의 벤치마크를 했을때 결과는 놀랍게도 의도와 많이 달랐다고 주장합니다.

위의 글에 따르자면, 번들러를 사용할떄 쓰는 압축 기술은 대용량 파일의 압축에 더 유리하기 때문에, js 모듈따위의 작은 용량의 파일은 압축 비용이 원본비용보다 높은 문제를 지적합니다.

이러한 데이터들과 벤치마크를 통해 지금까지 중론처럼 나온 결론은
번들링은 HTTP1.1 과 HTTP2 를 막론하고 성능향상을 유도할 수 있으나,
과도한 번들링은 서버의 캐싱문제로 다른 퍼포먼스 이슈를 초래할 수 있습니다.
결과적으로 상황과 기능 등에 맞게 세분화 한 번들링 / 하지만 너무나도 세세한 경우라면 stream이 증가할 것이므로 너무 세세하지는 않게 적당한 번들링을 사용해야 한다는 것 입니다.




이제 기본적인 웹팩의 용도를 넘어 좀더 향상된 사용방법을 간단하게 훑어보았으며, 이제는 실제로 코드를 짜 봐야 할 시간인거 같군요.

[Webpack 공부 #1] Http1.1 and Http2

새로 취직하게 된 직장에서는 어렴풋이 모든것을 처음부터 시작해야하는것이 아닌가 하는 판단이 들기 시작하고 있습니다.
코드관리, 서버, 배포, 모든 환경을 스스로 정의해야할지도 모른다는 생각이 점차 들기 시작하여, 저는 개발환경 구축부터 서비스를 위한 환경구축에 대한 정보 탐색을 시작했습니다.

당장 머릿속에 떠돌던 몇가지 자동화 혹은 개발환경의 힌트들이 면접중에 떠올랐습니다.

GitLab Jira DevOps Docker Jenkins..

왜냐하면 저에게 '환경 구축'이라는 단어들에 대해서 매우 생소하고 무지렁이인 상태였기 때문입니다.

무지렁이가 할수있는것은 리서칭 이지요!

우선 요청도 있고 해서 먼저 리서칭 한것은


Webpack 입니다.

웹팩이란 js 모듈이나, 기타 리소스들을 하나로 묶는 모듈 번들러 입니다. 그럼 왜 js나 리소스들을 하나로 묶는가에 대해 알아보아야 합니다. 그것을 알기 위해서는 HTTP1.1에 대해서 알아봐야 합니다.

HTTP 1.1 vs HTTP 2

기본적인 웹 프로토콜에서는 1요청당 1응답만을 돌려줍니다. 이 말은 하나의 웹 페이지에 필요한 리소스 파일들이 아래와 같다고 하면 [ index.html | default.css | foo.js | favicon.jpg | index.png ] 우리는 HTTP 요청과 응답 handshake 를 5번 해야 모든 윂페이지 로딩이 정상적으로 끝나게 됩니다. 5번의 지연시간이 소요되는것 입니다. HTTP 1.1의 전송방식에 문제점은 몇가지가 있는데,
1. HOL Blocking ( Head of Line Blocking)
동일한 네트워크 큐에 있는 패킷들이 Head부분의 패킷에 의해 지연되는 형상을 야기하는데,
웹 환경에서 HOL Blocking은 두가지가 있습니다.
HTTP HOL Blocking
TCP HOL Blocking
HTTP1.1 에서 앞서 언급된 여러개의 리소스를 모두 받기 위해서는 하나의 파일당 하나의 요청을 주고받는 행위를 없에기 위해 pipelining이 나왔습니다. 이 기술은 단 한번의 커넥션을 통해 TCP socket을 연결하는 방식입니다. 소켓이 연결이 되면, 해당 소캣을 통해 리소스들을 하나하나 순차적으로 받는 방식입니다. 이 말은 HTTP1.1에서는 전송방식이 반드시 동기화 형식으로 차례로 받을수 밖에 없다는 문제점을 보여줍니다. 하지만 이방식 역시 socket 통신을 통해 이루어지며, 그러는 와중에 리소스 다운로드에 지연시간이 생길 수 있습니다. 이런 경우, 다음 리소스들은 현재 받고있는 리소스의 다운로드가 완료 될 때 까지 팬딩상태에 머무르게 되며, 이를 우리는 HTTP HOL Blocking 이라고 부릅니다. TCP의 특성상 보낸 데이터가 올바르게 전송되었는지 확인한 후, 실패시 다시 보낼 수 있게 설계되어있는데( 3way hand shacking) 이런 경우가 발생할시, TCP는 전송받은 패킷의 순서를 관리하기 위해, 재전송을 받을때 까지 다음 순서의 패킷을 받지 않게 되며, 이런경우 TCP HOL Blocking이 걸린 상태라고 부를 수 있습니다.

2. 높아지는 RTT(Round Trip Time) 위에서 언급되다싶이, HTTP1.1은 동시에 하나의 connection(물론 세팅을 통해 늘릴수 있다고도 한다)을, 동기적으로 처리하기 때문에, TCP구조인 HTTP의 특성상 3way-handshacking을 하나의 리소스를 받을때 마다 이루어지기 때문에 RTT가 증가됩니다.

3. Header의 비대화 HTTP 1.1 이 되어가며 Header에 입력되는 메타데이터들의 양이 늘어나게 됩니다.그리고 모든 connection을 통한 통신에서는 Header가 반드시 포함됩니다. 특정 경우에 따라 완벽히 동일한 Header가 몇번이고 반복적으로 전송되기도 할것 입니다( 하나의 동일한 높은 용량의 데이터인 경우 페킷을 나누어 전송할 것 이며, 이때 헤더는 페킷 순서와 끝 유무 정도를 재외하면 동일할 것 입니다)


이러한 여러가지 문제점들이 있었고, 솔루션 또한 여러가지 존재하게 되었었습니다.
하지만 근본적인 솔루션들은 아니었으며, HTTP2 가 이러한 문제들을 해결하기 위해 나타났습니다...
그리고 HTTP2는 1.1과 동일한 형태를 유지하되 속도적인 측면을 개선하기 위해 개발되었으므로, 기존 명세와는 큰 차이는 없습니다. 추가는 있겠지만..

그리고 HTTP2에서 소개하는 기술은 아래와 같습니다.
Multiplexed Streams
클라이언트는 하나의 connection에서 이제 여러개의 메세지들을 받을 수 있습니다. 그리고 이제 순서를 따지지 않으며, stream으로 받게 됩니다.
Stream Prioritization
순서를 따지지 않고 데이터들을 받을수 있다는것은, 보여줄 내용을 순서에 맞게 보낼 수 없다는 의미이기도 합니다. 예를들어 js파일을 먼저 받고싶지만, 순서를 따지지 않게되기 때문에, 어느 타이밍에 js파일을 받는지 알 수 없게 됩니다. 그러한 이유로 각각의 리소스파일에 우선순위인 가중치 를 부과 할 수 있으며, 이를통해 무엇을 우선적으로 받을 수 있습니다.
Server Push
이제 클라이언트의 요청이 있지 않아도 서버는 임의로 데이터를 전달 할 수 있습니다. 기존의 1.1 에서는 클라이언트는 html을 먼저 받은뒤, 이후에 추가적으로 무슨 리소스가 필요한지 파악을 할 수 있었고, 요청을 보낼 수 있었습니다. 하지만 Server Push를 이용하여, 클라이언트가 첫번째 요청을 하게되면, 서버측에서 추가적으로 필요한 리소스들을 찾아내어 클라이언트의 추가 요청없이 임의로 전송을 하는 방식입니다. 이렇게 함으로써 connection 추가 요청 수를 줄이는 방법으로 성능향상을 꽤합니다.
Header Compression
무겁고 중복적으로 전송되는 Header 다이어트를 목적으로, Header Table과 Huffman Encoding 기법을 사용하게 됩니다. Header Table는 처음 전송받은 Header를 특별한 Table에 저장 해 두며 또다시 헤더를 요청받게 되면, 기존에 저장된 헤더 table과 diff를 때려서, 다른 부분만 명세하여 전송됩니다. 이렇게 함으로써 중복되는 header 데이터 전송 낭비를 해결했으며, 상당한 수준의 로드타임 개선을 이루었습니다.


2019년 5월 7일 화요일

방어 코딩?

첫번째 회사에 근무할때 완전히 다른 파트를 담당하느라 바쁘긴 해도, 사수분이 내 코드의 리뷰를 이따금 해 주곤 했었다. 또 아이러니하게도 그런 리뷰를 받는 날에는 항상 시간에 좇겨 어쩔수없이 짜거나, 진퇴양난으로 인해 만들어진 자부심이라곤 눈꼽만큼도 남아있지 않은 슬픈 코드들이 항상 비류 대상이었고, 항상 부끄러운 배움의 시간이었다.

어쩌면 내가 울상이거나 한숨을 쉬거나 '이런 코드를 정말로 라이브시켜도 되나' 하는 표정이었을때 리뷰를 해주셨던게 아닐까 글을 쓰다보니그런 생각이 흘러간다.

아무튼 이러한 리뷰시간을 갖으면서, 나는 짧은 개발자 인생에서 처음듣는 단어가 있었는데 바로 방어코딩 이라고 그는 불렀다.

그당시 내 보수중인 코드는 spring java였었으며, expected value가 다를수 도 있었기 때문에, 또 내 개발 커리어의 경험에 따라 - 특히 그당시 javascript의 undef value 로 크게 혼이 난적이 있었기 때문에 - 나는 가지고오는 value나 params 를 검사부터 하는것을 지향했었다.

예컨데 이런 함수의 형태를 만들어야 한다면 :

private foo getFooValueFromBar ( Bar bar ) {
 return FooMaker(bar);
}

난 대게 이러한 방식으로 함수 안을 보강했었다.
foo myFoo = null;
if ( bar == null || bar == '' ) {
 throw new Error("givin param is null");
} else {
 myFoo = FooMaker(bar);
 if ( myFoo != null ) return myFoo;
 else throw new Error("returned foo is null");
}

난 아직도 이게 그렇게 틀린 코드라고 생각하지는 않는다.
사수 역시 동의했다. 예외를 모두 under control 하는점은 좋으나, 굳이 이런게 필요하지 않은 경우까지 모두 한다는것이 내 사수분의 의견이었다.

그의 주장은 이해할 수 있었다. 왜냐하면 그 당시 메인 프로젝트는 이미 수많은 코드들의 스파게티로 엉망인 상태였으며, 우리는 이 스파게티코드를 대대적으로 변경하는 v2.0 작업을 진행하기 전까지는 '최대한 덜 지저분하게 판을 벌려가며 새 기능을 넣을것' 이라는 둘만의 목표의식을 지나고 있었다. (하지만 잘 지켜지지는 못했다 적어도 난)


최근 내 여자친구의 사수가 방어코딩이라는 언급을 하며 코드를 소개한 적이 있었다.
그녀는 spring java를 담당하던 이전직장의 나와는 달리, javascript를 담당하는 포지션이었으며, 그녀의 사수는 최적화와 숏 코딩에 대한 상당한 지지와 자부심을 가진 자신감 넘치는 사수였다.

그는 반대로 방어코딩에 대하여 매우 긍정적이며, 오히려 더 세밀하게 해야한다는 취지의 주장을 했다( 적어도 그렇게 이해했다. 내가 들은 이야기는 아니니깐 말이다 ) 그 역시 외주를 통해 만든 말라비틀어진 스파게티 수준의 코드들로 surrounded되어, 매일을 히스테리성 발작을 보일정도로 괴로워하는 사람이었으며, 내 사수분과 같은 생각인 2.0까지만 이 코드들을 최대한 아름답게 보강하며, 이후에는 새 버전을 올리며 버리자는 주장을 했었다.

이러한 글을 쓰기전에 나는 어떻게 두명의 3년차 4년차 개발자 선배들이 각기 다른 의견을 제시하는지에 대해 생각을 해 봤었고, 무엇이 이들을 상반된 주장을 하게 되는가 하는 호기심에 정리를 해 보기 위해 쓴 단순한 글이다.

java개발자로 5년차가 되어가고 있던 그는, 한 스타트업의 모든 프로덕트를 혼자서 2년넘게 관리해 오며, 언제나 스스로를 낮추며 공부를 멈추지 않은 훌륭한 사수였으며,
javascript 개발자로 3년차를 보내고 있는 그는, 상당히 유능한 실력으로 인정받아, 그 역시 또 다른 스타트업의 프론트앤드를 총괄하고있는 팀장이며, 항상 자신감 넘치고, 배움에 대해서 즐거움을 느끼는 타입이다.

둘다 이전에 만들어진 '완성하기 급급한' 프로덕트들로 괴로워하며, 여유만 생긴다면 새 프로덕트로 갈아탈 기회만을 노리고 있는 사람들이었다.

그렇기에 난 개발환경과 언어에 따라 두 가지 상반된 의견이 나왔으리라 라는 추측을 하고있다.

개인적으로 느끼는 java와 javascript의 차이점중 하나로 이것을 드는데,
java는 예외발생에 대해서 매우 민감하게 반응을 하고 오류를 뱉고 죽어버리는 반면,
javascript는 예외가 발생해도 은근슬쩍 계속 작동이 되어버리기 떄문에, 실제 오류발생 부분에서 상당히 지난 뒤에, 완전히 코드가 꼬인뒤에에 모든게 폭발한 뒤에에 오류가 나타나버리는것이다.

그런이유로 java는 발생하는 예외에 대해 민감하기 때문에, 추가적으로 개발자가 공들여야 하는 예외사항의 범위가 작으나, javascript는 모든 예외사항을 다 고려해야하기 때문에, 후자가 더 방어코딩이 필요한것이 아닐까 한다.

그래서 방어코딩, 해야하는가 말아야 하는가의 결론은

언제나 그렇듯 '지금 내 상황에 맞게'  ...

CSS border 요약

Border

border 프로퍼티로 굵기, 스타일, 컬러 를 정의할 수 있습니다.

  • 굵기 는 border-width 로써 경계선의 굵기를 정의하며
border-top-width | border-right-width | border-bottom-width | border-left-width
로 각 위치별로 따로 정의할 수 있습니다.

  • border-style에서 경계선의 스타일을 정의할 수 있습니다.
style은
border-top-style | border-right-style| border-bottom-style| border-left-style
로 각 위치별로 따로 정의할 수 있습니다.

  • 마지막으로 border-color로 경계선의 색을 정의할 수 있습니다.


border-width : 1px;
border-style : dotted;
border-color : #000;
위 인자들을 이용해 만든 border는

border : 1px dotted #000;
로 줄일수 있습니다.



border-radius 를 사용하여 둥근 모서리를 만들수 있습니다.
이 값은 border에 둥근 모서리를 만들수 있게 해 주며, border가 설정되어있어야만 보입니다.

border-radius : 1px;
border : 1px solid #000;

위와같이 border값 설정이 필요합니다.

  • border-radius값은 아래의 네가지 프로퍼티들의 조합입니다.
border-top-left-radius | border-top-right-radius | border-bottom-right-radius | border-bottom-left-radius

그러므로 특정 위치만 둥근 모서리를 만들고 싶을때
border-top-left-radius : 1px; border-top-right-radius : 0px;
border-bottom-right-radius : 1px; border-bottom-left-radius : 0px;
혹은
border-radius : 1px 0 1px 0;
으로 표현 할 수 있습니다.

border-radius 의 인자값이 두가지 혹은 세가지로도 표현이 가능하며,
border-radius : param1, param2, param3, param4
param3의 default value는 param1과 동일하며,
param4의 default value는 param4와 동일합니다.


border-image 로 경계선에 이미지 띄우기
해당 프로퍼티는 세가지의 값을 받는데,

이미지 경로, 이미지를 자르는 시작점, 모서리가 아닌 영역에서의 이미지 처리방법 을 정의합니다.

  • 이미지 경로는 말 그대로 background에 쓰일 이미지 경로를 정의하며
  • 이미지를 자르는 시작점의 경우,
우선 border-image에 입력된 이미지는 3x3 으로 총 9개의 이미지가 slice됩니다.
이 slice된 영역들은 border의 각 꼭지점과 면을 담당하게 됩니다.
하지만 필요에따라 이 slice하는 영역을 변경해야하는 경우가 생기는데 이때 이곳에서 slice할 영역을 정의하는것 입니다. 30% 로 자른경우, 
이미지 총 길이에서 30%씩 start, end영역을 자르며, 나머지 영역인 40%는 면에 그리게됩니다.
만일 이 자리는 영역이 50% 가 넘어가게 되면, start와 end영역에만 그려지며, 면에는 그려지지 않습니다(남은 영역이 없기 때문에)
  • 이미지 처리방법의 경우에는 stretch와 repeat 가 있습니다. 위의 자르는 영역에서 나온 면 부분의 이미지를 늘리거나 반복시킵니다.

2019년 4월 18일 목요일

React.js 공부노트 #3 styled-component 삽질기...

리엑트 공부 와중에 알게된게, 후배 하나가 나처럼 리엑트 헛발질을 열심히 하고있다는 소식을 접했습니다.

그 친구는 이틀전부터 CSS를 조금더 편하게 관리하기 위해서 어떤것을 사용해아하는가 에 대해 여기저기 찔러보고 다녔었고, 저 또한 기본 CSS말고는 써본적이 없었기 떄문에 아는바가 전혀 없었습니다.

그러는와중 상당히 잘 정리되어있는 블로그를 참조하고 제가 이번에 써볼 CSS모듈이 무엇이 될지 곧 정할 수 있게 되었습니다. 해외 유명포럼 Reddit을 몇년동안 잘 사용해왔던 터라 reddit에서 사용중엔 styled-component에 단박에 눈이 꽂혔고, 기본 react 강의의 흐름에 너무 다르지 않은 -러닝커브가 그다지 높지 않아보이는(component별로 jsx에서 작성하므로)- 것이 두번째 선정이유이며, 마지막으로 scss에서 사용할 수 있는 부모자식 관계 방식또한 가능했기 떄문에 선정을 하게되었습니다.


공식 도큐먼트에 따라 잘 작성중이었으나, 한가지 문제점에 봉착했습니다.

Header.js
...

class Header extends React.Component {
 render() {
  return(
   <header>
    <Foo/>
   </header>
  )
 }
}
export default Header;


App.js
import Header from 'some_location';
...

class App extends React.Component {
 render() {
  retrun(
   <Bar>
    <Header/>
   </Bar>
  )
 }
}
export default App;

의 코드가 있었습니다.
App.js 에서 style-component 모듈을 적용시켜 보았으며,
적용을 원했던것은 Bar 와 Header 두 DOM element였습니다.

App.js 에서 class define 이전에 한줄의 코드를 작성하는데,
const Bar = style.div` color : red; `;

이 코드를 작성하게 되면, Bar DOM element의 css가 적용이 되었습니다.
Header element또한 같은 방법을 사용하면 된다고 생각한 저는 아래 코드를 작성했었고
const Header = style.div` color : green; `;

에러를 만나는데, 이미 Header는 선언되어있음 이라는 에러를 만나게 됩니다.

그도 그럴것이 App.js 에서는 Header.js 를 import 하면서 Header 라는 변수명을 가진체 나왔기 때문에였습니다.

그럼 이를 해결하기 위해서는 변수명을 틀리게 하면 된다 인데,
App.js 에서
import Header as myHeader from ' ... ';

를 하게 된다면
<Bar>
 <myHeader/>
</Bar>

로 바뀌게 될것이고, style 또한 인식하지 못하게 될것입니다.

이러한 이유로 해결방법을 20분정도 찾아보았으나 마땅히 맞는 이슈를 찾지 못합니다.

한참 골똘이 생각하다가, 문제점을 다시 되짚어 보다 엄청난 사실을 깨달았는데...

<Bar> 와 <Header> 는 동일한 타입이 아니었습니다. 이는 가시적으로 보기쉽게 정리가 되어있을뿐, Bar는 DOM element가 맞으나, Header의 선언부를 보게되면
<div>
  <Foo>
</div>

라는 element들이 모아서 Header라는 변수명을 갖고있을 뿐 이었습니다.
그러니깐 DOM element가 아니니깐 스타일링을 할 수 없던것 이었습니다;;

이런 당연하고 뻔한걸 놓치다니..

그렇다면 이제 해결법은 너무나 단순해 집니다.
Header.js 에서 <div>를 스타일링 하면 되는것 이었습니다..