기억의 실마리
2024. 1. 10. 23:01

React

Facebook에서 개발된 오픈소스 라이브러리이며

CSR 웹페이지를 개발할 때 주로 사용된다. 컴포넌트 단위로

개발할 수 있어 유지보수, UI 재사용성을 높여 효과적으로 웹페이지를

개발, 운영할 수 있다.

 

React의 주요 특징

1. Virtual DOM, 동적인 웹페이지 구성

React는 메모리에 Virtual DOM(가상돔)을 생성하고 이를 활용하여 이벤트가 발생할 때 마다 실제 DOM과 상태를 비교하여 변경이 필요한 최소한의 변경 사항만 실제 DOM에 반영하여 렌더링되기 때문에 렌더링 효율성이 좋다. 이러한 특징으로 유저와 상호작용하는 동적인 웹페이지 개발 시 자주 채택된다.

 

2. Data Flow

Data Flow(데이터 방향)는 한 방향으로 흐르는 단방향이다. 데이터흐름이 양방향인 경우 어플리케이션의 규모가 커질 수록 데이터의 흐름을 추적하기 힘들고 복잡해지는 경우가 발생한다. 이와 달리 단방향으로 개발된 어플리케이션은 데이터를 추적하기 수월하고 변화에 대한 예측이 가능하여 디버깅이 쉬운 장점이 있다.

 

3. JSX를 활용한 컴포넌트 개발

React를 사용할 때 필수적인 요소는 아니지만 보편적으로 필수적 요소처럼 사용되고 있다. 개인적인 견해로 JSX를 활용하였을 때 가장 큰 장점으로는 "개발의 생산성의 증대"라고 생각한다. JS코드내에서 즉시 UI구현 작업이 가능하고 가독성 또한 좋아지기 때문이다.

 

4. Props & State

Props는 부모 컴포넌트에서 자식 컴포넌트로 전달해 주는 데이터를 의미하며 readonly 타입의 데이터이다. props는 변경이 불가능한 불변데이터이고 props를 전달해 준 최상위 부모 컴포넌트에서만 props를 변경할 수 있다.

State는 컴포넌트 내부에서 선언하여 값을 변경할 수 있어 동적인 데이터를 다룰 때 주로 사용된다. 사용자와 상호작용을 통해 데이터를 동적으로 변경할 때 사용되며 각각의 state는 독립적인 데이터이다.

 

5. Hooks

React가 함수형 컴포넌트를 표준으로 제공하면서 생긴 개념으로, React state와 Life cycle을 연동할 수 있게 해주는 함수를 뜻한다. 대표적으로 useState, useEffect, useCallback, useMemo 등이 있다.

 

마치며...

지금 껏 개발에 대한 포스팅을 해오며 돌이켜 생각해보면 react훅을 제외하면 나의 주력인 react에 관한 포스팅이 단 하나도 없다는 것이 조금 놀라웠다. 기술에 대한 이론적 역량을 보완하기 위해 react의 개념을 복기하며 포스팅하였고 알고 있더라도 포스팅을 하고 안하고의 차이는 꽤 크니 앞으로 꾸준히 노력하며 포스팅해야겠다.

2024. 1. 1. 21:44

변수 값을 어떻게 서로 바꿀 수 있을까?

가장 단순한 방법으로 새로운 변수를 만들고 값을 복사해서 두 변수의 값을

서로 교환 할당하는 방식이 있을 것이다.

쉽게 떠올릴 수 있는 가장 확실한 방법이기도 하다.

 

  • 새로운 변수를 활용한 예제 코드
let data1 = "It's String";
let data2 = 10;

console.log(data1) // "It's String"
console.log(data2) // 10

let copyData1 = data1;
data1 = data2;
data2 = copyData1;

console.log(data1) // 10
console.log(data2) // "It's String"

 

이러한 올드한 방식 말고 또 하나의 값을 교환하는 현대적인 방법이 있다.

바로 구조 분해 할당을 활용하여 값을 교환하는 방법이다.

 

 

구조 분해 할당

ES6부터 사용 가능하며 배열을 변수로 분해할 수 있도록 하는

특별한 문법이다. 몇가지 예제코드를 통해 쉽게 이해할 수 있다.

 

  • 구조 분해 할당 예제 코드
// 기본적으로 활용하는 방식
let arr = ["Ze", "Riong"];
let [firstName, surname] = arr;

console.log(firstName); // Ze
console.log(surname);  // Riong

// 필요하지 않은 데이터는 , 를 사용해서 건너뛰기가 가능하다.
let array = ["A", "B", "C", "D", "E"];
let [a, , c, ,e] = array;

console.log(a) // "A"
console.log(c) // "C"
console.log(e) // "E"

// 할당 연산자 우측에 배열 뿐 아니라 모든 이터러블(반복 가능한 객체)이 올 수 있다.
let [a, b, c] = "all";
let [on, tw, th] = new Set([1, 2, 3]);

console.log(a, b, c) // a l l
console.log(on, tw, th) // 1 2 3

 

이렇게 구조 분해 할당에 대해 이해했다면 대충 감이 올 수도 있다.

아래 예제 코드를 통해 어떻게 변수 값을 교환할 수 있는지 알아보자.

 

 

구조 분해 할당을 활용한 변수 값 교환

변수는 이터러블 구조가 아닌데 어떻게 구조 분해 할당을 활용할까?

답은 간단하다. 변수를 배열에 넣어 이터러블하게 만들고 재할당하는 방식이다.

백문이 불여일견!

 

let str = "string";
let num = 230;

console.log(str) // "string";
console.log(num) // 230;

// 배열 내부에 변수를 넣어 이터러블 구조를 만들고 swap
[str, num] = [num, str];

console.log(str) // 230;
console.log(num) // "string";

 

 

마치며...

운이 좋게 서류합격을 하고 기술 면접을 보았는데 두 변수의 값을 서로 할당해주기 위한 방법을 서술해보라는 질문이 있었다. 나는 올드한 방식으로 새로운 변수를 선언하고 값을 할당하는 방식으로 설명하였고 면접이 끝나고 찾아보니 구조분해할당을 활용하는 트렌드한 방법이 존재했었다... 분명 당시의 질문 의도는 이러한 방식을 활용한 변수 값 교환에 대해서 설명하길 바랐을 것이다. 앞으로도 좀 더 다양한 방식에 대한 자료를 찾고 이해하기 위해 노력해야겠다.

2023. 12. 25. 15:04

API

Application Programming Interface의 약자로 응용 프로그램에서

운영체제나 프로그래밍 언어가 제공하는 기능을 제어 가능하도록

만든 인터페이스이며, 프로그램들이 서로 상호작용하는 것을

돕는 매개체라고 볼 수 있다.

 

REST

HTTP를 기반으로 필요한 자원에 접근하는 방식을 정의해둔

아키텍처이다. REST는 웹의 기존 기술과 HTTP 프로토콜을 그대로

활용하기 때문에 웹의 장점을 최대한 활용가능한 것이 특징이다.

 

REST의 속성

  1. 서버의 모든 자원은 클라이언트가 접근할 수 있는 고유 URI가 존재한다.
  2. 클라이언트가 요청할 때마다 필요한 정보를 보내주기 때문에 세션 정보를
    보관할 필요가 없어 서비스의 자유도가 높아지고 유연한 아키텍처 적용이 가능하다.
  3. HTTP 메서드를 사용한다.(GET, POST, PUT, DELETE 등)
  4. 서비스 내의 자원은 연관된 자원들과 연결되어 표현되어야한다.

REST는 HTTP메서드를 통해 자원을 처리하도록 설계된 아키텍처이다.

 

 

REST의 구성 요소

자원(Resource)

모든 자원은 서버에 존재하며 고유 ID를 가지고 있으며,

자원의 위치를 식별하는 URI(Uniform Resource Identifier)를 통해

자원에 접근할 수 있다.

 

메서드(Method)

  • GET: 리소스를 조회
  • POST: 리소스를 생성
  • PUT: 리소스를 전체 수정
  • PATCH: 리소스를 일부 수정
  • DELETE: 리소스를 삭제

 

메시지(Message)

HTTP header, body, 응답 상태 코드 등으로 구성되어 있다.

  • header: body에 어떤 형식으로 데이터가 담겼는지 표시
  • body: 자원에 대한 정보를 JSON, XML 등으로 전달

응답 상태 코드는 200 ~ 500 사이의 숫자로 클라이언트의

요청에 대한 상태를 나타낸다.

 

 

REST의 특징

1. Server-Client 구조

클라이언트는 자원을 요청하고 서버는 자원을 가지고 있으며

API를 제공하여 비즈니스 로직처리 및 저장을 책임진다.

 

2. Stateless(무상태)

HTTP는 무상태이며 REST는 HTTP를 기본으로 하기 때문에 무상태이다.

클라이언트의 상태(State)를 서버에 저장하지 않는 것을 무상태라고 표현하고

서버에서 클라이언트의 요청을 완전히 별개의 것으로 인식하고 처리한다.

따라서 이전의 요청이 다음의 요청에 연관되지 않고 처리 방식에 일관성을

부여하고 부담이 줄어든다.

 

3. Cacheable(캐시 처리 가능)
HTTP의 캐싱 기능을 적용할 수 있어 대량의 요청을 효율적으로 처리할 수 있다.

캐시를 활용하여 응답 시간이 빨라지고 성능, 서버의 자원 이용률을 향상할 수 있다.
 
4. Layered System(계층화)
클라이언트는 REST API 서버만 호출하며 REST 서버는 다중 계층 구성이 가능하다.

API 서버는 순수 비즈니스 로직을 수행하고 이의 앞단에서 보안, 로드 밸런싱, 암호화,

사용자 인증 등을 활용해 구조에 유연성을 줄 수 있다.
 
5. Code-On-Demand
서버로부터 스크립트를 받아서 클라이언트에서 실행한다.

(필수 요건 아님)
 
6. Uniform Interface(인터페이스 일관성)
URI를 통해 자원 조작을 통일되고 한정적인 인터페이스로 수행한다.

HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하며 특정

언어나 기술에 종속되지 않는다.

 

 

REST API의 장단점

장점

  1. 독립적인 언어와 플랫폼
  2. REST API 메시지를 통해 의도를 쉽게 파악 가능
  3. REST가 지원하는 프레임워크나 언어 등 없이 구현 가능
  4. HTTP로 기존 웹 인프라를 사용 가능
  5. 서버와 클라이언트의 역할을 명확하게 분리
  6. 다양한 서비스 디자인에서 생길 수 있는 문제 최소화

단점

  1. 표준이 존재하지 않음(보안, 정책 등)
  2. HTTP프로토콜만 사용 가능

 

 

마치며...

얼마 전 회사에 서류합격을 통지받고 면접을 볼 수 있는 기회가 있었다. 지금껏 개발을 해왔지만 정작 이론에 대한 부분은 약하다는 것을 느끼게 되었고 면접결과 역시 좋지 못했다. 한번에 잘 되리라 생각하진 않았지만 생각했던 것 보다 모르는 이론이 너무나도 많았던 것 같다... 기술면접에서 REST API의 특징을 말하는 부분에서 시원하게 답변하지 못했고 이 포스팅을 시작으로 이론공부도 꾸준히 해야겠다!

2023. 12. 3. 11:55

Caret Browsing (Cursor Browsing)

웹페이지에서 텍스트 페이지를 볼 때 input에 focus된 것 처럼 커서를

보여주는 기능이다. 텍스트 페이지에서 클릭한 위치에 커서가 보여지며

키보드 컨트롤을 통해 드래그가 가능해지기도 한다.

 

 

캐럿 브라우징 모드

F7을 누르면 캐럿 브라우징사용 여부를 묻기 위한 confirm창이 뜬다.

사용을 누르면 캐럿브라우징 모드가 되며 다시 F7을 누르면 해제된다.

 

 

언제쓰면 좋을까?

개인적으로 장문의 글을 읽을 때 사용하면 좋겠다고 생각했다.

커서를 통해 읽던 위치를 파악할 수 있고 키보드를 사용하여 좀 더

정밀하게 드래그하여 텍스트를 복사할 수도 있기 때문이다.

 

 

 

마치며...

캐럿브라우징을 포스팅하게 된 이유는 개발을 하는 과정에서 live-server로 띄운 웹페이지의 텍스트영역에 지속적으로 커서가 생기는 현상에 당황스러웠고 처음에는 코드의 문제로 버그가 발생하는 줄 알고 몇분간 삽질을 한 경험이있었다. 이 후 키보드가 잘못 눌렸을 때 문제가 발생했고 해당 브라우저에서 띄운 모든 페이지가 커서를 띄우는 것을 확인 후 캐럿 브라우징에 대해 알게되었다... 혹시 캐럿브라우징 기능이 필요할 수도 있고 같은 실수를 했을 때 당황하지 않고 대처하기 위해 포스팅했고 앞으로도 경험해야 할 문제들도 발단부터 검증하면 분명 해결할 수 있을 것이라는 믿음이 더 강해졌다.

2023. 11. 21. 00:31

Webpack

webpack은 Node.js 런타임 기반의 웹어플리케이션을 구성하는 자원을 모듈

단위로 번들링 해주는 도구이다. 프론트엔드 개발 트렌드로 자주 사용되는

라이브러리, 프레임워크(React, Vue 등)는 프로젝트 파일의 크기가 큰 경우

대다수이기 때문에 webpack을 통하여 파일들간의 의존성 관계를 정리하고

코드를 최적화하여 하나의 스크립트 파일로 만들어 주로 최적화된 서비스를

제공하기 위해 사용된다.

 

Webpack의 장점

  • 코드를 축소하여 최적화하고 사용하지 않는 코드를 제거하여 빌드하는 방식으로 성능을 최적화할 수 있다.
  • CSS가 아닌 SASS 혹은 stylus, Typescript 사용 시 컴파일 과정에서 필요 플러그인을 추가하고 번들러를 실행해준다.
  • 종속성 문제의 해결

 

Webpack의 단점

  • 일부 패키지들을 loader를 통해 매번 추가해주어야 하며 추가하고자 하는 자원의 타입에 따라 추가해 주어야 하는 loader가 다를 수 있기 때문에 러닝커브가 다소 있는 편이다.

 

Install

# 웹팩, 개발자 서버 인스톨
npm i -D webpack webpack-dev-server

# 필요한 플러그인 및 로더 설치 (css, sass, static copy plugin, env 등)
npm i -D html-webpack-plugin dotenv-webpack css-loader copy-webpack-plugin cross-env source-map-loader sass-loader clean-webpack-plugin

웹팩(개발자 서버 포함)과 필요한 로더와 플러그인을 설치한다.

 

webpack.config.js 분리

html / css / vanillaJS 구성으로 웹팩 적용하였으며 config 작성할 때 common, dev, prod로

나누어 빌드환경에 맞춰 별도로 관리해주었다.

 

webpack.common.js

공통으로 적용 될 config를 작성한다.

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const DotEnv = require('dotenv-webpack');

module.exports = {
	entry: {
		main: path.resolve(__dirname, '../src/script.js'),
	},
	output: {
		path: path.resolve(__dirname, '../public'),
		filename: '[name].min.js'
	},
	// target: ['web', 'es5'], // es5 환경 작업 시 사용
	module: {
		rules: [
			{
				test: /\.js$/,
				loader: 'babel-loader',
				exclude: /node_modules/
			},
			{
				test: /\.js$/,
				enforce: 'pre',
				use: ['source-map-loader'],
			},
			{
				test: /\.s?css$/,
				use: [
					'style-loader',
					'css-loader',
					'sass-loader'
				]
			},
			{
				test: /\.(glb|gltf)$/,
				use: ['file-loader']
			},
		]
	},
	plugins: [
		new HtmlWebpackPlugin({
			template: path.resolve(__dirname, '../src/index.html'),
			filename: 'index.html',
			minify: true,
		}),
		// origin 그대로 복사할 파일을 지정
		new CopyWebpackPlugin({
			// 빌드 시 public 폴더에 자동 생성(patterns 경로에 해당 파일이 없으면 에러발생)
			patterns: [
				{ from: path.resolve(__dirname, '../static') },
				{ from: path.resolve(__dirname, '../src/style.css') },
			]
		}),
		// dotenv-webpack패키지를 통한 환경변수(env) 사용
		new DotEnv({ path: '.env' }),
	]
};

 

 

webpack.dev.js

webpack.common.js에 추가적으로 개발자 서버에서만 적용될 config를 작성한다.

const path = require('path')
const { merge } = require('webpack-merge')
const commonConfiguration = require('./webpack.common.js')

module.exports = merge(
    commonConfiguration,
    {
        mode: 'development',
        devServer: {
            liveReload: true,
            static: {
                directory: path.resolve(__dirname, '../public')
            },
            // hot: true,
            watchFiles: ['src/**/*'],
            port: 3000,
        },
    }
)

 

webpack.prod.js

webpack.common.js에 추가적으로 빌드 시 적용될 config를 작성한다.

const { merge } = require('webpack-merge')
const commonConfiguration = require('./webpack.common.js')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');

module.exports = merge(
    commonConfiguration,
    {
        mode: 'production',
        module: {
            rules: [
                {
                    test: /\.(js|jsx)$/,
                    exclude: /node_modules/,
                    use: ['babel-loader']
                },
                {
                    test: /\.s?css$/,
                    use: [MiniCssExtractPlugin.loader, 'style-loader', 'css-loader', 'sass-loader']
                }
            ]
        },
        optimization: {
            minimizer: [
                new TerserPlugin({
                    terserOptions: {
                        compress: {
                            // 빌드 시 콘솔로그 drop
                            drop_console: true
                        }
                    }
                })
            ],
            splitChunks: { chunks: 'all' }
        },
        plugins: [
            new CleanWebpackPlugin(),
            new MiniCssExtractPlugin(),
            // build 과정에서 환경변수 사용 가능하도록 설정
            new webpack.DefinePlugin({
                'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), // 환경변수 접근 필수 지정!
                'process.env.FIREBASE_API_KEY': JSON.stringify(process.env.FIREBASE_API_KEY),
                'process.env.FIREBASE_AUTH_DOMAIN': JSON.stringify(process.env.FIREBASE_AUTH_DOMAIN),
                'process.env.FIREBASE_PROJECT_ID': JSON.stringify(process.env.FIREBASE_PROJECT_ID),
                'process.env.FIREBASE_SENDER_ID': JSON.stringify(process.env.FIREBASE_SENDER_ID),
                'process.env.FIREBASE_APP_ID': JSON.stringify(process.env.FIREBASE_APP_ID),
                'process.env.FIREBASE_MEASUREMENT_ID': JSON.stringify(process.env.FIREBASE_MEASUREMENT_ID),
            })
        ]
    }
)

 

package.json

scripts를 수정하여 webpack을 적용한다.

{
  
  "scripts": {
    "start": "webpack serve --open --config ./bundler/webpack.dev.js",
    "build": "webpack --config ./bundler/webpack.prod.js"
  },
 
}

 

 

마치며...

주로 react를 create-react-app을 통해 보일러플레이트를 설치하여 개발을 진행하였고 webpack은 create-react-app을 통해 함께 설치되며 최적화에 도움을 준다는 기본적인 개념만 알고있었다.

 

이렇게 웹팩을 직접 프로젝트에 도입하며 경험해보니 그 동안 create-react-app을 통해 react 보일러플레이트를 설치하고 이미 구성되어있는 편리한 환경속에서 webpack을 사용하고 있었다는 것을 깨달았다.

 

생각했던 것 보다 높은 자유도 때문인지 러닝커브를 느꼈던 것 같고 특히나 환경변수를 적용하는 것이 가장 어려웠다...

 

항상 그렇듯 알고나면 별거 아니지만 그 과정은 험난했고, 이 후에 문제를 극복하며 따라오는 만족감은 이로 말할 수 없는 것 같다. 아직도 갈 길이 멀었음을 깨달았고 다시 한 번 더 열심히 정진해야겠다는 다짐을 굳히는 시간들이었다.

2023. 11. 8. 00:07

1. Three.js

WebGL엔진을 기반으로 브라우저에서 3D 그래픽 구현

보다 쉽고 직관적으로 생성, 관리할 수 있도록 제공해주는

라이브러리 이다. 기본적인 WebGL은 점, 선, 삼각형을 그리는

단순한 시스템을 가지고 있으며 Three.js를 사용하지 않아도

모든 그래픽 구현이 가능하지만 코드의 복잡도는 비교 조차

안될만큼 복잡해지고 관리 또한 난이도가 올라가기 때문

아직 시도할 엄두가 나지 않지만 추 후 시간을 내어 다뤄봐도

좋은 경험이 될 것 같다.

 

2. Three.js 구조

 

Renderer

Scene, Camera 객체 데이터를 전달 받아 화면 내부 3D Scene의

일부 객체들을 2차원 평면 이미지로 렌더링해주는 핵심기능을 수행한다.

 

 

Scene

다수의 Mesh, Light, Group, Object3D, Camera로 이루어진 트리 구조이다.

배경색, 안개, 다수의 오브젝트, 빛, 질감 등을 표현하는 화면이다.

Scene은 최상위 노드이기 때문에 객체의 위치와 방향이 부모(Scene)기준이다.

 

 

Camera

Camera는 다른 구성 객체와는 달리 Scene 그래프에 포함되지 않으며

Scene객체를 촬영하여 어떻게 보여줄 것인가를 결정하는 역할을 한다.

 

 

Light

여러 종류의 광원을 말하며 이는 즉 조명을 뜻한다.

AmbientLight, SpotLight, DirectionalLight 등 다양한 광원을 활용하여

Scene에 존재하는 다양한 3D요소들을 3D 공간 공간에서 볼 수 있다.

 

 

Geometry

3D요소의 모양을 정의할 수 있으며 내장객체 또는 파일을 통해 형상을 만들 수 있다.

 

 

Material

질감을 뜻하며 표면의 색상, 투명도, 질감을 나타낼 수 있다.

 

 

Mesh(Object3D)

Mesh는 특정 Material의 속성을 가진 Geometry를 그리는 객체이다.

Mesh는 3D공간 상의 위치와 특정 기준 축 회전 등을 결정할 수 있으며

Material과 Geometry는 재사용이 가능하여 여러 Mesh가 특정

Material, Geometry를 동시 참조 가능한 특징이 있다.

 

 

마치며...

오늘은 Three.js의 기본 구성과 개념에 대한 포스팅만을 진행했지만 현재 Three.js를 사용한 프로젝트가 완성에 가까워졌고 완성된 이후에 Three.js에 대한 추가 포스팅을 진행할 예정이다. 언제나 개발을 통해 기능을 구현하는 것도 중요하지만 가장 중요한 것은 사용한 기술에 대한 개념, 원리를 명확히 이해하고 있는 것이라 생각하고 있고 나에게는 하나의 원칙이기도 하다. 앞으로도 근거 있는 기술의 사용과 검증 가능한 코드를 지속하기 위해 더 나은 노력할 것이다.

2023. 10. 29. 12:16

개발자가 되기위한 여정이 어느덧 1년 6개월이 되어간다.

개발을 처음으로 경험하고, 적성을 알게되어 시작하였고 직장을 다니며 약 8개월 공부를 하고

더 많은 시간을 투자하여 개발에 집중하고 싶어 3년간 종사했던 청원경찰을 그만두고

남은 퇴직금으로 어떻게든 버티며 개발자가 되기 위해 계속해서 달려온 것 같다.

 

시작은 너무나도 어렵고 작은 문제를 해결하기 위해 많은 시간을 쏟게 되었지만

시간이 흐를수록 사고하는 방식이 달라지고 스스로가 얼마나 부족한 사람이었는지

깨닫는 시간의 연속이었다.

 

개발은 나를 돌아보게 하였고 생각하는 폭을 넓혀주었으며 다른 방향의 시야를 밝혀주었다.

말 그대로 인생이 바뀌었다고 생각이 든다.

 

꾸준하게 개발을 학습하고 결과물을 만들어내는 것은 나에게 있어 기쁘고 가치있는 일이 되었다.

어느새 퇴직금은 바닥이 보이니 마음이 조급해졌고 개발에 몰두하게 된 것 같다.

 

깃허브의 잔디는 꾸준히 심을 수 있게 되었지만 블로그에 소홀해져버렸다.

그리고 잔디라는 것이 깃허브의 커밋내역을 하루 단위로 지정되어 녹색으로 표기되는 증명가능한

활동내역이라는 것을 4주 전에 알게되어 특정 분기마다 잊지않고 커밋하고 있다.

좀 더 일찍 알았다면... 분명 녹색으로 가득 차 있었을텐데 좀 아쉽다는 생각이 들었다.

 

아직 포스팅되지 않고 GoogleKeep에 메모되어있기만 한 기록들이 너무너무 많다.

분명 내가 사용하고 내가 기록하는 것은 좋지만 개발자로서 진로를 희망한다면 기업에게

내가 무엇을 했는지 보여 줄 수 있는 결과물을 내어야한다는 것은 너무 당연했다.

나의 기록을 보여주기 위해서 구글계정을 공유할 순 없으니...

 

다시 한번 증명할 수 있는 결과만들자는 결심이 생겼고 좀 더 마음의 여유를 갖고자

Daily카테고리를 만들게 되었다.

 

개발을 진행하며 구직활동을 시작한 것은 2개월이 되었지만 약 70개의 기업에게서

긍정적인 연락은 받지 못했다.

 

그래도 언제나 그래왔듯이 나는 하려는 일을 할 것이고 더욱 본질에 다가가기 위해 노력하며

중꺾마(중요한 건 꺾이지 않는 마음!!)의 의지를 스스로 꺾지 않을 것이다!

 

개발 근황은 객체 지향 패턴을 활용하여 three.js를 사용해서 포트폴리오를 새로 만들고있다.

학습에 어려움이 있었지만 관심이 많았던 기술이라 즐겁게 배우며 만들고 있다.

 

그리고 이 글을 보는 취준생분들께 같이 힘내자고, 화이팅하자고 말씀 전해드리고 싶습니다.

연속되는 실패에도 좌절하지 않고 나의 길을 꾸준히 다지며 성장하는 것은 절대로

허무한 일이 아니라고 믿습니다. 아직 빛을 발하지 못했을 뿐이고 빛을 내기위한 여정이라고

생각하기 때문입니다. 그리고 그 끝에는 분명 우리가 바라던 모습에 가장 가까운 모습을 한

나 자신이 기다리고 있다고 생각합니다.

 

모두 화이팅입니다!

 

 

Github: https://github.com/zeriong

2023. 7. 10. 11:40

Vercel

버셀은 Next.js 개발팀이 만든 호스팅사이트이다.

데이터를 저장할 필요가 없으며 별도의 절차 없이 호스팅을 해준다.

 

배포하기

vercel에서 배포하는 것은 어렵지 않고 아주 쉬운편에 속한다.

가장 먼저 깃허브 레포지토리에 프로젝트를 만들었다고 가정하고

편의를 위해서 vercel에 github계정으로 회원가입을 한다.

 

  1. 로그인진행 후 Add New...을 눌러 프로젝트를 생성한다.
  2. Import Git Repository에서 git계정을 연결하여 저장소의 프로젝트들을 가져온다.
  3. Import를 눌러 deploy(publishing)를 진행한다.

 

위와 같이 프로젝트 이름을 설정하고 프레임워크를 동일하게 설정해준다.

 

유의사항

프로젝트를 진행할때 특정 API-key를 사용해서 통신을 해야하는 경우가 아주 많다.

그러한 API-key는 분명 유출시 위험성이 있기 때문에 .env파일에 환경변수로 사용했을 것이고

Github에도 업로드 되지 않게 했을 것이다. vercel에서 파일을 배포할때 Github의 레포지토리를

기준으로 배포하기 때문에 vercel은 환경변수를 알 수 있는 방법이 없다. 그렇기 때문에 반드시

Environment Variables 텝을 눌러 개발환경과 동일한 변수명과 동일한 API-key를 넣어주어야 한다.

만약 API-key와 같은 환경변수의 값이 입력되지 않는다면 배포가 성공해도 status 500 에러가 발생한다.

 

환경변수를 모두 Add를 눌러 추가하고 마지막으로 Deploy를 눌러주면 배포가 완료된다.

 

 

마치며...

유의사항이라고 큼직하게 환경변수 적용에 대해 적어 두었지만 사실 너무나 당연한 것이다. 나는 환경변수에 대해서 떠올리지 못했고 500에러를 마주하며 좌절했었다. 너무 당연하게 개발환경에서 많은 시간을 투자해서 개발을 하다보니 익숙하지 않은 환경에서 무언가를 시도한다는 것은 그런 당연한 것을 쉽게 망각하기도 하는 것 같다. 역시 경험은 성장에서 빼놓을 수 없는 중요한 요소인 것을 다시금 깨닫는 시간이었다.