전체 글 검색 결과

178개 발견
  1. 미리보기
    2020.07.02 - mr.november11

    [mysql] 로컬 내 docker 를 사용하여 mysql 실행 시 명령어

  2. 미리보기
    2020.05.26 - mr.november11

    GitHub Actions 에서 Only actions in <ID> are allowed for this repository 에러가 발생할 경우

  3. 미리보기
    2020.04.18 - mr.november11

    Test

  4. 미리보기
    2020.04.18 - mr.november11

    [React] 모바일에서 input 컴포넌트 클릭 시 자동으로 화면이 확대될 경우 해결 방법

  5. 미리보기
    2020.04.09 - mr.november11

    [React+Spring] 리액트, 스프링 부트로 웹소켓 구현하기

  6. 미리보기
    2020.04.07 - mr.november11

    [번역] 자바스크립트 예제로 배우는 함수형 프로그래밍

  7. 미리보기
    2020.04.06 - mr.november11

    [node.js] AWS SDK사용하여 S3 버킷에 업로드하기

  8. 미리보기
    2020.04.03 - mr.november11

    메이븐(maven) 빌드 시 "Source option 5 is no longer supperted." 에러가 발생할 경우 해결 방법

  9. 미리보기
    2020.03.31 - mr.november11

    [React] Github Pages로 리액트 프로젝트 무료 호스팅하기

  10. 미리보기
    2020.03.31 - mr.november11

    [git] VS Code 편집기를 git diff 툴로 활용하기

로컬 내 docker 를 사용하여 mysql 실행 시 명령어

 

docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=password -d mysql mysqld --default-authentication-plugin=mysql_native_password

다른 카테고리의 글 목록

리뷰/기타 카테고리의 포스트를 톺아봅니다

GitHub Actions 에서 Only actions in <ID> are allowed for this repository 에러가 발생할 경우 

Workflow 로그를 확인하면 다음과 같은 문구의 에러가 발생한다. 

Error 

Only actions in "novenber11th" are allowed for this repository 

 

이 경우 Setting -> Actions 메뉴에서 Actions permissions 가 Enable local and third party Actions for this repository 로 설정되어 있는지 확인한다. 에러가 발생할 당시에는 해당 값이 Enable local Actions only for this repository 로 설정되어 있었다.

(메뉴 설명상으로는 문제가 없어야 하는데 왜 그런지는 잘 모르겠다 ..)

 

다른 카테고리의 글 목록

리뷰/기타 카테고리의 포스트를 톺아봅니다

Test

2020. 4. 18. 01:14 - mr.november11

Test

 

다른 카테고리의 글 목록

리뷰/기타 카테고리의 포스트를 톺아봅니다

모바일에서 input 컴포넌트 클릭 시 자동으로 화면이 확대될 경우 해결 방법은 메타데이터 내 user-scalable=no 를 설정하면 된다.

 

CRA로 생성한 리액트 프로젝트 기준으로 다음과 같이 index.html 파일 내 viewport 메타 데이터 정보가 존재한다. 

 

<meta name="viewport" content="width=device-width, initial-scale=1 />

 

여기에 user-scalable=no 를 추가하면 간단하게 문제를 해결할 수 있다. 

 

 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />

다른 카테고리의 글 목록

React 카테고리의 포스트를 톺아봅니다

- Back-end : Spring Boot, WebSocket, SockJS, Gradle

- Front-end : ReactJS, react-stomp

 

1. Spring Boot 서버 구현 

1) Spring Boot -> Message -> WebSocket 로 Spring boot 프로젝트를 생성한다. 
   생성 후 프로젝트 내 spring-boot-starter-websocket 이 추가되었는지 확인해야 한다. 

 

'org.springframework.boot:spring-boot-starter-websocket'

 

2) WebSocketConfig 클래스 생성

- enableSimpleBroker : 메시지 브로커를 등록한 

- addEndpoint : 클라이언트가 접속할 웹 소켓의 주소, setAllowedOrigins("*")로 전체 CORS 를 허용하며 SockJS을 사용하도록 설정했다. 

 

@Controller
@Configurable
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/test").setAllowedOrigins("*").withSockJS();
    }

}

 

3) 웹소켓을 컨트롤할 TestController 클래스 생성 

- 웹소켓을 주고 받을 시 이벤트를 Trigger 하는 방법은 2가지가 있다. 

   먼저 client 소켓에서 sendMessage 함수로 메시지를 보낼 경우에는 @MessageMapping 어노테이션으로 받을 수 있다.
   두 번째로 @RequestMapping을 사용할 경우에는 웹 소켓이 연동된 Client와 무관하게 외부의 GET 질의로 이벤트를 Trigger 할 수 있다. 

 

- 메시지를 응답하는 방식도 2가지다. 

   첫 번째는 @SendTo 어노테이션을 사용하여 해당 topics를 수신하는 Client Websocket에 메시지를 전달할 수 있다.  
   이 경우 해당 함수는 리턴할 타입을 정의해야하며 반환값 리턴을 통해 Client에 메시지를 전달한다. 

   두 번째는 SimpMessagingTemplate를 사용하는 방식이다.  @SendTo 어노테이션을 사용하지 않고SimpMessagingTemplate로 응답값을 보낼 수 있으며, 이 경우 해당 함수의 리턴값은 void로 처리해야 한다.  SimpMessagingTemplate의 convertAndSend 함수를 사용하면 특정 유저에게만 메시지를 보낼 수 있다. 

 

@RestController
public class TestController {

    @Autowired
    private SimpMessagingTemplate webSocket;

    @MessageMapping("/sendTo")
    @SendTo("/topics/sendTo")
    public String SendToMessage() throws Exception {

        return "SendTo";
    }

    @MessageMapping("/Template")
    public void SendTemplateMessage() {
        webSocket.convertAndSend("/topics/template" , "Template");
    }

    @RequestMapping(value="/api")
    public void SendAPI() {
        webSocket.convertAndSend("/topics/api" , "API");
    }
}

 

2. React 코드 구현

1) 프로젝트 생성

 

npx create-react-app websocket_react

 

2) 관련 라이브러리 추가 

- sockjs-client, react-stomp 라이브러리 추가

 

yarn add sockjs-client react-stomp

 

3) 테스트 App 코드 작성

- react-stomp 라이브러리를 사용하여 웹소켓을 주고 받을 SockJsClient 컴포넌트를 생성한다.

  SockJsClient 생성 시 url은 WebSocket Config에서 Endpoint로 추가한 주소를 지정한다. 
  topics는 서버가 메시지를 보낼 시 수신할 토픽을 지정한다. 다중 지정할 수 있다.

  예제에서는 서버에서 3가지 방식으로 발신하는 모든 메시지를 수신한다. 

 

- SendTo, SendTemplate 버튼은 위 Controller에서 지정한 함수를 트리거하는 이벤트를 작성한다. 

   버튼 클릭 시 SockJsClient의 ref가 지정된 websocket에서 각 sendMessage 함수를 사용하여 서버에 메시지를 보낸다. 

- SockJsClient 관련 Docs : https://github.com/lahsivjar/react-stomp/blob/master/API.md

import React, {useRef} from 'react';

import SockJsClient from 'react-stomp';

function App () {
  const $websocket = useRef (null);

  const handleMsg = msg => {
    console.log (msg);
  };

  const handleClickSendTo = () => {
    $websocket.current.sendMessage ('/sendTo');
  };

  const handleClickSendTemplate = () => {
    $websocket.current.sendMessage ('/Template');
  };

  return (
    <div>

      <SockJsClient
        url="http://localhost:8080/start"
        topics={['/topics/sendTo', '/topics/template', '/topics/api']}
        onMessage={msg => {
          console.log (msg);
        }}
        ref={$websocket}
      />
      <button onClick={handleClickSendTo}>SendTo</button>
      <button onClick={handleClickSendTemplate}>SendTemplate</button>

    </div>
  );
}

export default App;

 

3. 실행 결과

- SendTo 버튼 클릭 시 

 

- SendTemplate 버튼 클릭 시

 

- 외부에서 http://localhost:8080/api 호출 시

다른 카테고리의 글 목록

Spring 카테고리의 포스트를 톺아봅니다

원문 : https://medium.com/@riteshkeswani/a-practical-introduction-to-functional-programming-javascript-ba5bee2369c2

Mary Rose Cook이 작성한 A practical introduction to functional programming을 기반으로 작성한 문서입니다. 원문의 파이썬 코드 대신 자바스크립트 코드 예제로 내용을 설명합니다.


함수형 프로그래밍은 사이드 이펙트(side effect)가 없다는 것이 특징입니다. 이는 함수 외부에 있는 데이터 의존하지 않으며, 함수 외부에 있는 데이터를 변경하지 않는 것을 의미합니다. ‘함수형'의 모든 것은 이러한 속성에서 파생된다는 점을 명심해야 합니다.

다음은 비 함수형 function의 예제입니다.

 

다음은 비 함수형 function의 예제입니다.

 

var a = 0;

function increment1() {
	return a += 1;
}
(역주 : increment1 함수가 외부 데이터 변수인 a 에 의존합니다.)

 

다음은 함수형 function의 예제입니다.

 

increment2(a) {
	return a + 1;
}

 

반복문 대신에 map과 reduce를 사용하십시오.

 

Map

 

map은 함수와 배열 원소를 사용합니다. 먼저 비어있는 배열을 새롭게 생성합니다. 원본 배열의 각 원소에 대해 함수를 실행하고 반환 값을 새로운 배열에 삽입합니다. 모든 과정이 끝나면 새로운 배열을 반환합니다.

아래의 비 함수형 코드는 이름의 배열을 임의로 할당된 코드명으로 변경합니다.

 

var names = [“Mary”, “Isla”, “Sam”];
var code_names = [“Mr. Pink”, “Mr. Orange”, “Mr. Blonde”];

for(var i in code_names) {
	var randomIndex = Math.floor(Math.random() * code_names.length); 
	var randomValue = code_names[randomIndex];
	names[i] = randomValue; 
}
(역주 : 실제 이름 리스트인 names를 반복문 수행 과정 내에서 직접 변경합니다.) 

console.log(names);
# => ["Mr. Blonde", "Mr. Pink", "Mr. Pink"]

 

위 코드를 for 반복문 대신 map 함수를 사용하면 다음과 같습니다.

 

var names = [“Mary”, “Isla”, “Sam”];
var code_names = [“Mr. Pink”, “Mr. Orange”, “Mr. Blonde”];

names = names.map(function(item) {
	var randomIndex = Math.floor(Math.random() * code_names.length); 
	var randomValue = code_names[randomIndex];
	return randomValue; 
});
(역주 : names에 대한 변경은 map 함수가 완료된 후 return 과정에서 이루어집니다.) 

console.log(names);
# => ["Mr. Orange", "Mr. Orange", "Mr. Blonde"]

 

Reduce

 

reduce 또한 함수와 배열 원소를 사용합니다. 각 원소를 조합하여 생성된 값을 반환합니다.

 

다음 예제는 ‘Sam’이라는 단어를 문자열 목록에서 찾아 카운트합니다.

 

var sentences = [
	‘Mary read a story to Sam and Isla’, 
	‘Isla cuddled Sam’, 
	‘Sam chortled’
];

var sam_count = 0;
for(var i in sentences) {
	var results = sentences[i].match(/Sam/g);
	if(results) {
		sam_count += results.length;
	}
}

console.log(sam_count);
# => 3

 

동일한 코드를 reduce로 작성하면 다음과 같습니다.

 

var sentences = [
	‘Mary read a story to Sam and Isla’, 
	‘Isla cuddled Sam’, 
	‘Sam chortled’
];

var sam_count = sentences.reduce(
	function(previousValue, currentValue) {
		var results = currentValue.match(/Sam/g);
		if(results) {
			previousValue += results.length;
		}
		return previousValue; 
	}, 
	0
);

console.log(sam_count);
# => 3

 

map과 reduce의 장점

 

  • 한 줄로 간단하게 처리할 수 있습니다.
  • map과 reduce에서는 반복에서 가장 중요한 부분인 배열, 연산, 반환 값이 항상 같은 위치에 있다.
  • 반복문의 코드는 이전에 선언된 변수에 영향을 미칠 수 있다. map과 reduce는 일반적으로 함수형으로 작동합니다.
    (역주 : map과 reduce는 함수형 프로그래밍 개념에 따라 기존 변수에 대한 사이드 이펙트가 없도록 구현하는 것이 원칙입니다.

  • map과 reduce는 원소 단위의 연산입니다. 반복문은 사람이 한 줄 단위로 로직을 읽고 이해해야 합니다. 반면에 map과 reduce는 복잡한 알고리즘과 원소의 추상적인 상태를 빠르게 이해할 수 있는 블록 단위의 코드를 제공합니다.

  • map과 reduce와 유사한 기능을 가진 다양한 함수(filter, all, any, find 등)가 있습니다.

명령형으로 작성하지 말고 선언형으로 작성하십시오.

아래 예제 프로그램은 세 대의 차량에서 레이스를 진행합니다. 각 단계에서 차량은 앞으로 이동하거나 정지합니다. 프로그램은 각 단계 별 차량의 위치를 출력합니다. 5단계가 진행된 후 레이스를 종료합니다.

 

레이스의 출력 결과는 다음과 같습니다.

 

-
--
--

--
--
---

---
--
---

----
---
----

----
----
-----

 

프로그램 코드는 다음과 같습니다.

 

var time = 5;
var car_positions = [1, 1, 1];

while(time > 0) { 
	time -= 1;
	console.log(‘’); 

	var carsCount = this.car_positions.length;
	for(var i=0; i<carsCount; i++) {
		if(Math.random() > 0.3) {
			this.car_positions[i] += 1;
		}

		var output_str = '- '.repeat(car_position);
		console.log(output_str);
	}
}

 

위 코드는 명령형으로 작성되었습니다. 함수형 프로그래밍은 선언형으로 코드를 작성합니다. 이는 어떻게 하는지에 대한 정의(how)가 아니라 무엇을 할 것인지 정의(what)합니다.

함수형 프로그램밍으로 구현하기

각 코드를 함수로 구현하여 프로그램을 선언형으로 작성할 수 있습니다.

 

function move_cars() {
	var carsCount = car_positions.length; 
	for(var i=0; i<carsCount; i++) {
		if(Math.random() > 0.3) {
			car_positions[i] += 1;
		}
	}
}

function draw_car(car_position) {
	var output_str = '- '.repeat(car_position);
	console.log(output_str);
}

function run_step_of_race() {
	this.time -= 1;
	move_cars(); 
}

function draw() {
	console.log(‘’);
	for(var i in car_positions) {
		draw_car(car_positions[i]);
	}
}

while(time > 0) {
	run_step_of_race();
	draw();
}

 

프로그램의 메인 루프는 다음과 같습니다.

 

“남은 시간이 있다면 레이스를 실행하고 출력합니다. 그리고 시간을 다시 확인합니다.” 각 레이스의 단계에 대해 더 자세히 알고 싶다면 구현된 함수를 읽으면 됩니다.

 

코드 자체가 내용을 설명하고 있기 때문에 주석을 추가하지 않아도 됩니다.

 

코드를 함수로 나누는 것은 코드를 더 읽기 쉽게 만들기 때문에 고민이 필요하지 않습니다.

 

위 코드는 함수를 사용하지만 외부 데이터(변수)에 의존적이기 때문에 함수형 프로그래밍의 조건을 만족하지 않습니다. 코드의 함수는 상태 값을 매개변수로 전달받아 사용하지 않습니다. 이러한 방식은 외부 변수의 변화에 의해 함수의 결괏값이 달라질 수 있습니다. 각 함수가 실제로 무엇을 하는지 확인하기 위해 정독이 필요합니다. 함수 내에서 외부 변수를 사용한다면 변수의 출처를 찾고 다른 함수에서 해당 변수를 변경하는지 확인해야 합니다.

 

상태 제거하기

 

자동차 레이스의 함수형 프로그래밍 버전은 다음과 같습니다.

 

function move_cars(car_positions) {
  return car_positions.map(function(item) {
    if(Math.random() > 0.3) {
      item += 1;
    }
    return item;
  });
}

function draw_car(car_position) {
  var output_str = ‘- ‘.repeat(car_position);
  console.log(output_str);
}

function run_step_of_race(state) {
  state[‘time’] -= 1;
  state[‘car_positions’] = move_cars(state[‘car_positions’]);
  return state; 
}

function draw(state) {
  console.log(‘’);
  state[‘car_positions’].map(function(item) {
    draw_car(item);
    return item;
  });
}

function race(state) {
  draw(state);
  if(state[‘time’] > 0) {
    state = run_step_of_race(state);
    race(state);
  }
}

race({
  ‘time’: 5,
  ‘car_positions’: [1, 1, 1] 
});

 

위 코드는 함수형 프로그래밍으로서 다음과 같은 특징을 갖습니다.

  • 공유 변수를 사용하지 않습니다. time과 car_positions는 race()로 전달됩니다.

  • 함수는 매개 변수를 사용합니다.

  • 함수 내에서 변수가 인스턴스화 되지 않습니다. 모든 데이터는 반환 값을 통해서 변경됩니다. race()는 run_step_of_race()의 결과와 함께 반복됩니다. 각 단계마다 새로운 상태가 생성되어 다음 단계로 전달됩니다.

파이프라인을 사용하십시오.

이전 섹션에서는 일부 명령형 반복문이 보조 함수를 호출하는 재귀 형태로 사용되었습니다. (역주 : race 함수 내에서 race를 다시 호출하는 재귀형 구조입니다.) 이번에는 파이프라인 기법을 활용하여 명령형 반복문을 다른 형태로 다시 작성해보겠습니다.

 

아래의 반복문은 밴드의 이름, 출신을 수정하는 역할을 수행합니다.
(역주 : 출신을 ‘Canada’로 수정하고 이름은 단어 단위로 제일 앞 문자를 대문자로 수정합니다.)

 

var bands = [
  {‘name’: ‘sunset rubdown’, ‘country’: ‘UK’, ‘active’: false},
  {‘name’: ‘women’, ‘country’: ‘Germany’, ‘active’: false},
  {‘name’: ‘a silver mt. zion’, ‘country’: ‘Spain’, ‘active’: true}
];

function format_bands(bands) {
  for (var i in bands) {
    bands[i][‘country’] = ‘Canada’;
    var name = bands[i][‘name’];
    name = name.replace(‘.’, ‘’);
    var nameParts = name.split(‘ ‘);
    for(var j in nameParts) { 
      nameParts[j] = nameParts[j].charAt(0).toUpperCase() +  nameParts[j].slice(1);
    }
    bands[i][‘name’] = nameParts.join(“ “);
  } 
}

format_bands(bands);

//print bands
console.log(JSON.stringify(bands));

 

위 코드 함수에서 ‘format’의 의미는 매우 애매모호합니다. 코드를 살펴보면 동일 반복문 안에서 세 가지 작업이 수행됩니다.

  • ‘country’ 키를 ‘Canada’로 설정합니다.
  • 구두점(.)을 밴드 이름에서 제거합니다.
  • 밴드 이름을 대문자로 변환합니다.

이는 코드가 의도한 바를 파악하기 어렵고 코드가 수행되는 상태를 파악하기 어렵습니다. 이러한 코드는 재사용하기 어렵고 테스트나 병렬 화도 어렵습니다.

다음과 비교해 보겠습니다.

 

pipeline_each(
  bands, 
  [set_canada_as_country, strip_punctuation_from_name, capitalize_names]
)

 

위 코드는 이해하기 더 쉽습니다. 각 기능이 서로 연관되어 있는 것처럼 보입니다. 이전 함수의 출력 결과는 다음 함수의 출력 결과로 입력됩니다. 각 함수가 함수형 프로그램의 특성을 갖고 있다면 재사용, 테스트, 병렬화가 용이합니다.

 

pipeline_each의 역할은 밴드를 set_canada_as_country()와 같은 변환 함수로 한 번에 하나씩 전달하는 것입니다. 함수가 모든 밴드에 적용된 후 pipeline_each는 변환된 밴드를 다음 함수로 전달합니다.

 

변환 함수를 살펴보겠습니다.

 

var set_canada_as_country = function set_canada_as_country(band) {
  band['country'] = "Canada";
  return band;
}

var strip_punctuation_from_name = function strip_punctuation_from_name(band) {
  band['name'] = band['name'].replace('.', '');
  return band;
}

var capitalize_names = function capitalize_names(band) {
  var nameParts = band['name'].split(‘ ‘);
  for(var j in nameParts) { 
    nameParts[j] = nameParts[j].charAt(0).toUpperCase() +  nameParts[j].slice(1);
  }
  band['name'] = nameParts.join(“ “);  
  return band;
}

 

pipeline_each 구현은 다음과 같습니다.

 

function pipeline_each(data, functions) {
  return functions.reduce(
    function(newData, currentFunction) {
      return newData.map(function(item) {
        return currentFunction.call(this, item);
      });
    }, 
    data
  ); 
}

bands = pipeline_each(
  bands, 
  [set_canada_as_country, strip_punctuation_from_name, capitalize_names]
);

console.log(JSON.stringify(bands));

Conclusion

함수형 프로그래밍은 ‘어떻게(how)’가 아니라 ‘무엇(what)’을 정의합니다. 이는 코드를 깔끔하게 추상화하여 나중에 쉽게 최적화할 수 있는 장점이 있습니다.

다른 카테고리의 글 목록

Javascript 카테고리의 포스트를 톺아봅니다
참고 사이트 : https://aws.amazon.com/ko/sdk-for-node-js/

예제 코드 

aws-sdk 라이브러리를 활용하여 파일 경로에 해당하는 파일을 s3 로 업로드한다. 

AceessKey 는 s3 upload 권한을 가져야 한다. 

const AWS = require('aws-sdk');
const fs = require('fs');
const path = require('path');

const accessKeyId = '<ACCESS_KEY>';
const secretAccessKey = '<SECRET_ACCESS_KEY>';
const region = 'ap-northeast-2';
const bucket = '<BUCKET_NAME>';
const s3 = new AWS.S3({accessKeyId, secretAccessKey, region});

const fileName = <FILE_NAME>;

const fileStream = fs.createReadStream(fileName);
fileStream.on('error', function(err) {
  console.log('File Error', err);
});

const uploadParams = {
  Bucket: bucket,
  Key: path.basename(fileName),
  Body: fileStream,
};

s3.upload(uploadParams, function(err, data) {
  if (err) {
    console.log('Error', err);
  }
  if (data) {
    console.log('Upload Success', data.Location);
  }
});

 

 

다른 카테고리의 글 목록

node.js 카테고리의 포스트를 톺아봅니다

현상

메이븐(maven) 빌드 시 "Source option 5 is no longer supperted." 에러가 발생할 경우

해결방법

프로젝트 내 pom.xml 파일에 다음과 같이 properties를 추가한다. 

 <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring.version>5.0.0.RC2</spring.version>
</properties>

sping.version은 원래 pom.xml에 있던 프로퍼티다.

maven.compiler.source, maven.compiler.target 만 추가하면 된다.  

다른 카테고리의 글 목록

Spring 카테고리의 포스트를 톺아봅니다
참고 사이트 : https://reactgo.com/deploy-react-app-github-pages/

리액트로 생성한 정적 웹페이지는 AWS의 S3, Heroku, Github Pages 등을 사용하여 무료 또는 저렴한 가격으로 호스팅할 수 있습니다.

Heroku의 경우에는 한국 Region을 지원하지 않기 때문에 접속 시 해외망을 경유하여 속도가 매우 느립니다. 

AWS S3의 경우에는 소액이지만 S3 공간에 대한 금액이 발생합니다. 

 

따라서 무료로 사용 가능한 Github Pages를 활용하여 리액트 프로젝트를 호스팅 해보겠습니다. 

Github Page는 Github에서 제공하는 웹 호스팅 서비스로 무료로 사용하기 위해서는 Gibhub 리포지터리를 공개형(Public)으로 설정해야 합니다. 보안상 소스 공개가 불가능한 프로젝트라면 AWS S3를 추천드립니다. 

 

이번 튜토리얼은 gh-pages라는 라이브러리를 활용하며 다음과 같이 진행합니다. 

 

1. CRA로 테스트용 리액트 프로젝트 생성

$ npx create-react-app github-pages-test
$ cd github-pages-test
$ code . (MacOS로 VS Code 사용 시)

 

2. Github repo 생성 (Github pages를 사용하기 위해서는 Public으로 repo를 생성해야 합니다.) 

3. 테스트용 프로젝트 Github 세팅

echo "# github-pages-test" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/november11th/github-pages-test.git
git push -u origin master

 

4. Github 프로젝트 repo 내 Settings로 이동 

    - GitHub Pages 메뉴에서 Source를 master branch로 지정하여 웹사이트 URL을 확인합니다.

       예제에서는 https://november11th.github.io/github-pages-test/ 입니다. 

5. 프로젝트 내 package.json 파일에 homepage 프로퍼티 설정

 

6. 프로젝트 내 gh-pages 모듈 설치 

yarn add gh-pages

 

7. 프로젝트 내 package.json 파일에 다음 predeploy, deploy 스크립트 명령어 추가

"scripts":{
 "predeploy": "react-scripts build",
 "deploy": "gh-pages -d build",
}

 

8. 프로젝트에서 yarn deploy 실행

$ yarn deploy                                                                                                            1 ↵
yarn run v1.21.1
$ react-scripts build
Creating an optimized production build...
Compiled successfully.

File sizes after gzip:

  39.4 KB  build/static/js/2.389e231c.chunk.js
  787 B    build/static/js/runtime-main.85847e19.js
  654 B    build/static/js/main.17df9291.chunk.js
  547 B    build/static/css/main.5f361e03.chunk.css

The project was built assuming it is hosted at /github-pages-test/.
You can control this with the homepage field in your package.json.

The build folder is ready to be deployed.

Find out more about deployment here:

  bit.ly/CRA-deploy

$ gh-pages -d build
Published
✨  Done in 15.57s.

yarn deploy가 문제 없이 실행 되었다면 Github repo 내 gh-pages 브랜치가 추가 생성되었습니다.

 

 

9. 다시 Github 프로젝트 repo 내 Settings로 이동하여 GitHub Pages 메뉴에서 Source를 변경합니다.
    이번에는 master가 아닌 방금 생성된 gh-pages 브랜치를 지정합니다. 

 

10. 이제 https://november11th.github.io/github-pages-test/로 접속하면 다음과 같이 CRA로 생성한 테스트 웹사이트가 화면상에 출력됩니다. 이후 코드가 변경될 시에는 yarn deploy로 변경사항을 바로 Gitub pages에 배포할 수 있습니다. 

다른 카테고리의 글 목록

React 카테고리의 포스트를 톺아봅니다

[git] VS Code 편집기를 git diff 툴로 활용하기

2020. 3. 31. 19:41 - mr.november11

1. ~/.gitconfig 파일 내 diff 관련 설정을 추가한다(또는 수정한다).

[diff]
    tool = vscode
[difftool "vscode"]
    cmd = code --wait --diff $LOCAL $REMOTE

2. git difftool <branch 이름> 명령어로 diff 를 실행한다. 

 

3. VS Code 왼쪽 상단 아이콘을 클릭하여 CHANGES 파일 리스트를 확인하고 변경된 소스 코드 내역을 비교한다. 

다른 카테고리의 글 목록

리뷰/기타 카테고리의 포스트를 톺아봅니다