넵 저번 포스팅에서 drag and drop 에 대해서 정말 간단하게만 작성 하였는데


drop까지는 못했던것 같습니다.


그 마무리 작업을 하도록 하겠습니다.


// 자바스크립트를 이용한 드래그 앤 드롭 1탄!

https://ipex.tistory.com/entry/JavaScript-USE-HTML5-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%93%9C%EB%9E%98%EA%B7%B8-%EC%95%A4-%EB%93%9C%EB%A1%AD-Drag-and-Drop-using-JavaScript-and-HTML5


우선 저번 코드에서 해줘야 할 작업이 있습니다.


객체를 이동할건데요 이동하기 위해서 객체의 최상단에 id값을 하나 주도록 하겠습니다.


<div class="dragtarget" id="newTargetID">
        <div class="dragInner" draggable="true" ondragstart="dragStart_(event)" ondrag="drag_(event)">
            Drag Target
        </div>
    </div>



자 새롭게 id를 추가하였구요


dragStart부분에서


해당 id값을 던지기로 합니다.


   function dragStart_(e){
                console.warn('drag Start');
            var parentNode = e.target.parentElement;
            e.dataTransfer.setDragImage(parentNode,0,0);    

            e.dataTransfer.setData('targetId',e.target.parentElement.id);

        }


event.dataTransfer에 있는 setData로 데이터를 set하고 drop에서 getData로 받아 와서 사용 가능합니다.


** 드래그 이벤트는 보라색 영역만 받기 때문에 전체 태그가 드래그 하기 위해서 parentElement.id로 부모의 id를 넘기도록 합니다. id도 부모에 설정 하였구요


그리고 dropzone에 droppable ="true"는 설정 된상태겠죠? drop 이벤트에


e.preventDefault() 추가와

해당 id값을 가져와서 dropzone에 붙이도록 하겠습니다.


   function drop_(e){
            console.warn("drop");
            e.preventDefault();
            var targetId = e.dataTransfer.getData('targetId');

// e.target ( 현재 dropzone 태그 )

// e.target.appendChild (해당 dropzone 태그에 )

// document.getElementById(targetId) 드래그 하였던 타겟 (setData로 id를 넘김)

// 을 붙이도록 합니다.

            e.target.appendChild(document.getElementById(targetId));
        }



이 작업이 완료 될 시






드롭시!




깔끔하게 드롭된 점이 확인되네요


미천한 글 읽어주셔서 감사합니다.~


전체 소스코드 


<!DOCTYPE html>
<html>
<head>

    <title> 드래그앤드롭 </title>
    <meta charset="utf-8">
    
    <style>
    .dragtarget{
        width:100px;
        height:100px;
        background-color:tomato;

    }
    .dragInner{
        width:inherit;
        height:30px;
        background-color:slateblue;

        color:white;
    }
    .dropzone{
        position:absolute;
        width:500px;
        height:500px;
        background-color:yellowgreen;

        left:300px;
        top:300px;
    }
    </style>
</head>
<body>
    <div class="dragtarget" id="newTargetID">
        <div class="dragInner" draggable="true" ondragstart="dragStart_(event)" ondrag="drag_(event)">
            Drag Target
        </div>
    </div>
    <div class ="dropzone" droppable="true" ondragover="dragOver_(event)" ondrop="drop_(event)"> Drop Zone </div>
<script>
        function dragStart_(e){
            console.warn('drag Start');
            var parentNode = e.target.parentElement;
            e.dataTransfer.setDragImage(parentNode,0,0);    
            e.dataTransfer.setData('targetId',e.target.parentElement.id);
        }
        function drag_(e){
            console.log("drag");
        }
        function dragOver_(e){
            e.preventDefault();
        }
        function drop_(e){
            var targetId = e.dataTransfer.getData('targetId');
            console.warn("drop");
            e.preventDefault();
            e.target.appendChild(document.getElementById(targetId));
        }
</script>
</body>
</html>


안녕하세요 정말 오랜만에 포스팅을 하는거 같습니다... 


회사일이 너무 바쁜것..


이번 포스팅에서는 HTML5 에서 제공하는 Drag and Drop 에 대해서 작성할 예정입니다.


물론 테스트 브라우저는 Chrome 입니다.


우선적으로 HTML5에 drag and drop 에 대한 mdn 주소입니다.


// HTML5 drag and drop MDN

https://developer.mozilla.org/ko/docs/Web/API/HTML_%EB%93%9C%EB%9E%98%EA%B7%B8_%EC%95%A4_%EB%93%9C%EB%A1%AD_API


우선 드래그를 하기 위한 target 데이터와  드롭을 할수 있는 드롭 존  2개를 만들어 보도록 하겠습니다.



자 이렇게 2개의 div를 만들었습니다. (HTML 코드는 볼수 있도록 아래에 적어 놓겠습니다.)


해당 Drag Target을 드래그하여 초록색 Drop Zone 에 넣을 겁니다.


일단 그냥 드래그를 해볼까요?


역시 안됩니다.


드래그하기 위해서는 draggable 속성을 true로 주어야 합니다.


그런데 여기서 특이점이 제가 dragtarget을 일부러 2개의영역으로 잡았습니다.


반반씩 있는 영역이 아니라 dragtarget이라는 영역 내부에 dragInner를  넣은 형태 입니다.


    <div class="dragtarget">
        <div class="dragInner">
         Drag Target
        </div>
    </div>


코드는 이와 같습니다.


이렇게 한 이유는 조금있다 알수 있습니다.


드래그포인트는 dragInner 에만 줄려고 합니다. 다른 영역은 드래그는 대부분 제목 표시줄에만 되는경우가 많으니까요


자 드래그를 해봅시다



드래그가 되긴 하는데 썸네일이 조금 맘에 안드네요 ( draggable이 dragInner에만 들어가있어서 해당 객체에 대한 썸네일만 제공됩니다.)


최대 root객체를 지정하여서 다 같이 나오게 하고 싶은데요 이부분을 처리 해주는 곳이 setDragImage입니다. (IE에선안됩니다. )


테스트용이기 때문에 div 태그 안에 inline 으로 ondragstart 함수를 하나 만들어 줍니다.(태그안에 ondragstart같이 넣는 방법은 좋은 방법은 아닙니다. 지금은 테스트용이기 때문에 이렇게 작성합니다.


> addEventListener('dragstart',dragStart,false); 와 같은 형식을 취하는게 더 좋습니다.


div class="dragtarget">
        <div class="dragInner" draggable="true" ondragstart="dragStart_(event)"
ondrag="drag_(event)">
            Drag Target
        </div>
    </div>

function dragStart_(e){
        console.warn('drag Start');
}
function drag_(e){
    console.log("drag");
}


와 같은 형태로 작성을 해줍니다.


잘 되는 점확인이  됩니다. 이제 썸네일 부터 바꿔 보겠습니다.

event로 들어오는 값을 이용해서 작성 합니다.


function dragStart_(e){
                console.warn('drag Start');
            var parentNode = e.target.parentElement;
            e.dataTransfer.setDragImage(parentNode,0,0);    
        }


setDragImage의 첫번째 인자로는 썸네일 을 받게되는데 


event.dataTransfer.setDragImage(image, xOffset, yOffset);

를 확인해보면 image를 dragInner가 아닌 부모의 값 전체를 선택하게 하고 오프셋 x와 y 를 0으로 주게되면 현재 마우스의 위치에서 바로 부모의 객체가 나타날것으로 보입니다.



짜잔 ㅎㅎ    부모의 객체를 그대로 썸네일 형태로 가져와서 사용하게 됩니다.


이제 드래그가 가능한 상태가 되었고 해당 객체를 Drop Zone 에넣어 줘야 되는데요 아무리 이동을 해도 넘어가지 않습니다.


드래그가 가능하기 위해서 draggable 속성을 주게 되는데 드롭도 마찬 가지입니다. droppable  이라는 속성이 필요합니다.

<div class ="dropzone" droppable="true"> Drop Zone </div>


dropzone 에도 추가 해줍니다. 


draggable  ondragstart , ondrag 가 짬뽕이였듯이

droppable  ondrop   , ondragover 가 짬뽕입니다.

    <div class ="dropzone" droppable="true" ondragover="dragOver_(event)"
ondrop="drop_(event)"> Drop Zone </div>


        function dragOver_(e){
            console.log('dragOver');
        }

        function drop_(e){
            console.log("drop");
        }



하고 드래그앤 드롭시 보면 drop 이 발생하지 않는 점을 확인 하실수 있습니다.



mdn 에 는 dragover시 drop 을 활성화 하기위한 2가지 방법을 제시하고있습니다.


<div ondragover="return false">
<div ondragover="event.preventDefault()">

Calling the preventDefault() method during both a dragenter and dragoverevent will indicate that a drop is allowed at that location. However, you will commonly wish to call the preventDefault() method only in certain situations, for example, only if a link is being dragged. 

저는 event.preventDefault 로 처리하였는데 대부분 이 방식대로 처리 한다고 합니다.


Drop 처리가 되는 점을 확인 하실 수 있습니다.


하지만  실제 설정한 target이 이동되지는 않았기 때문에 이 이동에 대한 내용을 다음 에 작성 하겠습니다.


감사합니다.


코드


<!DOCTYPE html>
<html>
<head>

    <title> 드래그앤드롭 </title>
    <meta charset="utf-8">
    
    <style>
    .dragtarget{
        width:100px;
        height:100px;
        background-color:tomato;

    }
    .dragInner{
        width:inherit;
        height:30px;
        background-color:slateblue;

        color:white;
    }
    .dropzone{
        position:absolute;
        width:500px;
        height:500px;
        background-color:yellowgreen;

        left:300px;
        top:300px;
    }
    </style>
</head>
<body>
    <div class="dragtarget">
        <div class="dragInner" draggable="true" ondragstart="dragStart_(event)" ondrag="drag_(event)">
            Drag Target
        </div>
    </div>



    <div class ="dropzone" droppable="true" ondragover="dragOver_(event)" ondrop="drop_(event)"> Drop Zone </div>
<script>
        function dragStart_(e){
                console.warn('drag Start');
            var parentNode = e.target.parentElement;
            e.dataTransfer.setDragImage(parentNode,0,0);    
        }
        function drag_(e){
            console.log("drag");
        }

        function dragOver_(e){
            e.preventDefault();
            console.log('dragOver');
            
        }

        function drop_(e){
            console.log("drop");
        }
</script>
</body>
</html>


[2018-10-22]


React에서 setState시에  여러번 setState를 호출할시에는


setState({ 형태가 아니라 


setState((state,props) =>{

});

형태처럼 함수로 던져야 한다.

// 공식 홈페이지 

https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

[2018-10-20]


css 애니메이션에서는 하드한 작업을 하는 css 애니메이션과 그렇지 않은 애니메이션이 있다.


이에 앞서 기본적으로 브라우저 는 싱글스레드 기반이기 때문에 블로킹 로직 (for 문 ) 같은 경우가 있을 경우


UI 가 멈추는 현상이 발생한다. 이 그렇기 때문에 css animation 도중에도 블로킹 로직중 하나인 for문을 일정 이상 돌리


게 되면 애니메이션이 멈추는 현상이 같이 발생하게 된다.


하지만 모든 UI 가 멈추지는 않는다.


(브라우저 역시 C++기반으로 만들어졌고 OS 위에서 돌아가는 형태이기 때문에 js 만 JIT형태의 싱글스레드지 


브라우저 내부적으로는 싱글스레드 같은 형태를 사용할수가 있기 때문이다. Chrome에서는 이와같은 경우를 ServiceWorker로 해결하려고한다.



회사에서 일하다가 알게된건데 어떤 연구원이 직접 링크 해준 url이다.

@연구원님 감삼다

// 블로킹 로직을 취하여도 모든 UI가 멈추지 않는 현상 확인 

http://www.phpied.com/css-animations-off-the-ui-thread/


일부 애니메이션은 main thread 와 관계없이 실행되는 경우가 있다. 완전한 native 기반 (브라우저)


에 css 애니메이션은 main thread에서 도는것이 아니라 composite thread 에서 실행된다고 한다.(다른 스레드이기 때문


에 main thread에서 실행되는 블로킹 로직에 의해 ui 가 멈추는 현상이 발생하지 않는다. compositor thread에서 돌기 


떄문 (배움 노트이기 떄문에 배운거고.. 이에대해서는 따로 조사해봐야겠다)


대표적으로 공유 받은 내용에선


transform 과 opacity 의 경우에는 compositor thread에서 실행되기 때문에 블로킹 로직에 영향을 받지 않게 된다. 


background-color 같은 경우는 헤비한 동작으로 main thread에서 동작하게 된다.


// 관련 링크 공유

https://developers.google.com/web/fundamentals/design-and-ux/animations/animations-and-performance#css-vs-javascript-performance


와 같은 형태로  ** keyframe에서는 !important 가 무시됩니다.


@-webkit-keyframes blink {

    0% {

        -webkit-transform: scale(1);

        opacity: 1;

    }

    100% {

        -webkit-transform: scale(0.5);

        opacity: 0;

    }

}



링크를 안가보실까봐 중요    부분 을 캡처 하였습니다.


의문이 드는점은 Chroem,FireFox,Opera 정도면 IE는 ???? 아직 국내 웹에선 IE를 빼놓을수가 없다.... 언제 ts를 하지



[2018-10-15]


리덕스 - 상태관리 lib 




직접 그려본 도식도 흠흠 



[2018-10-03]


&& 연산자 - 가드 연산자


|| 연산자 - 기본 연산자


ex:



npm package.json 에서


^(minor,patch 는 업데이트 가능)

~(patch 업데이트)

x.x.x  모든 숫자 가능

< > <= >=  그대로의 의미를 가짐


npm 설치

npm i module@version 명으로 버전 명 설정 가능

ex:)

npm i cookie-parser@1.4.2


npm 업데이트

npm update ( 전체 업데이트 ) ^~ x.x.x.x => 등의 형태에 맞게 package.json 에있는

또는 


npm 부분 업데이트

npm update cookie-parser (특정 모듈)


npm 삭제

npm remove cookie-parser


npm 상태 확인(업데이트 가능한 리스트 확인)

npm outdated






'비공개 카테고리 및 미사용 카테고리 > 옛날 일기장' 카테고리의 다른 글

깍돌이 근황  (0) 2019.03.05
번아웃  (0) 2018.10.19
[이달의 배움] 2018년 8월  (0) 2018.08.21
파이썬  (0) 2016.07.27
마우스저거 참  (0) 2016.07.20

안녕하세요 QA 인데 qa자료가 제일없는거 같아서 조금 그렇네용...



오늘은 IE11버전 이하 IE 10버전 부터 발생하는 이슈 중 특이한 이슈가 있어서 작성하게 되었습니다.


시작은 즉슨 .. IE 9 버전에서 기능이 이상합니다.! 라는 이야기와 함께 찾아봤습니다.


준비물


window.onbeforeunload  && a 태그와 href 속성


요약 

a태그가 눌릴때마다 window.onbeforeunload 가 호출되는 현상 IE 구버전에서 발생하게됩니다.


내용 

<a href="javascript:pay();" class="btn_b btn_red"><span>결제하기</span></a>


 와 같은 코드가 있을때


해당 DOM 에 만약에 window.onbeforeunload 가 들어가 있을 경우


해당 a태그가 클릭될때마다 onbeforeunlaod에서 작성된 함수가 계속 실행됩니다.


노답 버그!


해결법

1번 href를 쓰지 말고 onClick 을 사용합니다. 


2번 의 경우는 오류가 났던 사이트 개발자 분이 직접 이렇게 사용하여서 해결했다고 합니다. 


jQuery 를 사용한 방법인데요


$(window).data('beforeunload',window.onbeforeunload);

     $('a[href^="javascript:"]').hover( 

        function(){window.onbeforeunload=null;},

        function(){window.onbeforeunload=$(window).data('beforeunload');}

    );

약간의 꼼수(?) 느낌으로 이렇게 해결했다고하네요


약간의 설명이들어가자면     $('a[href^="javascript:"]').hover( 

는 a태그중 href속성에서 javascript: 로 시작하는 모든속성에 대한 .hover 작업입니다.


아래의 hover 속성에 보면 param 으로 2개가 들어가있죠 , 로 나눠져있는걸 보면


jQuery 를 안쓰는 요즘 분들? 또는 jQuery 자체를 안쓰시는 분들은 이해가 안되실수도 있으니


jQuery doc를 확인해보면


.hover( handlerIn, handlerOut )


이렇게 되어있습니다.


말그대로 들어올때, 나갈때인거죠 


클릭하기위해서 마우스가 올라왔을때 window.onbeforeunload를 빼버립니다. 그리고 클릭하면서 href가 실행된 후


밖으로 나갈때 다시 원래의 값을 붙여줍니다. 



부족한 글 읽어 주셔서 감사합니다.~




'QA > QA 활동' 카테고리의 다른 글

QA 업무 중 자료 구조?  (0) 2019.01.28
좋은 테스트 코드 및 테스트의 특성  (0) 2018.11.15
Daily note  (0) 2016.09.28
윈도우즈 GPT Convert MBR  (0) 2016.07.05
Back ground 쉘  (0) 2016.06.21

안녕하세요 오늘은 제가 테스트 하는 툴중에 Windows Application 이있는데


사용하다보니 자꾸 느려지고 (오래 사용도 안했는데) 이에 대한 케이스도 정확하지 않고



매번 연구소에다가 


" .. A작업 하다가 느려지는거같아요 .. 이부분 확인 좀 .. 부탁 드릴게요 .."


".. A하다가 -> B하고 D하면 느려지는거 같은데요?? "


아 이런거는 뭔가 내가 생각해도 사용자가 제품 쓰고 Q&A 하는 느낌이였다.


아 물론 QA활동 중 에 사용자 경험을 위주로 하는 활동도 있기 때문에 틀린 행동이나 작업은 아닌데


QA라면 뭔가 더 전문적이여야 하지않을까


"A작업시에 갑자기 heap memory 가 튀는거 같은데  이부분 동적 할당 (malloc) 처리가 제대로 됐는지 코드 확인 부탁 드립니다."


아.. 너무 좋은거같네요 뭔가 일한 느낌


메모리 는 Heap 만 생각 하겠지만


생각보다 더 복잡 합니다. 


그래서 메모리 모니터링툴을 하나씩 찾아서 포스팅 할 예정인데


가장 먼저 나오는


Windows VMMap 을 사용해보려고 합니다.


해당 모니터링 해주는 트리는 되게 많습니다.


Image, 

Mapped File

Shareable

Heap

Managed Heap

Stack

Private Data

Page Table

Unsuable

Free


제대로 사용하려고 마음먹었다면 위의 메모리 저장소나 관리 사용 하는 위치 등에 대해서 자세하게 쓸 것 같은데


결론적으로는 저는 이 툴 사용은 안하기로했습니다.


사용시간은 2시간 내외 입니다. (처음 사용시 최소한의 모니터링은 할수 있어야 된다고 생각 합니다.)


1. Interval 형식으로 View를 해주지 않습니다.


물론 옵션은 있습니다. Options -> Trace Snapshot Interval - [1 Second], [ 2 Second ] 5 10 등등

그런데 이게 되는건지 확인이 잘 안됩니다. 우측 하단에 Trace.. 라는 메뉴가 있긴한데 따로 출력되거나 입력

되는것도 있지 않고 여튼..  계속 확인하려면 F5키를 눌러줘야되는데 실시간 모니터링 해주는 다른 툴이 있을거라

생각합니다. ... (후)


2. 메모리 사용량이 너무 높습니다.

아니 메모리 모니터링 하는 툴이 메모리 사용량이 기하학적으로 높아집니다. 

인터벌로 뿌려주는것도 아니고!

제가 사용하는 램이 16G를 쓰는데 이거 혼자서 14G까지 먹습니다. 20분 정도 틀었을시에

메모리 분석하는 툴이 메모리 누수가 있다니요 (추측)  별론거 같아요 Windows 7 64비트 기준입니다.

분석 결과 보기전에 제 PC가 죽겠습니다.

(시나리오 확인결과 현재 메모리 확인이 안되니까 -> F5로 새로고침해서 확인할때마다 누수가 발생.. 하는것 같습니다.)


메모리 사용값 분석해서 화면에 뿌려주는  툴이 용량이 이렇게 올라가는건 좀 아닌거 같아요 ㅋㅋㅋ

3. ETC

잠깐만 썻지만 뭔가 사용성에는 적합하지 않다고 생각합니다. (QA입장에서)

개발자 입장에선 나쁘지않을것 같은게 메모리 leak 이 의심되는 구간에 대한 코드를 돌리기전에 한번 확인하고

돌린 후에 확인시에 메모리 변동 추이는 확실하게 확인이 가능하니까요 

하지만 사용성을 확인하면서 메모리 튀는 부분을 확인하는 QA 입장에선 별로 좋다고는 못 느껴서 일단 다른 툴들을

찾아 보도록 하겠습니다. (다른게 더 별로면 VMMap 으로 돌아올수도있고.. )


정말 없으면.. 모니터링해서 숫자로 표현하는 정도는 뭐.. 만들어서 쓰죠 


글 읽어주셔서 감사합니다.









'QA > 테스팅 관련 툴' 카테고리의 다른 글

vscode remote 사용 후기  (0) 2018.06.27
UNIX signal  (0) 2016.07.15
QA_테스팅의 종류  (0) 2016.06.21



Node.js 웹 어플리케이션 프레임워크 - > Express !  뭔가 이름부터 짱짱 멋지네요


비슷한 프레임워크로 koa가 있다고는 하는데 뭔가 익숙한 Express에 대해서 작성 해놓으려고 합니다.


현재 사용중인 버전은 express 4.16.3 버전을 사용중에 있습니다. (2018-09-19)


이외에 같이 사용중인 npm Module은


cors 2.8.4

iconv-lite 0.4.24

morgan 1.9.1

multer 1.3.1

joi 13.6.0

faker 4.1.0 정도가 있겠네요


Node.js 가 설치 된 상태라고 가정 시에


express를 설치 하겠습니다.



      mkdir praticeExpress
      cd praticeExpress
      // npm 초기화 
      npm init 
      // express 설치 
      npm i express 
      // express 구조 파악을 위한 express-generator 설치  전역에서 사용하기 위한 -g 옵션 
      npm i express-generator -g 
      // 단순 구조파악을 위한 pug 프로젝트 생성
      express --view=pug testApp
      cd testApp
      npm install
      // LInux 기준 실행 
      npm start
  


구조 파악을 위한 generator 후에 구조 입니다.


.
├── app.js
├── bin
│   └── www
├── package.json
├── public
│   ├── images
│   ├── javascripts
│   └── stylesheets
│       └── style.css
├── routes
│   ├── index.js
│   └── users.js
└── views
    ├── error.pug
    ├── index.pug
    └── layout.pug

[공식 홈페이지 https://expressjs.com/ko/starter/generator.html ]



app.js 부터 보겠습니다.


1. app.js

불러 오는 모듈들이 엄청 많네요

http-errors,express,path,cookie-parser,morgan, ./routes/index , ./routes/users


이중에서 불러오는 모듈들에 대해서는 각각 모듈에 대해 검색? 으로 찾을수 있는 부분들이라고 생각되서 이를 제외한 것들에 대한 확인을 하였습니다.


var app = express; // 공식 홈페이지에 이와같이 쓸수 있도록 가이드 되었습니다. 따라갑시다


// views -> 사용하는 템플릿 엔진 이 있는 디렉토리 설정 

app.set('views ', path.join(__dirname,'views'));

// 뷰 엔진 설정 - express에서 사용할 템플릿 엔진을 설정합니다. pug로 생성했기 때문에 pug로 지정하네요

app.set('view engine','pug');


// * 만약에 뷰엔진을 지정하지 않았을시에는 index.pug 라고작성해 주어야 하지만

// * 뷰 엔진을 pug로 지정하였을 경우는 index라고만 써도 index.pug로 인식하여 동작합니다.

// * res.render('index')      < - > res.render('index.pug')


// ** 템플릿 엔진 사용시에는 관련 모듈도 설치 하셔야됩니다. npm i pug 



// app.use

공식 홈페이지에는 이와같이 나타나있습니다.


지정되는 경로에서 지정된 미들웨어 기능을 탑재


app.use([Path],callback[,callback ...])


path : 미들웨어 기능이 호출되는 경로  Default [ '/' ]

 - 경로를 나타내는 문자열

 - 경로와 패턴

 - 경로와 일치하는 정규식 패턴

 - 위의 조합의 배열


callback : 콜백 함수                         Default : None

 - 미들웨어 기능

 - 일련의 미들웨어 기능 , 로 구분 

 - 미들웨어 기능의 배열

 - 위의 조합의 배열

자세한 내용은 따로 포스팅 하겠습니다.  

아래의 코드들에 대해 설명을 달자면

// express.json 은 express 16 버전 부터 사용 가능 

// express 내장 미들웨어 로 JSON 을 구문 분석 및 Content-type 헤더가 type 옵션과 일치 하는 요청을 보고하는

// 미들웨어를 반환하여 use ( 현재 express에서 사용 합니다. )

// 만약에 Content-type이 맞지 않거나 등의 오류가 발생하면 request 는 req.body 에 채워지는데 {} 값으로 채워집니다.


app.use(express.json());


// urlencoded 역시 내장된 미들웨어로 body의 인코딩을 UTF-8 로 받아 처리해준다.

// extended: 옵션은 기본값은 true이며 true일 경우  

// URL-encoded data와 querystring library 또는 qs 라이브러리 사이의 파싱을 선택할수 있게 허용한다.

// false로 주게 되면 이 부분은 허용하지 않게 한다. ( express 자체적으로 처리 )

app.use(express.urlencoded({ extended: false }));


// express 내장 미들웨어로 루트 디렉토리에서 정적 데이터들 위치를 지정한다. 

// req.url 로 제공된 root디렉토리 와 결합하여 제공할 파일을 결정 

app.use(express.static(path.join(__dirname,'public')));


// 라우터를 사용  -> routes 에서 다시 

app.use('/',indexRouter);

app.use('/users',usersRouter);


// 이외 코드들은 express 에러 핸들링 코드로 되어있는데 이부분은 따로 다뤄야 할것 같습니다.!


2. bin

실행 파일을 놓은 폴더 입니다.  (현재는 어떤 느낌인지 정도만 보고 넘어갑니다.)

3. package.json

현재 사용하는 npm 프로젝트의 의존성 파일입니다.

4. public

정적 파일로 사용할 폴더입니다. 대부분 리소스 파일들을 놓습니다.

해당 폴더를 사용하기 위해서 app.js에서는

express.static이라는 메서들를 사용합니다.

app.use(express.static(path.join(__dirname,'public')));


5. routes

express에서 use로 사용하기로 되어있던 라우터들이 있는 폴더 입니다.

app.use('/',indexRouter);

app.use('/users',usersRouter);

// 로사용 


var express = require('express');


// **** express.Router는 새로운 Router 오브젝트를 반환 해주는 express API 입니다.

var router = express.Router();



/* GET users listing. */

// / 로 작성하였지만 실제 app.js에서는 app.use('/users'/로 경로를 지정하기 때문에

// / 로 작성하여도 실제 동작은 /users 가 됩니다. 


// get으로 /totalUser 라고 작성시에는 실제로는

// /users/totalUser에 대한 라우팅을 실행합니다. ** app.use('/users', ... ) 로 호출하였을 시에


router.get('/',function(req,res,next) {

res.send('respond with a resource');

});


// 위의 만들어진 router를  module.exports를 통하여 exports 합니다. 


// app.js 에서는 var userRouter = require('./routes/users'); 로 사용 

module.exports = router; 


6. views

express에서 사용할 뷰 (views) 템플릿 엔진이 있는 폴더 입니다.

app.set('views ', path.join(__dirname,'views')); 로 지정 



generator를 통해서 기본적인 구조를 파악 한 후에 간단한 더미데이터를 던져 주는 서버를 제작해 보았습니다.


// dummy Data Server

https://github.com/lgance/VanillaJS/tree/master/myVanillaJS/legacy/dummyServer


사용은 


git clone https://github.com/lgance/reactStudy.git 로 클론을 뜬 후에 내부에 dummyServer가 있을 겁니다.


cd dummyServer 


npm update ( package.json 과 package-lock.json 을 통한 모듈 설치 -> git에는 node_modules를 올리지 않음 )


node app.js


요청은  localhost:3505/dummys?columns=20&rows=50 와같이 사용하시면 됩니다.


원하는 컬럼과 로우에 맞게 데이터를 던져 줍니다(JSON) 


[결과]













git을 쓰다보면 예전에 만들어 놓은 폴더를 날리고 싶은데


gitlab 같은 웹페이지에서는


파일 자체 삭제는 제공하지만  폴더 통째로 날리는 법은 제공을 안해주는 것 같습니다.


그래서 어떻게 하면 지울수 있을까 하다가


찾아본 방법이 있습니다.


우선 git CLI 에서 git pull 을 해야 될거 같으니 이거 먼저 합시다 


git pull


git rm -r --cached [날리고싶은 폴더]


> 만약에 

[폴더] TestA

[폴더] TestB

[폴더] TestC

[폴더] TestD

[파일] .gitignore

[파일] README.md


이형식인데

A,B를 git에서 제거하고 싶다!


git rm -r --cached TestA

git rm -r --cached TestB


하게되면 현재 두 폴더에 대한 캐시가 날아가게 됩니다.( 없다는것 처럼 인식 )


git commit -m"TestA TestB 삭제"


.gitignore에서 저 위에 폴더 실제로 삭제 되진 않았기 때문에


.gitignore 파일


/TestA

/TestB


위와 같이 .gitignore파일을 작성 후


git push origin master


!! 짜잔 해당 폴더가 없어졌네요



** 번외 편 폴더 추가 

// 폴더 생성

mkdir addFolder


// 생성된 폴더 안에 .gitkeep 생성 // git은 폴더만은 인식 하지 못하기 때문에 파일을 넣어 줌

touch addFolder/.gitkeep


// git status 에서 인식이 되기 때문에 추가 가능 폴더를 추가

git add addFolder


// 마스터 푸쉬!

git push origin master


포스팅 읽어 주셔서 


감사합니다.






안녕하세요 오늘은 gitlab 에있는 웹훅 (webhook) 기능을 사용하다 발생한 이슈에 대해서 작성 하려고 합니다.


최신 버전 GitLab 에서 같은 서버에있는 CI(Jenkins) 에 webhook 을 요청시에는


Internal Server Error 500 이 나타납니다.


일단 해당 이슈는 ssrf 관련 이슈이기 때문에 gitlab ssrf 라고 검색 하여도 충분한 결과를 얻을수는 있을 겁니다.


ssrf이슈인지 파악이 안됐었.. ㅜ


해당 내용 설명에 앞서 ssrf에 대해서 간단하게 작성하자면


SSRF ( Server - Side - Request - Forgery ) 서버 요청 위조 

CSRF ( Client - Side - Request - Forgery ) - 클라이언트 요청 위조

SSRF는 CSRF 와 달리 서버가 직접 호출해서 발생하는 문제입니다.  서버가 직접 요청하는 바람에 외부에서 내부에 있는 리소소스 등 접근해서 서버 직접 제어가 가능해지기 때문에 해당 의 경우 SSRF의 위험성이 있기 때문에


Jenkins 서버와 GitLab이 같은 서버에 위치할때 루프백 (자기자신) 으로 요청하게 되면 SSRF 가 발생하게됩니다.


gitlab webhook 은 기본적으로 내부 서버 요청을 서버가 직접 하는것들을 SSRF 이슈로 인해 허용하지 않기 때문입니다.


그래서 기본적으로 gitlab 생성후 webhook 을 내부 같은 서버에 있는 jenkins(CI)에 호출하게되면 500 Internal Server Error 가 발생합니다.


우선 gitlab 업데이트 노트를 보겠습니다.



SSRF 이슈때문에 설정을 변경하여야 한다고 되어있습니다.


GitLab 에 접속합니다.  (ROOT 계정)


루트 계정으로 접속하게되면 위와같이 admin Area 가 있습니다. 해당 스패너를 클릭합시다.




최하단에보면 Settings 라고 있습니다.


그리고 우측에서 쭉 내리다보면


Outbound requests가 있습니다.

Expand 해 주신 후에

Allow requests to the local network from hooks and services 

체크 해줍시다.





자 이제 gitlab을 재시작 하고 webhook 을 테스트 해보면 정상적으로 됨을 확인 하실수 있습니다.


gitlab 시작 및 종료


sudo -s gitlab-ctl start

sudo -s gitlab-ctl stop


gitlab 재 설정 후 재 시작


sudo -s gitlab-ctl reconfigure


// gitlab 기본 설정 

https://ipex.tistory.com/entry/gitlab-기본-설정?category=768899




감사합니당~




// 가상 터미널 체인지 총 6개 가능


Ctrl + Alt + F1 

Ctrl + Alt + F2 

Ctrl + Alt + ... 


안녕하세요 리액트를 제대로하기전에 


라이프 사이클 까지보았고 이번에는 리액트의 스타일에 대한 작성을 해보려고합니다.


기본적으로 앞서서 스타일을 작성하는 방법에서는


2가지 방법이 있었죠


1. Inline Style CSS 

인라인 방식의 CSS는 클래스 또는 컴포넌트형 함수들 에서 

js Object 형식으로 만들어서 직접 태그에 넣는 방식의 스타일 방식입니다.


인라인 스타일 방식입니다.


render 함수에서 직접 작성합니다.


render() {
const tempStyle={
display:"inline-block",
width:"100px",
height:"100px",
boder:"1px solid black",
background:"orange",
}
return (
<Fragment>
<div style={tempStyle}></div>
</Fragment>
);
}
}


const tempStyle 이라고 작성된 style을 직접 리턴하는 태그에 style로 넣어주게됩니다.

위의 코드에서는 변수를 만들어서 넣었지만 같은형식으로 태그에도 직접 넣어줘도 됩니다.


<div style={{
display:'inline-block',
width:'100px',
height:'100px'
}}></div>



해당 인라인으로 작성후 npm start 로 확인 시 


정상적으로 렌더링 된점을 확인 하실 수 있습니다.


이 방식이 인라인 스타일 방식입니다.



2. Import Style CSS

미리 작성해둔 CSS를 불러와서 (import) 태그에 className으로 작성하여서 사용하는 스타일 방식

import 하여서 css를 사용하는 경우 다른 경우(리액트가 아닌 경우) 에서는


<link rel="stylesheet" href="./style/styles.css"/> 와 같은 방식으로 가져오게 되지만


리액트에서는 import 구문을 통하여서 가져와야합니다.


import styles from './App.css';


해당과 같이 호출 하여서


<div className={styles.box} ></div>


.box{
display:inline-block;
width:100px;
height:100px;
border:1px solid black;
position:fixed;
top:50%;
left:50%;
transform:translate(-50%,-50%);
}


의 box 클래스를 가져와서 입힐 때는 위와같이 작성하여야 합니다.

하지만 작성엔 문제가 없지만


화면에 렌더링시에는 나타나지 않습니다.


왜!!!? webpack 설정이 안되어있기 때문이죠 


테스트용이기 때문에 webpack production 은 건드리지 않고 dev만 건드리면


webpack.config.dev.js 에  css-loader 부분이 있습니다.


** 만약에 create-react-app 으로 만들어졌는데 webpack.config.dev.js가 없다면??

해당 프로젝트에서 npm run eject 명령어를 입력하시면 해당 파일이 생성됨을 확인하실수 있습니다.


이부분에


loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
// modules 지정안할시는 아예 import가 되지않음
modules:true,
},

modules 옵션을 추가해줍시다.!!


그러면 정상적으로 화면에 렌더링이 되는 점을 볼수 있습니다.


위의 코드에서 styles.box 로 넣었지만 리액트는 여러개의 클래스도 넣을 수 있습니다.


<div className={[styles.box,styles.blue].join(' ')}></div>



해당 방법은 너무 지저분하기도 하고 코드 가독성도 그냥 그래서 조금 더 줄이기 위해서 classnames라는 lib를 사용한다고 합니다.



npm i classnames


- .join 이 빠지고 단순 괄호로 묶어서 사용 ( 하지만 style.box style.box  style이 중복되는 현상 발생 )

>classnames에 bind라는 기능을 사용 !! 



import classNames from 'classnames';


<div className={classNames(style.box,style.blue)}></div>




결과


from classnames를 classnames/bind로 꼭 수정하셔야됩니다.


const st = classNames.bind(styles);


-> 해당 css파일들에 대한 클래스를 st가 묶어서 가지고 있는 것으로 보입니다.


그래서 결국 다중 클래스 를 집어 넣을시에는


st('box','second',third') 로 하게되면


App.css에 있는

.box{}   .second{} .third{} 가 순서대로 불려와집니다.


중복되는 클래스가 있을 경우 뒤의 css 스타일이 적용됩니다. (유의바람!)


import React, { Component,Fragment} from 'react';
import classNames from 'classnames/bind';
import PropTypes from 'prop-types';
import styles from './App.css';


const st = classNames.bind(styles);

class App extends Component {
static propTypes = {
name: PropTypes.string,
}
render() {
const isBlue = true;
const tempStyle={
display:"inline-block",
width:"100px",
height:"100px",
boder:"1px solid black",
background:"orange",
}
return (
<Fragment>
<div className={st('box',{
blue:isBlue
})}>
</div>
</Fragment>
);
}
}
export default App;



다음에는 sass에 대해서 작성하겠습니다!

+ Recent posts