📌 Loader(로더)란?
webpack은 기본적으로 Javascript, JSON 파일만 해석할 수 있다.
webpack이 로더를 사용하여 번들링 할 때에 다른 타입의 파일을 처리하거나 유효한 모듈로 변환하여 애플리케이션에서 사용할 수 있도록 도와준다.
계속 읽기webpack은 기본적으로 Javascript, JSON 파일만 해석할 수 있다.
webpack이 로더를 사용하여 번들링 할 때에 다른 타입의 파일을 처리하거나 유효한 모듈로 변환하여 애플리케이션에서 사용할 수 있도록 도와준다.
계속 읽기모듈로 관리하는 파일들을 번들링 해주는 툴이다.
Webpack 모듈 번들러를 명령어 환경에서 사용하기 위해 webpack, webpack-cli를 설치합니다.
1 | $npm i -D webpack webpack-cli |
package.json 파일에 webpack 번들링을 수행하는 bundle 명령을 등록합니다.
1 | { |
.browserslistrc
파일을 생성한다.1 | > 0.5% in KR |
1 | $npm run webpack:dev |
기본적인 구성으로도 번들링 훌륭하지만 복잡한 구성을 위해서 구성파일을 별도로 작성해 관리하는 것이 좋습니다.
1 | // webpack/common.js |
1 | // webpack/dev.js |
1 | // webpack/prod.js |
1 | // package.json |
이제 기본 webpack 구성이 아닌 직접 생성한 파일을 통해서 번들링 작업을 해줄 수 있다.
Webpack 전용 개발 서버를 구동하기위해 패키지를 설치한다.
1 | $npm i -D webpack-dev-server |
1 | // webpack/server.js |
개발 환경에서 서버 구성 파일을 불러온다.
1 | // webpack/dev.js |
1 | // package.json |
1 |
|
어느 연못에 엄마 말씀을 좀처럼 듣지 않는 청개구리가 살고 있었다. 청개구리는 엄마가 하는 말은 무엇이든 반대로 말하였다.
엄마 말씀 word가 매개변수로 주어질 때, 아래 청개구리 사전을 참고해 반대로 변환하여 return 하도록 solution 메서드를 완성하라.
A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Z | Y | X | W | V | U | T | S | R | Q | P | O | N | M | L | K | J | I | H | G | F | E | D | C | B | A |
word | result |
---|---|
“I love you” | “R olev blf” |
1 | function problem4(word) { |
배달이가 좋아하는 369게임을 하고자 한다. 놀이법은 1부터 숫자를 하나씩 대면서, 3, 6, 9가 들어가는 숫자는 숫자를 말하는 대신 3, 6, 9의 개수만큼 손뼉을 쳐야 한다.
숫자 number가 매개변수로 주어질 때, 1부터 number까지 손뼉을 몇 번 쳐야 하는지 횟수를 return 하도록 solution 메서드를 완성하라.
number | result |
---|---|
13 | 4 |
33 | 14 |
1 | function problem3(number) { |
parseInt()
메서드 대신 +number
를 사용하여 형변환을 시켰으면 어떨까하는 아쉬움이 남는다. 왜냐하면 parseInt()
메서드는 특정 진수법에 해당하는 정수로 반환하는 역할을 하기에 단순히 숫자로 형변환을 위함이 목적이라면 의미가 벗어난다고 생각했다. 마찬가지로 String()
메서드 대신 (i + ‘’)
로 형변환 시켜야겠다.리드미란, 다른 사람에게 나의 프로젝트가 얼마나 유용한지를 설명하기 위한 소개글이다.
위 두가지를 목적으로 작성하는 것이 바로 리드미이다.
기본만 잘 따라도 좋은 리드미처럼 보일 수 있다.
위 5가지가 github에서 언급하는 리드미 작성에 포함되어야 할 정보이다.
[x] 리드미 작성 기준에 맞게 리드미 작성하기
위 예시는 내가 과제 제출을 위해 처음에 적었던 리드미이다. 이 리드미를 좋은 리드미 작성법에 맞게 개선해보자.
이 프로젝트는 사용자가 다양한 상태의 업로드 버튼 UI가 필요할 때, 재사용 가능한 컴포넌트를 제공하는 프로젝트이다.
기본적인 사용법은 다음과 같습니다.
1 | <UploadButton type="idle">업로드</UploadButton> |
아래의 타입을 설정하면 다음과 같은 모양의 버튼 UI가 생성됩니다.
type | shape |
---|---|
idle | ![]() |
pending | ![]() |
resolved | ![]() |
rejected | ![]() |
disabled | ![]() |
만약 프로젝트에 대해 도움이 필요하시다면 아래 이메일로 연락을 주세요!
https://github.com/loco9939 |
---|
![]() |
https://github.com/loco9939/zero-base/tree/icon-upload-button/complete
리드미란 처음 내 프로젝트를 다른 사람에게 알리는 첫 게시물이므로 사람들이 내 프로젝트를 어떻게 하면 편리하게 사용할 수 있을지, 또 사용하고 싶도록 만들지를 생각하면서 작성해야하는 것을 알게되었다.
이것을 정말 쉽지 않다. 게다가 내 프로젝트에 대해서 정리하여 남에게 설명하는 연습이 잘 되어있지 않아서 낯설고 힘들었지만 아직은 처음이니깐 앞으로 프로젝트를 하게된다면 오늘 배운 점을 고려하면서 작성하도록 노력할 것이다.
알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.
첫째 줄에 알파벳 대소문자로 이루어진 단어가 주어진다. 주어지는 단어의 길이는 1,000,000을 넘지 않는다.
첫째 줄에 이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력한다. 단, 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다.
입력 | 출력 |
---|---|
Mississipi | ? |
zZa | Z |
z | Z |
baaa | A |
1 | const input = require("fs").readFileSync("/dev/stdin").toString().trim(); |
문자열을 풀 때, 정규표현식을 사용하면 반복문을 줄이고 코드를 깔끔하게 하여 가독성을 키우는 연습을 하는데 도움이 될 것 같다.
주어진 테스트 케이스를 다 만족했지만, 제출했을 때 오답이라고 나와서 당황했다. 어떻게 하면 내 제출이 만족 못시키는 케이스가 있을까하고 생각해보면서 여러가지 상황을 제시하면서 테스트 케이스를 찾아내었다.
그 결과 처음 정규표현식을 생성할 때, alphabets 배열을 순회하면서가 아닌 초기 입력값의 순회한 요소를 넣어주었기 때문에 제대로 된 결과가 나오지 않는다는 것을 깨닫고 수정하였다.
테스트 케이스를 어떻게 찾아내지라고 생각하면서 막막했었는데,
위 두가지를 실행해보다보니 찾게되어서 기뻤다.
JSX는 리액트 컴포넌트 사용을 HTML 처럼 사용하기 위해 생겨났다. JSX는 XML 처럼 생긴 문법 표현식이다.
1 | const name = "loco"; |
하지만 우리는 이렇게 편리한 JSX를 바로
하지만 이렇게 편리한데 사용하고 싶으니
Babel은 자바스크립트 컴파일러로 아래의 역할을 하여 브라우저 호환 문제를 해결한다.
babel을 사용하면 최신 문법으로 작성한 코드를 원하는 브라우저 환경에 잘 동작하도록 알아서 코드를 변환한 새로운 파일을 생성해준다.
또한, 애플리케이션이 방대해짐에 따라 한곳에서 파일을 관리하기가 어려워 모듈로써 파일을 구분하기 시작했다.
그렇게 파일을 구분을 하긴 했는데 그 많은 파일을 선후 관계를 따져가면서 HTML 파일에 등록시키고 최적화 하는 작업은
이러한 배경이 있기에
앞서 설명했듯이 webpack은 모듈 번들러이다. 웹 브라우저 환경은 CBD, Module 프로그래밍에 적합하지 않다.
왜냐하면 브라우저 호환성때문이다. 모던 브라우저가 모듈을 사용할 수 있긴 하지만
애플리케이션이 방대해짐에 따라 복잡성이 증가하여 코드가 혼란스러워지고 뒤섞이게 되어 개발이 어려워지는 문제가 발생하였다.
이를 해결하기 위해 코드 베이스를 모듈로 관리하고 번들링 해줘야한다.
애플리케이션에서 사용되지 않는 코드는 최적화 과정을 통해 제거되어 꼭 필요한 코드만 번들에 포함되도록 한다.
번들링으로 한곳에 묶기는 하였는데 이게 또 너무 크다보니
주석, 공백, 긴 함수명 등을 모두 축소 또는 제거하여 파일의 크기를 크게 줄일 수 있다. 이렇게 최적화된 코드는 사람이 읽기 힘들기에 디버깅하기가 어렵다.
이를 위해 코드를 추적하는
결과적으로 편리한 JSX를 사용하기 위해서는 babel이라는 컴파일러로 변환은 하여 브라우저가 읽을 수 있는 파일로 변환해주어야 하며, 브라우저는 애플리케이션을 build 해주는 환경을 기본 제공해주지 않고 수많은 모듈 파일들을 번들링해주는 도구로서 webpack을 사용한다.
수업을 하면서 개발을 하기 위한 Tool이 왜 이렇게나 많은지, 하나를 배우는 데에도 시간이 오래걸려 쉽게 접근하지 못한 부분이었다.
그동안 CRA(Create React App)이라는 명령어를 통해 리액트를 쉽게 사용할 수 있는데, 이는 기본적인 설정을 지원하고 프로젝트에 맞게 설정을 변경할 수가 없다. 그렇기 때문에 config 파일들의 설정이 필요하다는 것을 알게되었다.
앞으로 더 훌륭한 개발자가 되기 위해서는 기본 설정에만 의존하지 않고 내가 진행하려는 목적에 맞는 세팅을 알아둘 필요가 있어 열심히 배워보려고한다.
1 | const container = document.querySelector('root'); |
1 | const Button = props => { |
1 | const icons = { |
이 모든 코드가 한 파일에 있기에 이를 컴포넌트 단위와 역할별로 구분해주어야 한다.
1 | // ./main.js |
1 | // ./components/UploadButton.js |
1 | // ./components/Icon.js |
1 | import {createRoot, StrictMode} from './react.js'; |
위와 같이 import를 해오고 싶었지만
그러므로 ReactDOM, React로 객체처럼 사용해야만 했다.
간단한 업로드 버튼 컴포넌트를 구현하는 과제를 해보면서 리액트와 좀 더 친숙해지는 계기가 된 것 같다. figma 시안이 워낙 꼼꼼하게 잘 나와있어서 스타일링 하는데는 큰 어려움 없이 해서 좋았다.
처음 딱 시작하려는 순간부터 오류를 맞이해서 당황하였지만 문제도 잘 해결했고 SVG 파일에 애니메이션과 스타일을 입혀보는 것을 직접 해보니 더 기억에 오래 남을 것 같다.
암호문을 좋아하는 괴짜 개발자 브라운이 이번에는 중복 문자를 이용한 새로운 암호를 만들었다. 예를 들어 “browoanoommnaon”이라는 암호문은 다음과 같은 순서로 해독할 수 있다.
임의의 문자열 cryptogram이 매개변수로 주어질 때, 연속하는 중복 문자들을 삭제한 결과를 return 하도록 solution 메서드를 완성하라.
1 | function problem2(cryptogram) { |
하나 걸리는 부분은 제한사항을 에러처리를 해주어야 하나 고민을 하였다. 사용자가 제한사항에 벗어나는 입력을 할 수도 있으므로 이에 대한 에러를 발생시켜주는 것이 사용성에 더 옳다고 생각하여 if 조건문을 통해 에러처리를 해주었습니다.
에러처리에 대해서는 깊게 생각해보지 못했는데, 제한사항에 대해 한번 더 깊이 생각해보면서 에러처리의 필요성을 느낄 수 있었던 문제여서 즐거웠다.
또한 stack 자료구조를 생각하면서 문제를 해석하면 지금의 코드보다 훨씬 더 간결하고 가독성있는 코드를 구현할 수 있다는 것을 오늘 코드리뷰를 통해 깨닫게 되었다. stack으로 구현해보는 것은 다음 시간에 해보도록 하자.
화면에 렌더링되는 UI를 컴포넌트 단위로 쪼개 사용할 수 있는 Javascript 라이브러리리 혹은 프레임워크이다.
라이브러리인가? 프레임워크인가?는 크게 중요하지 않다. 우리가 중점적으로 생각해야할 부분은 리액트는
리액트는 점진적이므로 애플리케이션을 모두 리액트로 구성할 필요가 없다.
리액트는 Javascript 중점 라이브러리이다. 그러므로 자바스크립트를 잘하면 재밌을 것이다.
리액트는 별도의 설치가 필요없이 컴포넌트를 즉시 사용해볼 수 있다.
선언형 프로그래밍으로 명령형 프로그래밍보다 코드를 이해하기가 쉽다.
리액트를 배우면 웹, 리액트 네이티브를 배우면 모바일 등 한가지를 배워 확장성이 넓다.
1 | // CDN |
만약 버전을 변경하고 싶다면 @version을 써준다.
만약 IE를 고려 해야한다면 17 버전을 사용하고 그렇지 않다면 18 버전 사용하자.
1 | <script src="//unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script> |
💡 React v17의 render()와 v18의 createRoot() 차이
1 | // version 17 |
리액트 버전 18부터 render() 대신 createRoot()를 사용한다.
1 | createRoot(container[, options]) |
1 | // version 18 |
문서의 RealDOM 요소 노드인 container를 React Root로 만들어 반환하고, React Root를 render() 메서드를 사용하여 React 요소를 RealDOM에 렌더링한다.
1 | // Real |
RealDOM 요소 노드는 브라우저가 렌더링하면서 생성한 것이고 이와 달리 React 요소 노드는 Object(객체)로 그 형태가 다르게 생겼다.
위 사진을 보면 props라는 객체에 children, className, lang 등이 담겨있는 것을 알 수 있다. props에 대해서는 이후에 알아보자.
❗️ StrictMode 오류 해결
ECMAScript에서 ‘use strict’ 사용하여 문법적 오류를 미리 알려주었듯이 React에서도 이러한 오류를 미리 알려준다.
이에 대한 경고를 해결하기 위해서는 StrictMode 컴포넌트를 사용해야한다.
1 | React.createElement( |
사용법은 간단하다. 생성하려는 React 요소를 React.StrictMode의 자식 요소로 전달해주면 된다.
자바스크립트에서는 재사용을 위해 함수를 사용하고 리액트에서는 재사용을 위해 컴포넌트를 사용한다. 컴포넌트 생성 방법은 함수를 생성하듯이 생성할 수 있다.
1 | function SvgPath(props) { |
리액트 컴포넌트는 매개변수로 props를 받는다.
props 객체를 통해 다른 컴포넌트에게 본인의 HTML attributes, 자바스크립트 값(객체, 배열, 함수 등)을 전달해줄 수 있다.
함수선언식, 함수표현식 둘 다 가능하다.
하지만 createElement()를 사용하여 컴포넌트를 생성하는 것은 매우 번거로운 일이다. 그 대안으로 생겨난 것이 바로 JSX이다.
JSX는 리액트 컴포넌트 사용을 HTML 처럼 사용하기 위해 생겨났다. JSX는 XML 처럼 생긴 문법 표현식이다.
1 | const name = 'loco'; |
자동 세미콜론 삽입이 되는 것을 방지하기 위해 괄호로 감싸는 것을 추천한다.
선언형, HTML과 비슷한 구조, {}를 사용한 데이터 바인딩이 편리하다.
브라우저엔진에 의해 해석되지 못하므로 babel이 컴파일을 해줘야만 한다.
HTML 보단 JS에 가까우므로 camelCase 명명규칙을 따른다.
JSX는 렌더링하기 전에 이스케이프하므로 애플리케이션에서 명시적으로 작성되지 않는 내용은 script에 주입되지 않아 XSS 공격으로부터 안전하다.
❗️ React에서 babel 추가 설정
이전에 React를 사용하기 전에 설정해두었던 babel 사양에서는 React를 컴파일 해줄 수 없다.
컴포넌트를 모듈 파일로 구분할 때에 babel은 input으로 지정된 파일만 컴파일 해주고 input 파일에서 import한 파일까지 컴파일해주지 않는다.
위 2가지 문제 해결을 위해서는 플러그인을 설치 해줘야한다.
1 | npm i -D @babel/preset-react |
1 | // babel.config.js |
설치가 끝났다면 babel.config.js 파일에 해당 플러그인을 사용할 것이라고 등록을 해줘야 정상 동작한다.
옵션값이 있을 경우 []로 감싸서 넣어주고 그렇지 않은 경우 문자열로만 추가한다.
이제 JSX를 사용할 준비가 끝났으니 JSX를 사용하여 컴포넌트를 생성해보자.
1 | const HeadLine = () => ( |
리액트 수업을 듣고 배운것을 차근차근 익혀가면서 정리해보았다. props에 대한 개념도 확실히 잡히고, JSX를 왜 쓰게 되었는지, 안쓰면 무엇인 문제점이고 불편한지를 깨달을 수 있는 시간이여서 좋았다.
공식문서를 읽어볼 때도 영어로 된 것을 자동번역하여 읽지 않고 원문을 보면서 읽으니 시간이 조금 더디지만 그렇기 때문에 기억에 더 오래 남을 것이라고 생각하여 영어로 읽는 연습을 하고있다.
author.bio
author.job