Develop

Develop/React.js

[React] fetch 로 통신하기

React에서 fetch는 JavaScript의 내장 API인 fetch() 함수를 사용하여 서버와 데이터 통신을 수행하는 방법이다. fetch 함수는 ES6부터 기본적으로 제공되는 함수이며, React 애플리케이션에서 AJAX 요청을 보낼 때 많이 사용된다. AJAX 란? AJAX는 "Asynchronous JavaScript and XML"의 약자로, 웹 애플리케이션에서 비동기적으로 서버와 데이터를 교환하기 위한 기술입니다. AJAX를 사용하면 페이지 전체를 새로 고치지 않고도 서버로부터 데이터를 가져오거나 서버에 데이터를 보낼 수 있습니다. 기존에는 웹 페이지에서 사용자의 요청에 따라 새로운 페이지를 서버로부터 전체적으로 다시 받아오는 방식인 전통적인 동기적인 요청 방식이 일반적이었습니다. 하지만 ..

Develop/React.js

[React] tooltip 구현하기

이렇게 마우스를 올려다 댔을 때 이게 어떤 버튼인지 미리 알 수 있는 문구가 나오게 하려면 tooltip 이라는 기능을 구현하면 된다. React에서 tooltip 을 구현하려면 여러 라이브러리를 활용해서 구현할 수 있는데 나는 그중에서도 react-tooltip 이라는 라이브러리를 사용해보려고 한다. https://react-tooltip.com/docs/getting-started Getting Started | React Tooltip This docs is related to V5, if you are using V4 please check here. react-tooltip.com 자세한 설명은 위에 나와있다. 본인도 공식문서를 보고 적용했기 때문에 빠르고 적용법만 보고싶은 분은 아래를 참고하시..

Develop/HTML, CSS

[HTML, CSS] 스크롤 기능 구현하기

캡스톤 프로젝트 중에 특정 구역 내에서 스크롤을 기능할 일이 생겨서 작성해보는 포스팅! 채팅창을 만드는데 채팅창에 있는 채팅 메세지 내용들만 스크롤이 가능하도록 할 것이다. 방법 tailwindcss 버전 import React from 'react'; function MyComponent() { return ( {/* 스크롤이 필요한 컨텐츠 */} ); } overflow-y-scroll 을 이용해서 스크롤이 필요한 컨텐츠를 감싸준다. 기본 css 버전 import React from 'react'; function MyComponent() { return ( {/* 스크롤이 필요한 컨텐츠 */} ); } 마찬가지로 overflow-y : 'scroll' 속성을 추가해준다. 스크롤이 넘치지 않도록 하고..

Develop/React.js

[React] useDebugValue

useDebugValue 란 React Hooks 중 하나로 개발자 도구 Dev Tools 에서 컴포넌트의 상태를 디버깅할 때 사용하는 함수이다. 사용법 useDebugValue 는 두개의 인자를 받음 첫번째 인자는 디버깅에 사용할 값(value) 두번째 인자는 옵션 객체이다. 예시 import { useDebugValue, useState } from 'react'; function useCounter(initialValue) { const [count, setCount] = useState(initialValue); useDebugValue(count, count => `Count: ${count}`); function handleIncrement() { setCount(count + 1); } fu..

Develop/React.js

[React] useRef

useRef 란 useRef는 React에서 제공하는 Hook 함수 중 하나로, 일반적으로 DOM 요소를 선택하거나 컴포넌트에서 변경 가능한 값을 저장하는 데 사용된다. 예시 예를 들어, useRef를 사용하여 DOM 요소를 선택하는 경우 다음과 같이 코드를 작성할 수 있다. import React, { useRef, useEffect } from 'react'; function Example() { const inputRef = useRef(null); useEffect(() => { inputRef.current.focus(); }, []); return ; } 위의 코드에서 useRef를 사용하여 input 요소를 선택하고, useEffect를 사용하여 컴포넌트가 마운트될 때 input 요소에 자동..

Develop/React.js

[React] useCallback

useCallback 이란 React의 useCallback 훅은 성능 최적화를 위해 사용되는 훅 중 하나이다. 이 훅은 함수를 캐시(cache)하여 불필요한 함수 재생성을 방지하고, 성능을 최적화하는 데에 도움을 준다. 사용법 useCallback은 두 개의 인자를 받는다. 첫 번째 인자는 캐시할 함수이며, 두 번째 인자는 의존성 배열(dependency array)이다. 의존성 배열에는 캐시할 함수에서 참조하는 값들이 포함되며, 이 값들이 변경될 때마다 함수를 다시 생성한다. 예시 예를 들어, 다음과 같은 코드가 있다고 가정하자. import { useState } from 'react'; function MyComponent() { const [count, setCount] = useState(0)..

Develop/React.js

[React] Link와 useNavigate의 차이점 알아보기

React에서 페이지 이동을 구현할 때, Link 와 useNavigate 이라는 개념을 사용한다. 하지만 둘의 분명한 차이점이 있는데, 사용하다보니 궁금해져서 정리해보고자한다. Link Link는 클릭할 때 바로 이동하는 로직을 구현할 때 사용된다. 원래 페이지가 새로고침되면 현재 렌더링되어있는 컴포넌트가 다 사라지고 새로 컴포넌트가 렌더링 되는데, 이때 state 들이 모두 날아간다. 하지만 Link 를 사용한 경우에는 렌더링된 컴포넌트의 state 가 유지되어서 SPA로 동작할 수 있다. 실제 해당 링크로 이동하는 것이 아니라, 에 지정된 컴포넌트를 렌더링한다. * v6 부터는 Link 로 props 를 전달하지 못한다. (이것때문에 한참 붙잡고 있었다...) 예시 예를 들어서 상품 리스트를 클릭했..

Develop/JavaScript

[JavaScript] 비구조화 할당

React 를 공부하다가 '비구조화 할당' 이라는 개념에 대해서 확실히 정리하고 넘어가고 싶어져서 쓰는 포스팅! 비구조화 할당이란 비구조화 할당(Destructuring Assignment)은 배열이나 객체의 속성을 해체해서 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 의 표현식이다. 쓰는 이유 이는 배열이나 객체의 속성을 쉽게 꺼내서 변수에 할당할 수 있으므로 더 간결하고 가독성이 높은 코드를 작성할 수 있다 예시 예를 들어 다음과 같은 객체가 있을 때, const person = { name: 'John', age: 30, gender: 'male' }; 이 객체의 속성을 꺼내서 개별 변수에 할당하려면 다음과 같이 할 수 있다. const name = person.name; const..

Develop/React.js

[React] Fragment 문법을 왜 쓸까

왜 쓰는 거야? React 에서 JSX 를 사용할 때 return 문에는 무조건 최상위 태그가 존재해야한다. React 는 하나의 컴포넌트만을 return 할 수 있기 때문이다. 이때, Fragment 라는 걸 사용할 수 있는데 이는 불필요한 div, span 등의 HTML 요소 없이 여러 개의 자식 요소를 렌더링 할 수 있도록 하는 기능이다. Fragment 를 사용하면 컴포넌트의 여러 요소를 그룹화할 수 있다. 예시 예를 들어 App() 에 Table() 이라는 컴포넌트를 넣어서 사용하고 싶은 경우를 생각해보자. Table 컴포넌트는 다음과 같다. function Table() { return ( Hello World ); } 여기서 Table 컴포넌트 내의 태그들을 묶기 위해 최상위 태그로 div ..

Develop/React.js

[React] 긴 문자열 자르고 '...' 붙이기

요소들을 리스트로 보여주는데, 제목이 너무 길어서 넘어가는 문제가 생겼다. 줄을 넘어가면 grid 가 흐트러지기도하고, 보기에도 통일성이 없어보여서 너무 길면 적당히 자르고 끝에 ... 을 붙이도록 해봤다. 현재는 위와 같은 상태이다. 맨 오른쪽 요소를 보면 제목이 너무 길어서 아래줄까지 침범했다. 저 제목 데이터는 name 이라는 변수에 들어있었는데, processedName 이라는 이름의 변수로 새로 만들어줬다. const processedName = name.length > 15 ? `${name.slice(0, 15)}...` : name; 나는 15자가 넘어갈 경우 문자열을 자르고, 끝에 ... 이 붙도록 코드를 작성해봤다. processedName 변수를 적용해서 다시 화면을 구성해보겠다. 원..

Develop/HTML, CSS

[HTML, CSS] 당근마켓 클론코딩

다시 초심(?)으로 돌아가 html과 css 만을 이용해서 당근마켓 사이트를 클론코딩해보는 미니 과제! 일단 내가 구현하고자 한 사이트는 아래와 같다. https://www.daangn.com/ 당신 근처의 당근마켓 중고 거래부터 동네 정보까지, 이웃과 함께해요. 가깝고 따뜻한 당신의 근처를 만들어요. www.daangn.com 일단 여러 탭 메뉴 중에 '중고거래'에 해당하는 페이지만 클론코딩해보았다. Javascript 를 활용한 기능은 한가지만 넣었는데, 검색창에 무언가를 입력하고 채팅하기 버튼을 눌렀을 때 alert 으로 무슨 input 을 넣었는지 띄워주는 기능이다(정말 별거 아니지만 넣어보았다) 코드 코드는 아래와 같다. 파일을 따로 분리하지는 않았고 index.html, index.css 에 ..

Develop/React.js

[React] CommonJS module / ES module

리액트 스터디를 진행하다가 CommonJS module 과 ES module 이 언급이 되었는데 정리해볼겸 포스팅한다. 자바스크립트는 파일마다 독립적인 Scope(범위)를 가지지 않고 하나의 전역객체를 공유해서 사용한다. 대신 이렇게 되면 전역변수가 중복이 되는 문제가 생길 수 있다. 이러한 문제점을 해결하기 위해서 Node.js 에서는 사실상 표준이라고 할 수 있는 CommonJS를 채택하였다. 따라서 각각의 모듈들은 각자의 Scope를 가질 수 있게 되었다. 하지만 브라우저에서는 이를 지원하지 않았다. 그래서 ES6에서 이를 해결하기 위해 모듈 기능을 추가하게 되었다. 비교 ES Modules - module loader 를 비동기 환경에서 실행, import / export 구문을 찾아서 파싱 - ..

Develop

개발과 개선을 빠르게, DevOps

DevOps, 요즘 이리저리 많이 들리는 단어이다. 많이 들리다보니 개념이 정확이 무엇인지 궁금해졌고, 관련 영상과 글을 찾아보다가 이참에 정리해서 포스팅을 하면 좋겠다 생각했다.오늘날의 작업방식디지털 트랜스포메이션 시대의 기업들은 기술 혁신에 대한 도전에 직면하고 있다.2000년대 포춘 500대 기업의 절반이 디지털 트랜스포메이션이라는 거대한 도전앞에 새로운 기술기반 기업들에게 자리를 내주어야 했다.고객 가치를 빠르고 개선된 형태로 전달해주는 문제는 이제 단순히 매출을 조금더 올리는 문제가 아니라기업 생존의 문제가 되었다. 새로운 기술을 통해 서비스를 빠르게 개선하고, 가치있는 고객 경험을 전달함으로써 지속적인 혁신을 할 수 있는 환경을 만들어야하는 것이다. 소프트웨어 개발환경, 어떻게 혁신해야할까?D..

Develop/React.js

[React] Swiper로 이미지 슬라이드 구현 / 화살표 색변경

작은 프로젝트를 개발하다가 사진 슬라이드를 구현해야할 일이 있어 Swiper 를 선택하게 되었다. https://swiperjs.com/react Swiper React Components Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior. swiperjs.com 공식 문서에 들어가서 찬찬히 보면 된다. npm i swiper 일단 터미널에서 설치부터하고, 아래와 같이 사용하면 된다.(공식문서 예제다) // import Swiper core and required modules import { Navigation, Pagination, Scroll..

Develop/React.js

[React] Tailwind CSS 사용하기

styled component 를 써오던 나였는데, 이번에 동기와 작은 프로젝트 개발을 하나 하면서 동기가 tailwind css 에 대해서 알려줬다. 일단 공식은 여기다 https://tailwindcss.com/docs/installation Installation - Tailwind CSS The simplest and fastest way to get up and running with Tailwind CSS from scratch is with the Tailwind CLI tool. tailwindcss.com 사용 방법 일단 터미널에서 설치부터 npm install -D tailwindcss npx tailwindcss init 그리고 tailwind.config.js 파일에다가 module..

Develop/Git

[Git] git stash

저번에 개발을 하다가 알게된 새로운 git 명령어가 있어서 정리한다. git stash 란? 만약에 내가 작업을 하다가 브랜치를 변경해야할 일이 생긴다면 하던 작업물들을 커밋하기는 그렇고... 어떻게 해결해야할까? git stash 를 이용하면 된다 git stash 란 하던 작업을 임시로 저장해두고 싶을 때 사용하는 명령어이다. 변경사항을 스택에 잠시저장을 하고, 나중에 다시 꺼내올 수 있다. 이때 git stash 명령을 사용하면 워킹 디렉토리에서 수정한 파일만 저장을 한다. 명령어 정리 ⭐git stash : 스택에 새로운 stash가 만들어진다. 이 명령을 하면 워킹 디렉토리는 깨끗해진다. git stash list : 여러번 stash 한 경우 저장한 stash 목록을 확인할 수 있다. git ..

Develop/React.js

[React] overflow일 때 scroll bar 없애기(chrome 브라우저)

문제 프로젝트를 개발하는데 overflow 시에 저렇게 스크롤바가 보이는게 싫어서 해결하고 싶었다. 해결 - 크롬 브라우저를 사용 - styled components 를 사용 ::-webkit-scrollbar { display: none; } 위와 같이 속성을 추가해주었다. 스크롤바가 사라진 모습.

Develop/React.js

[React] Component 단축키로 쉽게 만들기

혼자 강의를 듣다가 강사님이 function을 만들때 단축키를 사용하셔서 금방금방 만드시길래 찾아봤다. 이렇게 rfce를 치고 엔터를 치면 이렇게 바로 파일이름이랑 똑같은 Component 틀을 만들어준다. (이런거 너무 좋아...😆) 방법 vscode에서 익스텐션을 하나 설치하면 사용할 수 있다. ES7 이라고 치면 저런 익스텐션을 찾을 수 있는데, 설치하면 단축어 사용가능하다.

Develop/React.js

[React] 서버와 클라이언트 서버 동시에 실행하기(feat. concurrently 라이브러리)

현재 서버 Node.js, 프론트 React.js 환경으로 프로젝트를 진행하는 강의를 듣고 있다. 서버랑 클라이언트를 원래는 따로 npm run을 해줘야하지만 concurrently 라는 라이브러리를 설치하면 동시에 실행시킬 수 있다고한다. 아는 게 많아지면... 손이 더 편하니까?! 한번 알아봤다. 설치 npm install concurrently --save 설치는 위와같이 터미널에서 해주고 루트 디렉토리에 있는 package.json에 scripts 부분을 보면 dev 부분이 있다. 저 부분을 아래처럼 작성해주면 원하는 명령어를 순차적으로 실행한다.

Develop/Database

[MongoDB] 몽고디비, 무료로 이용하자

결론부터 결론 : 몽고디비 클러스터는 아틀라스 프로젝트 당 하나씩 무료로 생성해서 이용가능. 하나 더 만들려고 하면 막힘. 왜 알게되었냐면... 리액트+노드로 프로젝트 만드는 강의를 들어보는 중인데, MongoDB를 이용한다고 한다고 하길래 새로운 클러스터를 생성하려고 했다. 클러스터를 생성할 때에 Shared로 설정하고 Cluster Tier 를 M0 으로 설정해주면 무료 클러스터를 만들 수 있다. 그런데 생성하려고 하니... 이미 무료 클러스터가 하나 있기 때문에 새로운 무료 클러스터를 생성할 수 없다고 떴다. 그래서 구글링해봤다. 결론은 시작할때 무료 shared tier를 이용할 수 있고, 대신 무료 클러스터는 Atlas 프로젝트 당 하나씩만 가능하다는 것이었다. 전에 노드 강의를 들었을 때 몽고..

Develop/React.js

[React] state 변경함수 사용할 때 주의점 : async

js 는 일반적인 코드를 작성하면 synchronous(동기방식) 하게 처리된다 -> 코드 작성한 윗줄부터 차례로 코드가 실행되는 것 하지만 어떤 함수들을 사용하면 asynchronous(비동기적) 하게 코드 실행이 가능하다. 예를 들어 ajax, 이벤트리스너, setTimeout 이런 함수들이다. 이런 함수들은 처리시간이 오래 걸린다. 그래서 ajax 요청하는 코드들은 순차적으로 실행되지 않고 다른 코드가 완료되면 실행된다. React 의 setState 함수 특징 리액트로 state를 만들때 function App(){ let [name, setName] = useState('kim') } 이런식으로 하는데, setName 이라는 state 변경함수들은 전부 asynchronous(비동기적) 으로 처..

Develop/Database

[MySQL] EC2에 MySQL 설치하고 MySQL Workbench 연결

ref: https://alkhwa-113.tistory.com/entry/AWS-EC2%EC%97%90-MySQL-%EC%84%A4%EC%B9%98%ED%95%98%EA%B3%A0-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%84%B1%ED%95%98%EA%B8%B0 AWS EC2에 MySQL 설치하고 개발환경 구성하기 1. MySQL 설치 $ sudo apt-get update $ sudo apt-get install mysql-server 2. MySQL 실행 $ /etc/init.d/mysqld start // MySQL 서버시작 $ ps -ef | grep mysql // 실행확인 $ sudo /usr/bin/mysql -u root -p // MyS..

Develop/React.js

[React] PWA 셋팅해서 앱으로 발행하기(모바일앱인척)

PWA 라는 걸 구글이 밀고 있다. Progressive Web App 이라는건데 웹사이트를 Android/iOS 모바일 앱처럼 사용할 수 있게 하는 웹개발 기술이다. 내가 만든 웹사이트를 모바일 앱으로 발행해서 쓸 수 있는 법을 알아보자 여기서 모바일 앱으로 발행한다는게, iOS/Android 앱으로 발행하는게 아니라 웹사이트자체를 스마트폰 홈화면에 설치하는 방식이다. PWA 의 장점 1. 스마트폰이나 태블릿의 홈화면(바탕화면)에 웹사이트를 설치할 수 있다. 앱을 누르면 상단 URL 바가 제거된 크롬 브라우저가 뜬다. 사실 웹이지만 유저가 봤을때는 그냥 앱같다. 2. 오프라인에서도 동작이 가능하다. service-worker.js 라는 파일과 브라우저의 Cache storage 덕분이다. (게임 만들 ..

Develop/Node.js

[Node.js] 이미지 업로드 & 이미지 서버 만들기

이미지 업로드 하는 방법에 대해서 배워보자 이미지 업로드 할 수 있는 페이지 만들기 upload.ejs 라는 파일명으로 view 를 하나 만들어줬다. enctype은 서버로 폼 전송하는 방식이다. enctype을 multipart/form-data 로 설정할 경우 인코딩하지 않고 그대로 전송한다는 의미이다. application/x-www-form-urlencoded 으로 설정하는 경우 base64라는 인코딩형식으로 인코딩되어서 전달됨. 일단 업로드 페이지는 위와같이 마련했다. upload페이지를 렌더링해주는 GET api를 만들어봤다. /upload 경로로 get 요청을 보내면 upload.ejs 를 렌더링 해줄거다. 업로드한 이미지를 하드에 저장 라이브러리를 하나 설치해준다. npm install m..

Develop/Node.js

[Node.js] router 폴더와 파일만들어 API관리

두 route 들을 다른 파일에서 관리하려고 한다. routes 라는 폴더를 만들고 shop.js 라는 파일을 만들어줬다. 아래와 같이 작성한다. 기존에 app 으로 사용했던걸 router 로만 바꾸어주면된다. module.exports 란? module.exports = 변수명; 이런식으로 쓰면 다른 곳에서 쓸 수 있게 저 변수를 내보내준다. 그리고 require('./파일경로'); 이런식으로 쓰면 다른 파일을 불러올 수 있다. 여기서 불러온 파일이 내보내는 변수가 있을 것이다. 그걸 가져다 쓸 수 있다. import 나 export 문법으로 대체 가능하다. 그러면 기존에 server.js 에 있던 route 대신에 아래와 같이 적어줄 수 있다 app.use() 는 미들웨어를 사용하고 싶을 때 쓰는 함..

Develop/Node.js

[Node.js] 작성자만 삭제가능하게하기

지금은 삭제버튼을 누구나 누를 수 있다. 하지만 회원가입기능이 있으니까 내가 썼던 글만 삭제가능하도록 해보자 /register 로 POST 요청이 들어오면 서버는 DB에 저장하면 될 듯하다. /register 경로로 POST 요청이 오면 login 이라는 collection 에 insertOne 함수로 데이터를 삽입한다. 콜백함수로 / (홈 경로)로 redirect 해서 돌아가도록 해줬다. 글 작성자만 삭제가 가능하도록 하기 일단 회원가입을 해서 계정을 하나 만들어준다. 지금을 글을 발행할 때에 글작성자가 따로 추가되지 않는다. 그래서 writer 라는 속성을 따로 만들어줬다. req.user._id 에는 현재 로그인한 유저의 정보가 들어있을 것이다. 따라서 writer 의 값을 이걸로 넣어줬다 post..

Develop/Database

[MySQL][오류] ER_NOT_SUPPORTED_AUTH_MODE

Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client 이런 오류가 떠서 해결하기위해 아래와 같은 명령어를 mysql에 접속해서 입력해준다. ALTER USER '[계정]'@'[호스트]' IDENTIFIED WITH mysql_native_password BY '[비밀번호]'; ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'mysql비밀번호'; 다시 노드를 실행해보면 오류없이 잘 작동한다.

Develop/Database

[MySQL] MySQL 기초

이번 프로젝트에서 mysql 을 쓰기로해서 한번 훑어보려고 포스팅! 개념 테이블을 그룹핑 한 것을 스키마(또는 데이터베이스라고도 함) 이라고 하고 이 스키마들을 합친 것을 데이터베이스 서버 라고 한다. 서버 접속 \connect --mysql root@localhost:3306 이렇게 mysql shell 에서도 가능하고 아니면 mysql workbench 실행해서 선택해서 접속이 가능한 것 같다. 스키마의 사용 스키마를 생성할 때에는 CREATE DATABASE 스키마이름; *이렇게 뜰 수 있는데 이건 JS 타입이어서 그렇다 \sql 명령어를 쳐줘서 sql 타입으로 변경시켜주면 된다. SHOW DATABASES; 를 입력했더니 현재 존재하는 데이터베이스들이 나온다. USE 스키마이름; SQL 과 테이블..

Develop/Node.js

[Node.js] 검색기능 만들기

검색 기능 일단 검색 창을 만들어주자. list.ejs 이 검색창에서 키워드를 입력하고 검색을 누르면 새로운 페이지에서 검색결과를 보여주도록 구현해보자 1. 검색 버튼을 누르면 서버에 POST 요청을 해야한다 2. 서버는 DB에서 데이터를 꺼내줘야한다. collection().findOne() collection().find().toArray() 등을 활용하면 되겠다. 그런데 GET 요청으로도 서버로 데이터를 전달 가능하다. GET 요청 시에 URL 뒤에 데이터를 심는 방법이다 URL query string query string 작성법은 다음과 같다. localhost:8080/list?데이터이름=데이터값 여러개를 입력한다면 데이터이름1=데이터값1&데이터이름2=데이터값2 이런 식이다. 이걸 query ..

Develop/Node.js

[Node.js] .env 파일에서 민감한 환경변수들 관리

실제로 서버를 배포할 때 필수라고 할 수 있는 .env 파일에 대해서 알아보자 server.js 를 작성했을 때 위와 같은 코드를 작성했었던 적이 있다. 이때 8080 이라는 포트번호를 사용했었고, mongodb+srv 라고 시작하는 db 접속 문자열이 있었다. 이런 값들은 개발환경이 달라지거나 다른 컴퓨터로 코드를 옮겨서 작업하면 수정이 필요할 수도 있다 이런 환경에 따라 가변적인 변수 데이터들을 보통 환경변수라고 한다. 개발자들은 환경변수를 보통 한곳에 모아서 관리하는데 .env 파일이다. 이곳에 중요한 환경변수들을 넣어두고 server.js에서 .env 파일에 있는 데이터를 쓰는 식이다. 중요한 정보들이 .env 파일에 있기 때문에 보안상으로 좋기도 하다. 방법 일단 환경변수 사용을 위한 라이브러리..

wonny_dev
'Develop' 카테고리의 글 목록 (3 Page)

...