API์˜ ๊ฒ€์ฆ ๋ฐ ๋ผ์šฐํŒ…์„ ์ž๋™ํ™”!

 

ํ˜„์žฌ Express.js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ REST API๋ฅผ ๊ตฌ์ถ• ์ค‘์ž…๋‹ˆ๋‹ค.

๋‚˜์ค‘์— ํŒ€์›์ด ํ•ฉ๋ฅ˜ํ•˜๊ฑฐ๋‚˜, ๋ฐ”์œ ์ผ์ • ํ›„์— ๋‹ค์‹œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ด์•ผ ํ•  ๋•Œ๋ฅผ ๋Œ€๋น„ํ•ด ๋ฌธ์„œํ™”๋ฅผ ํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค.

 

์‹œ๊ฐ„์˜ ์ œ์•ฝ ๋•Œ๋ฌธ์— Swagger์™€ OpenAPI Specification์„ ์‚ฌ์šฉํ•ด Design First ๋ฐฉ์‹์œผ๋กœ ๊ทœ๊ฒฉ์„ ์ •์˜ํ•˜๊ณ ,

์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

API์˜ ๊ฒ€์ฆ ๋ฐ ๋ผ์šฐํŒ…์„ ์ž๋™ํ™”ํ•˜๊ธฐ ์œ„ํ•ด express-openapi-validator ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ, ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์–ด์š” ๐Ÿง

JWT๋ฅผ http-only cookie๋กœ ์ „๋‹ฌํ•˜๋ ค๋Š”๋ฐ, Authorization ํ—ค๋”์™€ CSRF ํ† ํฐ ๊ด€๋ จ ๊ฒ€์ฆ์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค!!!

 

๋ฌธ์ œ ์ƒํ™ฉ

  1. CSRF ํ† ํฐ์ด ์žˆ๊ณ  Authorization ํ—ค๋”๊ฐ€ ์—†์„ ๋•Œ
    • Authorization ํ—ค๋” ํ•„์ˆ˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ
    • ์ด๋•Œ JWT ํ† ํฐ์€ ์ฟ ํ‚ค๋กœ ์ „์†ก
  2. CSRF ํ† ํฐ๊ณผ Authorization ํ—ค๋” ๋ชจ๋‘ ์—†์„ ๋•Œ
    • Authorization ํ—ค๋” ํ•„์ˆ˜๋ผ๋Š” ์—๋Ÿฌ ๋ฐœ์ƒ
    • ์ด๋•Œ๋„ JWT ํ† ํฐ์€ ์ฟ ํ‚ค๋กœ ์ „์†ก
  3. CSRF ํ† ํฐ ์—†์ด Authorization ํ—ค๋”๋งŒ ์žˆ์„ ๋•Œ
    • CSRF ํ† ํฐ ํ•„์ˆ˜๋ผ๋Š” ์—๋Ÿฌ ๋ฐœ์ƒ

์›์ธ ๋ถ„์„

http-only cookie๋ฅผ ์‚ฌ์šฉ ์ค‘์ด๋ฏ€๋กœ, Authorization ํ—ค๋”๋ฅผ ๋ณด๋‚ด์ง€ ์•Š๋”๋ผ๋„ ์ฟ ํ‚ค์˜ JWT ํ† ํฐ๋งŒ์œผ๋กœ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ validateSecurity ๋ฏธ๋“ค์›จ์–ด ๋กœ์ง์—์„œ CSRF๋‚˜ JWT ๋‘˜ ๋‹ค ๋ˆ„๋ฝ๋  ๊ฒฝ์šฐ ํ•ด๋‹น ๋ฏธ๋“ค์›จ์–ด์˜ ๋ณด์•ˆ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

์ฝ”๋“œ ๋ถ„์„

express-openapi-validator์˜ ๋‚ด๋ถ€ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•˜๋ฉด์„œ ์ธ์ฆ ๊ด€๋ จ ๋กœ์ง์ด SecuritySchemes ํด๋ž˜์Šค์™€ AuthValidator ํด๋ž˜์Šค์—์„œ ์ฒ˜๋ฆฌ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

  • SecuritySchemes ํด๋ž˜์Šค๋Š” securityHandlers๋ฅผ ํ†ตํ•ด ๋ณด์•ˆ ๊ฒ€์ฆ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • AuthValidator ํด๋ž˜์Šค๋Š” ์š”์ฒญ ํ—ค๋”๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ , Authorization ํ—ค๋”๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • ํŠนํžˆ validateHttp() ๋ฉ”์„œ๋“œ๋Š” ์ด Authorization ํ—ค๋”๋ฅผ ํ•„์ˆ˜๋กœ ์š”๊ตฌํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— type: http๋กœ ์„ค์ •๋œ ์Šคํ‚ด์—์„œ๋Š” Authorization ํ—ค๋”๊ฐ€ ํ•„์ˆ˜์˜€๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค!!

์•„๋ž˜๋Š” ๊ด€๋ จ ์ฝ”๋“œ์ด๋‹ˆ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”!

  • SecuritySchemes
๋”๋ณด๊ธฐ
class SecuritySchemes {
95    constructor(securitySchemes, securityHandlers, securities) {
96        this.securitySchemes = securitySchemes;
97        this.securityHandlers = securityHandlers;
98        this.securities = securities;
99    }
100    async executeHandlers(req) {
101        // use a fallback handler if security handlers is not specified
102        // This means if security handlers is specified, the user must define
103        // all security handlers
104        const fallbackHandler = !this.securityHandlers
105            ? defaultSecurityHandler
106            : null;
107        const promises = this.securities.map(async (s) => {
108            if (Util.isEmptyObject(s)) {
109                // anonymous security
110                return [{ success: true }];
111            }
112            return Promise.all(Object.keys(s).map(async (securityKey) => {
113                var _a, _b, _c;
114                try {
115                    const scheme = this.securitySchemes[securityKey];
116                    const handler = (_b =
117                        (_a = this.securityHandlers) === null || _a === void 0
118                            ? void 0
119                            : _a[securityKey]) !== null && _b !== void 0
120                        ? _b
121                        : fallbackHandler;
122                    const scopesTmp = s[securityKey];
123                    const scopes = Array.isArray(scopesTmp) ? scopesTmp : [];
124                    if (!scheme) {
125                        const message = `components.securitySchemes.${securityKey} does not exist`;
126                        throw new types_1.InternalServerError({ message });
127                    }
128                    if (!scheme.hasOwnProperty('type')) {
129                        const message = `components.securitySchemes.${securityKey} must have property 'type'`;
130                        throw new types_1.InternalServerError({ message });
131                    }
132                    if (!handler) {
133                        const message = `a security handler for '${securityKey}' does not exist`;
134                        throw new types_1.InternalServerError({ message });
135                    }
136                    new AuthValidator(req, scheme, scopes).validate();
137                    // expected handler results are:
138                    // - throw exception,
139                    // - return true,
140                    // - return Promise<true>,
141                    // - return false,
142                    // - return Promise<false>
143                    // everything else should be treated as false
144                    const securityScheme = scheme;
145                    const success = await handler(req, scopes, securityScheme);
146                    if (success === true) {
147                        return { success };
148                    }
149                    else {
150                        throw Error();
151                    }
152                }
153                catch (e) {
154                    return {
155                        success: false,
156                        status: (_c = e.status) !== null && _c !== void 0 ? _c : 401,
157                        error: e,
158                    };
159                }
160            }));
161        });
162        return Promise.all(promises);
163    }
164}
  • AuthValidator
๋”๋ณด๊ธฐ
class AuthValidator {
166    constructor(req, scheme, scopes = []) {
167        const openapi = req.openapi;
168        this.req = req;
169        this.scheme = scheme;
170        this.path = openapi.openApiRoute;
171        this.scopes = scopes;
172    }
173    validate() {
174        this.validateApiKey();
175        this.validateHttp();
176        this.validateOauth2();
177        this.validateOpenID();
178    }
179    validateOauth2() {
180        const { req, scheme, path } = this;
181        if (['oauth2'].includes(scheme.type.toLowerCase())) {
182            // TODO oauth2 validation
183        }
184    }
185    validateOpenID() {
186        const { req, scheme, path } = this;
187        if (['openIdConnect'].includes(scheme.type.toLowerCase())) {
188            // TODO openidconnect validation
189        }
190    }
191    validateHttp() {
192        const { req, scheme, path } = this;
193        if (['http'].includes(scheme.type.toLowerCase())) {
194            const authHeader = req.headers['authorization'] &&
195                req.headers['authorization'].toLowerCase();
196            if (!authHeader) {
197                throw Error(`Authorization header required`);
198            }
199            const type = scheme.scheme && scheme.scheme.toLowerCase();
200            if (type === 'bearer' && !authHeader.includes('bearer')) {
201                throw Error(`Authorization header with scheme 'Bearer' required`);
202            }
203            if (type === 'basic' && !authHeader.includes('basic')) {
204                throw Error(`Authorization header with scheme 'Basic' required`);
205            }
206        }
207    }
208    validateApiKey() {
209        var _d;
210        const { req, scheme, path } = this;
211        if (scheme.type === 'apiKey') {
212            if (scheme.in === 'header') {
213                if (!req.headers[scheme.name.toLowerCase()]) {
214                    throw Error(`'${scheme.name}' header required`);
215                }
216            }
217            else if (scheme.in === 'query') {
218                if (!req.query[scheme.name]) {
219                    throw Error(`query parameter '${scheme.name}' required`);
220                }
221            }
222            else if (scheme.in === 'cookie') {
223                if (!req.cookies[scheme.name] && !((_d = req.signedCookies) === null || _d === void 0 ? void 0 : _d[scheme.name])) {
224                    throw Error(`cookie '${scheme.name}' required`);
225                }
226            }
227        }
228    }
229}

 

๋ฌธ์ œ ํ•ด๊ฒฐ

 

๊ธฐ์กด ์„ค์ •

jwt_auth:
  description: Bearer token authorization with JWT
  type: http
  scheme: bearer
  bearerFormat: JWT
  • jwt_auth๋Š” type: http๋กœ ์„ค์ •๋˜์–ด ์žˆ์—ˆ๊ณ , ์ด ๋•Œ๋ฌธ์— validateHttp() ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜์–ด Authorization ํ—ค๋”๊ฐ€ ํ•„์ˆ˜๋ผ๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ƒˆ๋กœ์šด ์„ค์ •

jwt_auth:
  type: apiKey
  in: cookie
  name: token
  description: JWT token authentication using HTTP-Only cookies
  • jwt_auth๋ฅผ type: apiKey๋กœ ์„ค์ •ํ•˜์—ฌ, ์ด์ œ ์ฟ ํ‚ค์—์„œ JWT๋ฅผ ๊ฒ€์ฆํ•˜๋„๋ก ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.
 

๋ณ€๊ฒฝ ํ›„ validateApiKey() ๋ฉ”์„œ๋“œ๊ฐ€ ์ฟ ํ‚ค์—์„œ JWT๋ฅผ ๊ฒ€์ฆํ•˜๊ฒŒ ๋์Šต๋‹ˆ๋‹ค!

 

Swagger UI
CSRF Error

์ด์ œ์•ผ ์˜๋„ํ•œ ๋Œ€๋กœ ์ž˜ ๋™์ž‘ํ•˜๋„ค์š”!

 

๋‹ค๋งŒ, Authorization ํ—ค๋”๋ฅผ ๋ณด๋‚ด์ง€ ์•Š์•˜์„ ๋•Œ, ์—๋Ÿฌ์˜ ์›์ธ์€ ํŒŒ์•…๋์ง€๋งŒ ์•„์ง๋„ CSRF ํ† ํฐ์„ ๋ณด๋‚ด์คฌ์„ ๋• ์™œ ํ†ต๊ณผ๋˜๋Š” ๊ฑธ๊นŒ?๋ผ๋Š” ์˜๋ฌธ์€ ํ•ด๊ฒฐ์ด ์•ˆ ๋์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ๊ทธ ์˜๋ฌธ์€ ์ œ๊ฐ€ ์ž‘์„ฑํ•ด๋‘” ์•„๋ž˜์˜ validateSecurity ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ๋Œ์•„๋ณด๋ฉฐ ํ’€๋ฆฌ๊ฒŒ ๋์–ด์š”..๐Ÿ˜ญ

validateSecurity: {
	handlers: {
        jwt_auth: async (req) => {
          const isTokenValid = await authHandler(req);
          return isTokenValid && csrfCheck(req);
        },
        csrf_token: authHandler,
     },
},

 

csrf_token์˜ handler๋Š” csrf_token์„ ๋ณด๋‚ด์ฃผ์ง€ ์•Š์•˜์„ ๋• ๋™์ž‘ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์ €๋Š” ์œ„์ฒ˜๋Ÿผ jwt_auth์—์„œ jwt_auth๊ฐ€ ์žˆ์„ ์‹œ csrf_token์˜ ์ฒดํฌ๋„ ํ•จ๊ป˜ํ•ด ์ฃผ๋„๋ก ๋งŒ๋“ค์—ˆ์–ด์š”.

ํ•˜์ง€๋งŒ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ด๋Ÿฐ ์‹์œผ๋กœ ๋“ฑ๋กํ•ด์•ผ ํ•˜๋Š” ๊ฑด ๋ถ€์ž์—ฐ์Šค๋Ÿฝ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์ด ๋ถ€๋ถ„์€ ๋” ๊ฒ€ํ† ํ•ด ๋ณธ ํ›„ ๊ณต์œ ํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์˜ค๋Š˜์€ type: http์— ๋Œ€ํ•œ validateHttp ๋กœ์ง์ด AuthValidator Header๋ฅผ ํ•„์ˆ˜๋กœ ์š”๊ตฌํ•œ๋‹ค๋Š” ๊ฒŒ ๋ฉ”์ธ ์ฃผ์ œ์ด๋‹ˆ ์—ฌ๊ธฐ์„œ ๋” ๋‹ค๋ฃจ์ง„ ์•Š๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์ถ”๊ฐ€ ๊ณ ๋ ค ์‚ฌํ•ญ

type: apiKey๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด Bearer ํ† ํฐ์— ๋Œ€ํ•œ ๊ฒ€์ฆ์ด ์‚ฌ๋ผ์ง„๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด์—๋Š” type: http ์„ค์ • ๋•๋ถ„์— validateHttp ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜์—ˆ๊ณ , ์ด ๋ฉ”์„œ๋“œ๋Š” Authorization ํ—ค๋”์— Bearer ํ† ํฐ์„ ์š”๊ตฌํ•˜๋ฉด์„œ JWT๋ฅผ ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ type: apiKey๋กœ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋˜๋ฉด ์ด์ œ validateApiKey ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ณ  validateApiKey๋Š” Bearer ํ† ํฐ ํ˜•์‹์„ ์ „ํ˜€ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

 

์™œ Bearer ๊ฒ€์ฆ์ด ์ค‘์š”ํ• ๊นŒ์š”?
JWT ํ† ํฐ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Bearer ํ† ํฐ์œผ๋กœ ์ „์†ก๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

์ฆ‰, Authorization: Bearer <JWT> ํ˜•ํƒœ๋กœ ์ „์†ก๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด ๋ฐฉ์‹์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด type: http์™€ scheme: bearer ์„ค์ •์„ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•ด์•ผ validateHttp๊ฐ€ ์ ์ ˆํžˆ Bearer ํ† ํฐ์„ ๊ฒ€์ฆ ๊ฐ€๋Šฅํ•  ํ…Œ๋‹ˆ๊นŒ์š”.

 

ํ•˜์ง€๋งŒ ๋‹จ์ˆœํžˆ JWT๋งŒ ๊ฒ€์ฆํ•˜๊ณ  ์‹ถ๊ณ  Bearer ํ˜•์‹์— ์–ฝ๋งค์ด์ง€ ์•Š๊ฒ ๋‹ค๋ฉด, ํ˜„์žฌ์ฒ˜๋Ÿผ type: apiKey๋กœ ์„ค์ •ํ•œ ํ›„ ์ฟ ํ‚ค์—์„œ JWT๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๋กœ์ง์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

 

ํ˜„์žฌ๊นŒ์ง„, JWT๋ฅผ Bearer ํ˜•์‹์œผ๋กœ ์œ ์ง€ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด validateHttp() ๋ฉ”์„œ๋“œ์—์„œ ์ฟ ํ‚ค๋กœ ์ „๋‹ฌ๋œ JWT๋„ ํ•จ๊ป˜ ๊ฒ€์ฆํ•˜๋„๋ก ๋กœ์ง์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•˜๋‹ค๊ณ  ํŒ๋‹จ๋ฉ๋‹ˆ๋‹ค.

 


๊ฒฐ๋ก 

  • ์ฟ ํ‚ค ๊ธฐ๋ฐ˜ JWT ์ธ์ฆ๋งŒ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, type: apiKey๋กœ ์„ค์ •ํ•œ ํ›„ ์ฟ ํ‚ค์—์„œ JWT๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ํ•˜์ง€๋งŒ Bearer ํ† ํฐ ๋ฐฉ์‹์˜ ๊ฒ€์ฆ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด type: http ์„ค์ •์„ ์œ ์ง€ํ•˜๊ณ , validateHttp()์—์„œ ์ฟ ํ‚ค๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Pull requests

 

์ œ๊ฐ€ ์ƒ๊ฐํ•œ ๋ฐฉ์‹์ด ๋งž๋Š”์ง€, ๋†“์นœ ๋ถ€๋ถ„์€ ์—†๋Š”์ง€ ๊ฒ€ํ† ํ•˜๊ธฐ ์œ„ํ•ด validateHttp ๋ฉ”์„œ๋“œ๋ฅผ ์ˆ˜์ •ํ›„ PR์„ ๋‚จ๊ฒจ๋‘” ์ƒํƒœ์ž…๋‹ˆ๋‹ค.
๋น ๋ฅธ ์ ์šฉ ํ›„ ํ”ผ๋“œ๋ฐฑ์„ ์œ„ํ•ด ์—ฐ๊ด€๋œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊นŒ์ง„ ์†์„ ๋Œ€์ง€ ์•Š์•˜์ง€๋งŒ,
ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ๋” ๊นŠ๊ฒŒ ๊ณ ๋ฏผํ•ด ๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค!

 

 

๐Ÿ“ƒ ์ฐธ๊ณ  ๋ฌธํ—Œ  
npm-package
GitHub - cdimascio/express-openapi-validator

 

Allini๋Š” Create React App(CRA)์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ์ง์ ‘ Webpack๊ณผ Babel์„ ์„ค์ •ํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.
ํšŒ์‚ฌ์—์„œ Webpack์„ ์„ค์ •ํ•ด๋ณธ ๊ฒฝํ—˜์ด ์žˆ์–ด, ์ฒ˜์Œ์—๋Š” ๊ทธ ๊ธฐ์–ต์— ์˜์กดํ•ด ์ž‘์—…์„ ์‹œ์ž‘ํ–ˆ์–ด์š”.

๊ทธ๋Ÿฐ๋ฐ ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ๋„์ค‘ Pretendard-Black.subset.woff2 ๋ฐ Pretendard-ExtraBold.subset.woff2 ํฐํŠธ ํŒŒ์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†๋‹ค๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์ด ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํŒŒ์ผ ์œ„์น˜, font.css์˜ ๊ฒฝ๋กœ, ํŒŒ์ผ๋ช…, ๋นŒ๋“œ ์บ์‹œ ์‚ญ์ œ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ,

๋ฌธ์ œ๋Š” ์—ฌ์ „ํžˆ ํ•ด๊ฒฐ๋˜์ง€ ์•Š์•˜๊ณ ..๐Ÿ˜ข

์ œ๊ฐ€ ์ž‘์„ฑํ•œ Webpack ์„ค์ • ์ž์ฒด์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹Œ๊ฐ€ ์˜์‹ฌํ•˜๊ฒŒ ๋์Šต๋‹ˆ๋‹ค.

 

Webpack ์„ค์ • ์ ๊ฒ€: file-loader๋Š” ์ž˜ ๋“ฑ๋กํ–ˆ๋Š”๋ฐ...

์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ์ด์œ ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด webpack.config.js ํŒŒ์ผ์—์„œ ํŒŒ์ผ ๋กœ๋” ์„ค์ •์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

file-loader๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•ด๋‘์—ˆ๊ธฐ์—, ๋ฌธ์ œ๊ฐ€ ์—†์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์—ˆ์ฃ ..! 

{
  test: /\.(png|jpe?g|gif|webp)$/i,
  use: [
    {
      loader: "file-loader",
      options: {
        name: "[path][name].[ext]",
      },
    },
  ],
}

 

๊ทธ๋ ‡๊ธฐ์— ์ด ์„ค์ •์—๋Š” ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๊ณ , ์™œ ์ด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ๋„์ €ํžˆ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

 

์—‰๋šฑํ•œ ๊ณ ๋ฏผ: MSW๊ฐ€ ๋ฌธ์ œ์ธ๊ฐ€?

์ด์ฏค ๋˜๋‹ˆ MSW(Mocking Service Worker)๊ฐ€ ํฐํŠธ ํŒŒ์ผ์กฐ์ฐจ ๊ฐ€๋กœ์ฑ„๋Š” ๊ฒƒ์ด ์•„๋‹Œ๊ฐ€ ํ•˜๋Š” ์—‰๋šฑํ•œ ์ƒ๊ฐ๊นŒ์ง€ ํ•˜๊ฒŒ ๋˜์—ˆ์–ด์š”..!

MSW๋Š” ๋ฐฑ์—”๋“œ๊ฐ€ ๊ตฌ์ถ•๋˜๊ธฐ ์ „์— ํ”„๋ก ํŠธ์—”๋“œ UI ๊ฐœ๋ฐœ์„ ์œ„ํ•ด ์‚ฌ์šฉ ์ค‘์ด์—ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฝ์–ด๋ณธ ๊ฒฐ๊ณผ, MSW๋Š” ์ •์  ๋ฆฌ์†Œ์Šค(์˜ˆ: ํฐํŠธ ํŒŒ์ผ)์—๋Š” ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

MSW๊ฐ€ ํฐํŠธ ํŒŒ์ผ ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑ„์ง€ ์•Š๋Š” ํ•œ, ์ด ๋ฌธ์ œ๋Š” MSW์™€ ๊ด€๋ จ์ด ์—†์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•˜์Šต๋‹ˆ๋‹ค.

 

์ง„์งœ ๋ฌธ์ œ: Webpack ๋ฒ„์ „ ์ฐจ์ด

๊ณ ๋ฏผ์„ ๊ฑฐ๋“ญํ•˜๋˜ ์ค‘, ํ˜น์‹œ ๋‚ด๊ฐ€ ์•Œ๊ณ  ์žˆ๋˜ Webpack ์„ค์ •๊ณผ ํ˜„์žฌ ์‚ฌ์šฉํ•˜๋Š” ๋ฒ„์ „ ๊ฐ„์— ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๊ฒƒ์€ ์•„๋‹๊นŒ ํ•˜๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ์ƒ๊ฐ์ด ๋ฐ”๋กœ ์ •๋‹ต์ด์—ˆ์ฃ !!!  แ•ฆ( แ› )แ•ก

 

๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ž˜ ๋ด์•ผํ•ด์š”!!

 

Webpack 5์—์„œ๋Š” ํŒŒ์ผ ๋กœ๋” ์„ค์ •์ด ๊ฐ„์†Œํ™”๋˜์—ˆ๊ณ , ๋” ์ด์ƒ file-loader๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

Webpack 5์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค:

{
  test: /\.(jpg|jpeg|gif|png|svg|eot|woff|ttf)$/i,
  type: "asset/resource",
}

 

Webpack 5์—์„œ๋Š” file-loader์™€ url-loader๋“ฑ์„ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , asset/resource, asset/inline, ๊ทธ๋ฆฌ๊ณ  asset์„ ํ†ตํ•ด ํŒŒ์ผ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • asset/resource: ๋ณ„๋„์˜ ํŒŒ์ผ์„ ๋‚ด๋ณด๋‚ด๊ณ  URL์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. (file-loader ๋Œ€์ฒด)
  • asset/inline: ๋ฐ์ดํ„ฐ URL๋กœ ๋‚ด๋ณด๋‚ด๊ธฐ (url-loader ๋Œ€์ฒด)
  • asset: ์ž๋™์œผ๋กœ ๋ฐ์ดํ„ฐ URL๊ณผ ํŒŒ์ผ ๋‚ด๋ณด๋‚ด๊ธฐ ์ค‘ ์„ ํƒํ•˜๋ฉฐ, ๊ธฐ์กด์˜ ํฌ๊ธฐ ์ œํ•œ ์„ค์ •๋„ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ฐธ๊ณ ํ–ˆ๋˜ Webpack ๊ณต์‹ ๋ฌธ์„œ ๋งํฌ๋ฅผ ๋‚จ๊ฒจ๋‘˜๊ฒŒ์š”!!

 

ํ•™์Šต ๋ฐฉ์‹์— ๋Œ€ํ•œ ๋ฐ˜์„ฑ, ๊ทธ๋ฆฌ๊ณ  ์•ž์œผ๋กœ์˜ ๊ณ„ํš

์ด์ „์— TOAST Editor๊ฐ€ React 17 ๋ฒ„์ „๊นŒ์ง€๋งŒ ์ง€์›๋œ๋‹ค๋Š” ์ด์Šˆ๋ฅผ ๊ฒช์—ˆ๋˜ ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถ€๋„๋Ÿฝ์ง€๋งŒ ๊ทธ๋•Œ๋„ ์ด์ „ ์ง€์‹์—๋งŒ ์˜์กดํ–ˆ๋˜ ํƒ“์—, ์‚ฌ์šฉ๋œ ๊ธฐ์ˆ  ์Šคํƒ์— ๋Œ€ํ•ด ์ถฉ๋ถ„ํžˆ ๊ฒ€ํ† ํ•˜์ง€ ์•Š์•˜๋˜ ๊ฒฝํ—˜์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๋ฒˆ Webpack ์„ค์ • ๋ฌธ์ œ๋ฅผ ๊ฒช์œผ๋ฉด์„œ, ๋‹ค์‹œ ํ•œ ๋ฒˆ ์ €์˜ ํ•™์Šต ๋ฐฉ์‹์— ๋Œ€ํ•ด ๋Œ์•„๋ณด๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค..!

Webpack ๋ฒ„์ „์„ ์˜ฌ๋ฆฐ ํ›„์—๋„ ๋‹ค๋ฅธ ์ž‘์—…์— ๊ธ‰๊ธ‰ํ•ด ์ค‘์š”ํ•œ ๋ณ€ํ™”๋ฅผ ๋ฏธ์ฒ˜ ํ™•์ธํ•˜์ง€ ์•Š์•˜๋˜ ๊ฒƒ์ด ์›์ธ์ด์—ˆ์œผ๋‹ˆ๊นŒ์š”.

 

Allini ํ”„๋กœ์ ํŠธ๋Š” ํŒ€์›๋“ค์˜ ํšŒ์‚ฌ ์—…๋ฌด๋กœ ์ธํ•ด ์ž ์‹œ ์ค‘๋‹จ๋˜์—ˆ์—ˆ์ง€๋งŒ, ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!

ํ˜„์žฌ๋Š” ๋””์ž์ด๋„ˆ๋‹˜์ด ์š”์ฒญํ•œ ์ˆ˜์ •๋œ UI๋ฅผ ๋น ๋ฅด๊ฒŒ ์ ์šฉํ•˜๋Š” ๊ฒƒ์ด ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’๋‹ค๊ณ  ํŒ๋‹จํ•˜์—ฌ, ์ด ๋ถ€๋ถ„๋ถ€ํ„ฐ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

๊ทธ๋ ‡๊ธฐ์— Webpack 5 ๋ฒ„์ „์— ๋งž์ถ˜ ์ „์ฒด์ ์ธ ์„ค์ • ์ˆ˜์ •์€ ํ”„๋กœ์ ํŠธ๊ฐ€ ์™„์„ฑ๋œ ํ›„์— ์ง„ํ–‰ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

์šฐ์„ ์€ ํ”„๋กœ์ ํŠธ์˜ ์™„์„ฑ๋„๋ฅผ ๋†’์ด๋Š” ๋ฐ ์ง‘์ค‘ํ•˜๊ณ , ์ž‘์—… ์ค‘ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋“ค์€ ํ•˜๋‚˜์”ฉ ํ•ด๊ฒฐํ•ด ๋‚˜๊ฐˆ ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

 

ํ”„๋กœ์ ํŠธ๊ฐ€ ๋งˆ๋ฌด๋ฆฌ๋˜๋ฉด, CSS ํŒŒ์ผ์„ ๊ฐœ๋ณ„์ ์œผ๋กœ ์ถ”์ถœํ•˜๊ธฐ ์œ„ํ•œ MiniCssExtractPlugin ๋“ฑ์˜ ๋ฆฌํŒฉํ† ๋ง๋„ ์ง„ํ–‰ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

์ด ๊ณผ์ •์—์„œ ์ž‘์„ฑ๋œ ์ตœ์ข… ์ฝ”๋“œ๋„ ๋‚˜์ค‘์— ๋ธ”๋กœ๊ทธ์— ๊ณต์œ ํ•  ์˜ˆ์ •์ด๋‹ˆ, ๊ธฐ๋Œ€ํ•ด ์ฃผ์„ธ์š”! ๐Ÿ’ช

 

๐Ÿ“ƒ ์ฐธ๊ณ  ๋ฌธํ—Œ  
Webpack Asset Modules ๊ณต์‹๋ฌธ์„œ ์›๋ฌธ
Webpack Asset Modules ๊ณต์‹๋ฌธ์„œ ๋ฒˆ์—ญ

 

React.js์™€ Next.js ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋˜ ์ค‘, ์ฒ˜์Œ ๊ฐœ๋ฐœ ๊ณต๋ถ€๋ฅผ ์‹œ์ž‘ํ•  ๋•Œ ๊ณ ๋ฏผํ–ˆ๋˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•ด ๋‹ค์‹œ ํ•œ๋ฒˆ ์ •๋ฆฌํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ณผ๊ฑฐ์—๋Š” ์ด๋“ค์„ ์™„์„ฑ๋œ ๋กœ๋ด‡๊ณผ ์กฐ๋ฆฝํ˜• ๋กœ๋ด‡์— ๋น„์œ ํ•˜๊ณค ํ–ˆ์ง€๋งŒ, ์ง€๊ธˆ์€ ๋‹ค๋ฅด๊ฒŒ ์ ‘๊ทผํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๊ธฐ์— ์•ž์„œ ๊ธ€ ์ œ๋ชฉ๊ณผ ๊ฐ™์ด React.js์— ๋Œ€ํ•ด "๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ๋ฌด์—‡์ธ์ง€" ํ˜ผ๋™ํ•˜๋Š” ๋ถ„๋“ค์ด ๊ณ„์‹ค๊นŒ์š”?

https://ko.legacy.reactjs.org/

 

๊ทธ๋ ‡๋‹ค๋ฉด ๊ณต์‹ ๋ฌธ์„œ๋ถ€ํ„ฐ ํ™•์ธํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

๊ณต์‹ ๋ฌธ์„œ์˜ ๋ฉ”์ธ ํŽ˜์ด์ง€์—์„œ์กฐ์ฐจ "์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ JavaScript ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ" ๋ผ๋Š” ๋ฌธ๊ตฌ๋กœ ์šฐ๋ฆฌ๋ฅผ ํ™˜์˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด ์ˆ˜๋งŽ์€ ์‚ฌ๋žŒ๋“ค์€ ๋„๋Œ€์ฒด ๋ฌด์—‡ ๋•Œ๋ฌธ์— ํ˜ผ๋™ํ•˜๊ฒŒ ๋œ ๊ฑธ๊นŒ์š”?

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋Œ€ํ•ด ๊ฐ„๋žตํžˆ ์„ค๋ช…๋“œ๋ฆฐ ํ›„ "React.js๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ผ๊นŒ?"  ๋ชฉ์ฐจ์—์„œ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ •๋ฆฌํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 


๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ”„๋ ˆ์ž„์›Œํฌ๋ž€?

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

๊ฒ€์ƒ‰ ์‹œ ์‰ฝ๊ฒŒ ์•„๋ž˜์˜ ๋‚ด์šฉ๋“ค์„ ํ™•์ธํ•ด ๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

"ํŠน์ •ํ•œ ๊ธฐ๋Šฅ์„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฏธ๋ฆฌ ์ž‘์„ฑ๋œ ์ฝ”๋“œ์˜ ์ง‘ํ•ฉ"

"๊ฐœ๋ฐœ์ž๊ฐ€ ํ•„์š”์— ๋”ฐ๋ผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ, ๋„๊ตฌ์ฒ˜๋Ÿผ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ์„ ํƒ์ ์œผ๋กœ ์‚ฌ์šฉ"

 

์ •๋ฆฌํ•ด ๋ณด์ž๋ฉด, ๋ฌด์–ธ๊ฐ€๋ฅผ ๋งŒ๋“ค ๋•Œ ์œ ์šฉํ•œ ๋„๊ตฌ ๊ฐ™์€ ์นœ๊ตฌ๋„ค์š”.

๋งˆ์น˜ ๋ฏธ์šฉ์‹ค์—์„œ ์“ฐ๋Š” ๋„๊ตฌ๋‚˜ ๊ณต์‚ฌ ํ˜„์žฅ์—์„œ ์“ฐ๋Š” ๋„๊ตฌ์ฒ˜๋Ÿผ, ํŠน์ •ํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด ์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด ์ค๋‹ˆ๋‹ค.

๋“œ๋ผ์ด๊ธฐ๋กœ ๋จธ๋ฆฌ๋ฅผ ๋ง๋ฆด ํ•„์š”๋Š” ์—†์ง€๋งŒ, ํ•„์š”ํ•˜๋ฉด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ด๋Ÿฐ ๋„๊ตฌ๋“ค์€ ํ•„์š”์— ๋งž๊ฒŒ ๊ณจ๋ผ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋ ˆ์ž„์›Œํฌ

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ณด๋‹ค ๋” ํฐ ๋‹จ์œ„์˜ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ์˜ ์˜ˆ์‹œ๋ฅผ ๊ฐ€์ ธ์™€ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฏธ์šฉ์‹ค์—์„œ ๋จธ๋ฆฌ๋ฅผ ๋ง๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์„ ๋‹ค ์ •ํ•ด์ฃผ๊ณ , ๊ทธ ์•ˆ์—์„œ ์ •ํ•ด์ง„ ๋ฐฉ๋ฒ•์„ ์ด์šฉํ•ด ๋จธ๋ฆฌ๋ฅผ ๋ง๋ฆฌ๋Š”(ํ•„์š”ํ•œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š”) ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ Next.js๋Š” React.js๋ฅผ ๋ฒ ์ด์Šค๋กœ ํ•ด ์›น์„ ๋งŒ๋“œ๋Š”๋ฐ ํ•„์š”ํ•œ ์ „์ฒด์ ์ธ ํ•ด๊ฒฐ์ฑ…์„ ์ œ๊ณตํ•ด ์ค๋‹ˆ๋‹ค!

React.js์™€ Next.js์˜ ๊ด€๊ณ„

  • React.js๋Š” UI๋ฅผ ์„ ์–ธ์ ์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ์„ ํƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • Next.js๋Š” ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ์ „์ฒด์ ์ธ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•˜๋ฉฐ, React๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ํฌํ•จํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, ํ”„๋ ˆ์ž„์›Œํฌ์™€ React,js, Next.js์— ๋Œ€ํ•ด ๊ฐ„๋žตํžˆ ์„ค๋ช…๋“œ๋ ธ์Šต๋‹ˆ๋‹ค.

์ด์ œ ๋ณธ๋ก ์œผ๋กœ ๋“ค์–ด๊ฐ€ ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

 

React.js๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ผ๊นŒ?

์ €๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ํ•™์Šต์—์„œ "ํ”„๋ ˆ์ž„์›Œํฌ ์—†๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ | ํ”„๋ž€์„ธ์Šค์ฝ” ์ŠคํŠธ๋ผ์ธจ๋กœ" ๊ต์žฌ์˜,

"ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ฝ”๋“œ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค"๋ผ๋Š” ๋ฌธ๊ตฌ๊ฐ€ ๊ฐ€์žฅ ์™€๋‹ฟ์•˜์Šต๋‹ˆ๋‹ค.

๊ต์žฌ๋ฅผ ํ•™์Šตํ•˜๋ฉฐ ํ•ด๋‹น ๋ฌธ๊ตฌ๊ฐ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ฐจ์ด์— ๋Œ€ํ•ด ์ •๋ง ์ž˜ ์„ค๋ช…ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์–ด์š”.

 

๋ฐœ์ทŒํ•œ ๋ฌธ์žฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์‹œ ์ •๋ฆฌํ•˜์ž๋ฉด,

  • ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‹คํ–‰ ํ๋ฆ„์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ํ˜ธ์ถœํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋‚˜๋ˆ ๋ณผ ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”!
์—ฌ๊ธฐ์„œ ์ฝ”๋“œ๋ž€ ๊ตฌ์ฒด์ ์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

 

๋ฐœ์ทŒํ•œ ๋ฌธ์žฅ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ธ€์„ ์จ ๋‚ด๋ ค๊ฐˆ ์˜ˆ์ •์ด์—์š”.

์ฐธ๊ณ ํ•˜์—ฌ ์ฝ์œผ์‹ ๋‹ค๋ฉด ์ข€ ๋” ๋„์›€์ด ๋˜์‹ค ๊ฑฐ๋ผ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค!

๋‹ค์‹œ ๊ฐ•์กฐํ•˜์ž๋ฉด React.js๋Š” ๊ณต์‹์ ์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค.

์ด๋Š” React๊ฐ€ UI ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋‚˜ ์ €๋ฅผ ํฌํ•จํ•œ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์€ React๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด์œ ๊ฐ€ ๋ญ˜๊นŒ์š”?

 

์ด๋Š” ๋ฆฌ์•กํŠธ ์ƒํƒœ๊ณ„์™€ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ๊ฐ•๋ ฅํ•œ ์˜ํ–ฅ๋ ฅ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
React๋Š” UI๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‹œ์ž‘ํ–ˆ์ง€๋งŒ, ์ƒํƒœ๊ณ„์˜ ๋ฐœ์ „๊ณผ ํ•จ๊ป˜ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด React๋ฅผ ์ด์šฉํ•ด ํ”„๋ ˆ์ž„์›Œํฌ์ฒ˜๋Ÿผ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์กฐํ™”ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. 

 

์ด์ œ ์ง€๊ธˆ๊นŒ์ง€์˜ ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ ์‹ค์ œ ๊ฐœ๋ฐœ๊ณผ์ •์„ ์˜ˆ์‹œ๋กœ ๋“ค์–ด ๋‹ค์‹œ ํ•œ๋ฒˆ ์ •๋ฆฌํ•ด ๋ณด๋„๋ก ํ• ๊ฒŒ์š”!

 

์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•ด์•ผ ๋ ๊นŒ?

 

ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ ๋ฐฉ์‹๊ณผ ๋ชฉ์ ์„ ๋ช…ํ™•ํžˆ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

React๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋•Œ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋•Œ์˜ ์ฐจ์ด๋ฅผ ์ดํ•ดํ•˜๋ฉด ๋” ๋‚˜์€ ์„ ํƒ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

React๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋•Œ

์ปค๋ฎค๋‹ˆํ‹ฐ์™€ ์ƒํƒœ๊ณ„์˜ ์˜ํ–ฅ๋ ฅ

  • ๋ฆฌ์•กํŠธ๋Š” ์ดˆ๊ธฐ ์„ค์ •๊ณผ ๊ตฌ์กฐ๊ฐ€ ์ด๋ฏธ ์žกํ˜€์žˆ๋Š” ์ƒํƒœ์—์„œ ์‹œ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์€ ์ด๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, npm create-react-app์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๋ฉด ์ •ํ•ด์ง„ ๊ตฌ์กฐ ์•ˆ์—์„œ ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ ๋‚ด์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ

  • ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ปดํฌ๋„ŒํŠธ์— ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง, API ํ˜ธ์ถœ ๋“ฑ์„ ๋ชจ๋‘ ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ๋ฆฌ์•กํŠธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ˜•ํƒœ๋กœ ๋™์ž‘ํ•˜๊ฒŒ ํ•˜์—ฌ ํ”„๋ ˆ์ž„์›Œํฌ์ฒ˜๋Ÿผ ๋А๊ปด์ง€๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

์ฆ‰, React ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ชจ๋“  ์‹คํ–‰ ํ๋ฆ„์„ ์ œ์–ดํ•˜๋ฉฐ, ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์žฅ์ :

  • ๋น ๋ฅธ ๊ฐœ๋ฐœ ์†๋„: ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์— ํ†ตํ•ฉํ•˜์—ฌ ๋น ๋ฅด๊ฒŒ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ๊ตฌ์กฐ๊ฐ€ ๋ช…ํ™•ํ•˜๊ณ  ์ผ๊ด€์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹จ์ :

  • ์˜์กด์„ฑ ์ฆ๊ฐ€: ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์— ๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋˜์–ด ์žˆ์–ด, ๋ฆฌ์•กํŠธ๋ฅผ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋Œ€์ฒดํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
  • ์ด๋Š” ํ–ฅํ›„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹œ ํฐ ๋น„์šฉ์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

React๋ฅผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋•Œ

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ UI ๋ Œ๋”๋ง์„ ๋ถ„๋ฆฌํ•˜๊ณ , ์ด ๋‘˜์„ ์—ฐ๊ฒฐํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋‘๋Š” ๋ฐฉ๋ฒ•

 

์ƒํƒœ ๊ด€๋ฆฌ์™€ UI ์—…๋ฐ์ดํŠธ

  • ๋ฆฌ์•กํŠธ์—์„œ setState๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด UI๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋ฉ๋‹ˆ๋‹ค. ์ด ์ ์„ ํ™œ์šฉํ•˜์—ฌ, setState๋ฅผ UI๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์š”์†Œ๋กœ ๊ฐ„์ฃผํ•˜๊ณ , UI ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์—๋งŒ setState๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋Ÿฐ์‹์œผ๋กœ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ๋ฆฌ์•กํŠธ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฆฌ์•กํŠธ๋Š” ์˜ค๋กœ์ง€ UI๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์—ญํ• ๋งŒ ํ•˜๊ฒŒ ๋˜๋ฉฐ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋ถ„๋ฆฌ

  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ํ“จ์–ดํ•œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์ž‘์„ฑํ•˜์—ฌ ๋ฆฌ์•กํŠธ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ†ตํ•ด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ UI์™€ ๋ณ„๊ฐœ๋กœ ์ž‘๋™ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

UI ๋ Œ๋”๋ง์—๋งŒ ์ง‘์ค‘

  • ๋ฆฌ์•กํŠธ๋ฅผ ์ˆœ์ˆ˜ UI ๋ Œ๋”๋ง ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋ฆฌ์•กํŠธ ์™ธ๋ถ€์˜ ์ˆœ์ˆ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค ๋“ฑ์˜ ์ฝ”๋“œ๋กœ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์•กํŠธ๋Š” ์˜ค์ง ๋ฐ์ดํ„ฐ๋ฅผ ํ™”๋ฉด์— ๋ Œ๋”๋งํ•˜๋Š” ์—ญํ• ๋งŒ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋‹ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค ๋“ฑ์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜์—ฌ, ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์™€ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•œ ํ†ต์‹ 

  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ํ†ต์‹ (์—ฐ๊ฒฐ)์„ ๋‹ด๋‹นํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์„ค๊ณ„ํ•˜์—ฌ, ์ƒํƒœ ๋ณ€๊ฒฝ์„ ๋ฆฌ์•กํŠธ์— ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ณ , ํ•„์š”ํ•œ ์‹œ์ ์— ๋ฆฌ์•กํŠธ์˜ setState๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ UI๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•œ ๊ตฌํ˜„ ์˜ˆ์‹œ

/**
* ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง - ์ˆœ์ˆ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํด๋ž˜์Šค
*/
class BusinessLogic {
  constructor() {
    this.data = null;
    this.listeners = [];
  }

  setData(newData) {
    this.data = newData;
    this.notifyListeners();
  }

  getData() {
    return this.data;
  }

  addListener(listener) {
    this.listeners.push(listener);
  }

  notifyListeners() {
    this.listeners.forEach(listener => listener(this.data));
  }
}

/**
* ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ - UI ๋ Œ๋”๋ง
*/
import React, { useState, useEffect } from 'react';

const TestComp = ({ businessLogic }) => {
  const [data, setData] = useState(businessLogic.getData());

  useEffect(() => {
    const handleDataChange = (newData) => {
      setData(newData);
    };

    businessLogic.addListener(handleDataChange);

    return () => {
      businessLogic.removeListener(handleDataChange);
    };
  }, [businessLogic]);

  return (
    <div>
      <h1>{data}</h1>
    </div>
  );
};

/**
* ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ
*/
const logic = new BusinessLogic();
logic.setData("์ปคํ”ผ ๋งˆ์‹œ๊ณ ์‹ถ๋‹ค..");

const App = () => (
  <TestComp businessLogic={logic} />
);

export default App;

 

์žฅ์ 

  • ๋งŒ์•ฝ ๋ฆฌ์•กํŠธ๋ฅผ ์‹œ์žฅ์—์„œ ๋”์ด์ƒ ์›ํ•˜์ง€ ์•Š๊ฒŒ ๋˜๊ฑฐ๋‚˜ ์ƒˆ๋กœ์šด UI ๋ Œ๋”๋ง ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(์˜ˆ: ์Šค๋ฒจํŠธ)๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ–ˆ๋‹ค๋ฉด ์ „ํ™˜์ด ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๋ฆฌ์•กํŠธ์™€ ๋…๋ฆฝ์ ์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋‹จ์ 

  • ์‹ค์ œ ์‚ฌ๋ก€ ๋“œ๋ฌพ: ๋งŽ์€ ํšŒ์‚ฌ๋“ค์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ์‹์„ ์ฑ„ํƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ฐœ๋ฐœ ๋น„์šฉ๊ณผ ์‹œ๊ฐ„์ด ๋งŽ์ด ๋“ค๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
  • ๋†’์€ ๊ฐœ๋ฐœ ๋น„์šฉ: ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ UI๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ชจ๋“  ๊ฒƒ์„ ์ธํ„ฐํŽ˜์ด์Šค๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ๊ฐœ๋ฐœ ๋น„์šฉ์ด ๋งŽ์ด ๋“ญ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ดˆ๊ธฐ ๋Ÿฐ์นญ์ด ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์•„๋ž˜์—์„œ ์ข€ ๋” ์ƒ์„ธํžˆ ์ €์˜ ์ƒ๊ฐ์„ ํ’€์–ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค.

์œ„์™€ ์ค‘๋ณต๋˜๋Š” ๋‚ด์šฉ์ด ์žˆ์ง€๋งŒ ํ๋ฆ„์„ ์œ„ํ•ด ๊ทธ๋Œ€๋กœ ์ ์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

 

๊ธฐ์ˆ  ๋ถ€์ฑ„์™€ ๊ทธ ๊ด€๋ฆฌ

์ €๋Š” ๊ธฐ์ˆ  ๋ถ€์ฑ„์— ๋Œ€ํ•ด ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ๋‹จ๊ธฐ์ ์ธ ์ด์ต์„ ์œ„ํ•ด ์žฅ๊ธฐ์ ์ธ ์œ ์ง€๋ณด์ˆ˜ ๋น„์šฉ์„ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ์„ ํƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด ๊ธฐ์ˆ  ๋ถ€์ฑ„์˜ ๊ฐœ๋…์€ "React.js์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ”„๋ ˆ์ž„์›Œํฌ ๋ฐฉ์‹์˜ ๊ฒฐ์ •"์— ๋„์›€์„ ์ค„ ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ•ด์š”!

 

๊ทธ๋ž˜์„œ ์ง€๊ธˆ๋ถ€ํ„ฐ React๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋•Œ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋•Œ์˜ ๊ธฐ์ˆ  ๋ถ€์ฑ„๋ฅผ ๋น„๊ตํ•ด ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ”„๋ ˆ์ž„์›Œํฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋•Œ์˜ ๊ธฐ์ˆ  ๋ถ€์ฑ„

  • ๊ฐ•ํ•œ ๊ฒฐํ•ฉ์œผ๋กœ ์ธํ•ด ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ „ํ™˜์ด ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค.
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด React ์ปดํฌ๋„ŒํŠธ์— ๊นŠ์ด ๊ฒฐํ•ฉ๋˜์–ด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋•Œ์˜ ๊ธฐ์ˆ  ๋ถ€์ฑ„

  • ์ดˆ๊ธฐ ๊ฐœ๋ฐœ ๋น„์šฉ์ด ๋†’์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐ ๊ธฐ๋Šฅ์ด ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์–ด ๊ฐœ๋ฐœ ์†๋„๊ฐ€ ๋А๋ ค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์ˆ  ๋ถ€์ฑ„ ๊ด€๋ฆฌ์˜ ์ค‘์š”์„ฑ

๊ธฐ์ˆ  ๋ถ€์ฑ„๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ์ผ์ •์— ๋งž๊ฒŒ ๊ธฐ์ˆ  ๋ถ€์ฑ„๋ฅผ ์ž˜ ์กฐ์ •ํ•˜๋ฉด, ์žฅ๊ธฐ์ ์œผ๋กœ ๋” ๋‚˜์€ ์œ ์ง€๋ณด์ˆ˜์™€ ํ™•์žฅ์„ฑ์„ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๋ฌด์—‡๋ณด๋‹ค ์ €๋Š” ๊ธฐ์ˆ  ๋ถ€์ฑ„๊ฐ€ ์ƒ๊ฒจ๋„ ์ฒญ์‚ฐ๋งŒ ์ž˜ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๊ธฐ์ˆ  ๋ถ€์ฑ„๋ฅผ ์ž˜ ๋‚ด๋Š” ๊ฒƒ๋„ ์ €๋Š” ์ค‘์š”ํ•œ ๋Šฅ๋ ฅ์ด๋ผ๊ณ  ๋ณด๊ณ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž๊ฐ€ ์ด์œ ์ฝ”๋“œ๋งŒ ์ž‘์„ฑํ•˜๋Š” ์˜ˆ์ˆ ๊ฐ€๋Š” ์•„๋‹ˆ๋‹ˆ๊นŒ์š”.

๊ทธ๋Ÿฌ๋‹ˆ ๋ฌด์–ธ๊ฐ€๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋‹จ์ˆœํ•˜๊ฒŒ ์ •์˜๋œ ํŠน์ • ๋‹จ์–ด๋‚˜ ๋ฌธ์žฅ๋งŒ์„ ๋ฐ›์•„๋“ค์ด๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ ์ƒ๋Œ€์ ์œผ๋กœ ์ƒ๊ฐํ•˜๋Š” ์Šต๊ด€์„ ๋“ค์ผ ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋น ๋ฅธ ์„ฑ์žฅ์— ์œ ๋ฆฌํ•˜์ง€ ์•Š์„๊นŒ ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

 


๊ฒฐ๋ก 

React๋Š” ๊ณต์‹์ ์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด์ง€๋งŒ, ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ํ”„๋ ˆ์ž„์›Œํฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ์˜ ํŠน์„ฑ๊ณผ ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ React๋ฅผ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์ˆ  ๋ถ€์ฑ„๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉด์„œ, ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ฐจ์ด๋ฅผ ์ดํ•ดํ•˜๊ณ  ์ ์ ˆํ•˜๊ฒŒ ํ™œ์šฉํ•˜๋ฉด ์„ฑ๊ณต์ ์ธ ๊ฐœ๋ฐœ์„ ์ด๋ฃฐ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒ๋Œ€์ ์œผ๋กœ ์‚ฌ๊ณ ํ•˜๊ณ , ์ƒํ™ฉ์— ๋งž๋Š” ์ตœ์„ ์˜ ์„ ํƒ์„ ํ•˜๋Š” ์Šต๊ด€์„ ๊ธฐ๋ฅด๋ฉด ๋”์šฑ ๋น ๋ฅด๊ฒŒ ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

 

์—ฌ๋Ÿฌ๋ถ„๋“ค๊ป˜์„œ ์ด ๊ธ€์„ ์ฝ๊ณ  ๋‚œ ํ›„์—๋„, ๊ณ„์† ํ•™์Šตํ•˜๋ฉฐ ๋‹ค์–‘ํ•œ ์˜๊ฒฌ์„ ์ ‘ํ•˜๊ฒŒ ๋˜์‹œ๊ฒ ์ฃ ?!

์ž์‹ ๋“ค๋งŒ์˜ ๋‹จ์–ด๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜๊ณ , ๊ฐœ๋ฐœ ๋ฐฉํ–ฅ์— ๋Œ€ํ•œ ๊ธธ์žก์ด ์—ญํ• ์— ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ผ๋ฉฐ ์ด๋งŒ ๋งˆ์น˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

'CS' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Chrome ๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง - Critical Path ์ด์ „ ๊ณผ์ •์€?  (0) 2024.03.20

- ํ”„๋กœ์ ํŠธ๋ช… Allini -

๋กœ๊ณ ์˜ ๋””์ž์ธ์€ ํ”„๋กœ์ ํŠธ๋ช…์ธ Allini์˜ A์™€ ๊ฐ•์•„์ง€์˜ ์ฝ” ๋ชจ์–‘์„ ์„ž์–ด ๋””์ž์ธ๋์–ด์š”!

 

์•ˆ๋…•ํ•˜์„ธ์š”, ์˜ค๋Š˜์€ ์ œ๊ฐ€ ์ตœ๊ทผ์— ์‹œ์ž‘ํ•œ ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•ด ์†Œ๊ฐœํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์ด ํ”„๋กœ์ ํŠธ๋Š” ์ œ ๋ฐ˜๋ ค๊ฒฌ์˜ ๊ฑด๊ฐ•์„ ๊ด€๋ฆฌํ•˜๊ณ  ์•Œ๋ ˆ๋ฅด๊ธฐ ์ฆ์ƒ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ์‹œ์ž‘๋์–ด์š”!

์ง์ ‘ ์ž…๋ ฅ ๋˜๋Š” Tesseract.js ๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋ฏธ์ง€ ํ…์ŠคํŠธ ์ถ”์ถœ ์˜ˆ์ •!

์šฐ๋ฆฌ ๊ฐ•์•„์ง€๋“ค์ด ๋จน์€ ์Œ์‹๋“ค์„ ๊ธฐ๋กํ•˜๊ณ , ๊ทธ ์ •๋ณด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ†ต๊ณ„๋ฅผ ๋‚ด๊ณ , ์‹ฌ์ง€์–ด๋Š” ๊ฐ„์‹์„ ์ถ”์ฒœํ•ด์ฃผ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์šฐ๋ฆฌ ๊ฐ•์•„์ง€๊ฐ€ ์•Œ๋ ˆ๋ฅด๊ธฐ ๋ฐ˜์‘์„ ๋ณด์ธ ์Œ์‹๋“ค๋„ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์–ด์š”.

 

ํ•˜์ง€๋งŒ ์™œ Allini ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋์„๊นŒ์š”?!

์ €ํฌ ๊ฐ€์กฑ์˜ ์†Œ์ค‘ํ•œ ๋ฉค๋ฒ„์ด์ž ๋งˆ์Šค์ฝ”ํŠธ์ธ ๋ฐ˜๋ ค๊ฒฌ์˜ ์ด๋ฆ„์€ "๋ฝ€๊ธ€์ด" ์ž…๋‹ˆ๋‹ค. ์ด๋ฆ„ ๊ท€์—ฝ์ฃ ?!

"ํ™”์ดํŠธ ์Šˆ๋‚˜์šฐ์ €"๋ผ๋Š” ๊ฒฌ์ข…์ด์—์š”.

 

์Šˆ๋‚˜์šฐ์ €๋Š” ์œ ์ „์ ์œผ๋กœ ํ”ผ๋ถ€์งˆํ™˜์ด ์žˆ๋Š” ํŽธ์ž…๋‹ˆ๋‹ค.

๋ฝ€๊ธ€์ด์˜ ๊ฒฝ์šฐ์—” ์•Œ๋ ˆ๋ฅด๊ธฐ์„ฑ ํ”ผ๋ถ€์—ผ์ด๋‚˜ ์‹์ด ์•Œ๋ ˆ๋ฅด๊ธฐ๋กœ ์ธํ•œ ํ”ผ๋ถ€ ๋‘๋“œ๋Ÿฌ๊ธฐ, ๊ฐ„์ง€๋Ÿฌ์›€ ๋“ฑ ํ™˜๊ฒฝ๊ณผ ์‹์ด์˜ ๋ฌธ์ œ๊ฐ€ ๊ฐ€์žฅ ์‹ฌํ–ˆ์–ด์š”.

์‹์ด ์•Œ๋ ˆ๋ฅด๊ธฐ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ์‚ฌ๋ฃŒ์™€ ๊ฐ„์‹์„ ์ œํ•œํ•˜๊ณ  ๋™๋ฌผ ๋ณ‘์›์—์„œ ์ฒ˜๋ฐฉ๋ฐ›์€ ์ฒ˜๋ฐฉ ์‚ฌ๋ฃŒ๋ฅผ ๊ธ‰์—ฌํ•˜๊ณ  ๊ฐ„์‹์„ ์ œํ•œํ•˜๊ณ  ์–ด๋–ค ์žฌ๋ฃŒ์— ์•Œ๋ ˆ๋ฅด๊ธฐ๊ฐ€ ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌ๋ฅผ ํ•ด์„œ ๊ทธ ์žฌ๋ฃŒ๋ฅผ ํ”ผํ•˜๋ฉด ์‹์ด ์•Œ๋ ˆ๋ฅด๊ธฐ๋Š” ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  ํ”ผ๋ถ€ ์งˆํ™˜์ด ๊ฑฐ์˜ ์—†๋Š” ๊ฐœ์ฒด๋„ ์žˆ์–ด์š”! 

 

ํ•˜์ง€๋งŒ ์‚ฌ๋žŒ๋„ ๊ฐ•์•„์ง€๋„, ์‚ด์•„๊ฐ€๋ฉฐ ๋ณธ์ธ์—๊ฒŒ ์žˆ๋Š” ์•Œ๋ ˆ๋ฅด๊ธฐ๊ฐ€ ๊ณ„์† ๋ฐ”๋€๋‹ค๋Š” ์‚ฌ์‹ค ์•Œ๊ณ  ๊ณ„์…จ๋‚˜์š”?!

์ž์ฃผ ๋จน๋Š” ์Œ์‹์ด ์•Œ๋ ˆ๋ฅด๊ธฐ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์–ด ๋‹น์žฅ์€ ๊ดœ์ฐฎ์•„๋„ ์–ธ์ œ๋“ ์ง€ ๋‹ค๋ฅธ ์Œ์‹์— ์•Œ๋ ˆ๋ฅด๊ธฐ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑฐ์˜ˆ์š”!

์ €๋Š” ์ƒˆ์šฐ ์•Œ๋ ˆ๋ฅด๊ธฐ๊ฐ€ ์‹ฌํ–ˆ์ง€๋งŒ ์ด์ œ๋Š” ๋‹ค ์‚ฌ๋ผ์กŒ๊ณ , ๋ฝ€๊ธ€์ด๋Š” ๋‹น๊ทผ ์•Œ๋ ˆ๋ฅด๊ธฐ๊ฐ€ ์‹ฌํ–ˆ์ง€๋งŒ ์ง€๊ธˆ์€ ์ „ํ˜€ ๋‹ค๋ฅธ ์Œ์‹์— ์•Œ๋ ˆ๋ฅด๊ธฐ๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ ํ”ผ๋ถ€๋ฌธ์ œ๋กœ ๋ณ‘์›์— ๋ฐฉ๋ฌธ ์‹œ, ํ•ญ์ƒ ์•„๋ž˜์™€๊ฐ™์€ ์งˆ๋ฌธ๋“ค์„ ๋ฐ›์•˜์–ด์š”.

์˜ค๋Š˜์€ ๋ญ˜ ๋จน์˜€๋‚˜์š”? ์–ด์ œ๋Š”? ์ด๋ฒˆ ์ฃผ๋Š” ๋ฌด์—‡์„ ๊ฐ€์žฅ ๋งŽ์ด ๋จน์˜€์ฃ ? ์ด๋ฒˆ ๋‹ฌ์—๋Š” ์–ด๋–ค ์Œ์‹์„ ๊ฐ€์žฅ ๋งŽ์ด ๋จน์˜€์ฃ ? ๋ญ๋ฅผ ๋จน์˜€์„๋•Œ ์–ด๋–ค ์ฆ์ƒ์ด ์‹ฌํ•ด์กŒ์ฃ ? ์ด์ „์— ์•Œ๋ ˆ๋ฅด๊ธฐ๊ฐ€ ์žˆ๋˜ ์Œ์‹๋“ค์€ ์š”์ฆ˜ ๊ดœ์ฐฎ๋‚˜์š”? (์˜์–‘์„ ์œ„ํ•ด ์†Œ๋Ÿ‰ ๊ธ‰์—ฌํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ์–ด์š”!)

์ด๋Ÿฐ ์‹์œผ๋กœ ์ €์—๊ฒŒ ์งˆ๋ฌธ์ด ์˜ฌ๋•Œ๋งˆ๋‹ค ํ—ท๊ฐˆ๋ฆฌ๋”๋ผ๊ณ ์š”..!

๋”ฑ ์ •ํ•ด์ง„ ๊ฒŒ ์•„๋‹ˆ๋ผ ๊ณ„์† ๋ฐ”๋€Œ๋Š” ๊ฑฐ๋‹ˆ๊นŒ์š”! ๊ทธ๋ž˜์„œ ์ด ๋ชจ๋“  ๊ฑธ ์ตœ๋Œ€ํ•œ ํŽธํ•˜๊ฒŒ ๊ธฐ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ณ ์ž ๊ฒฐ์‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค!

ํ”„๋กœ์ ํŠธ์˜ 1์ฐจ ๋ชฉํ‘œ!!

์ด ํ”„๋กœ์ ํŠธ๋Š” ์šฐ๋ฆฌ ๋ฐ˜๋ ค๊ฒฌ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋‹ค๋ฅธ ๋ฐ˜๋ ค๊ฒฌ ์ฃผ์ธ๋“ค์—๊ฒŒ๋„ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค๊ณ ์ž ํ•ด์š”.
๋””์ž์ด๋„ˆ๋‹˜๊ณผ ํ˜‘์—…ํ•˜์—ฌ ๊ฐ„ํŽธํ•˜๊ณ  ํšจ๊ณผ์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐ˜๋ ค๊ฒฌ์˜ ์Œ์‹ ์„ญ์ทจ๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” UI / UX๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฅผ ํ†ตํ•ด ์Œ์‹ ์•Œ๋ ˆ๋ฅด๊ธฐ์˜ ์›์ธ์„ ํŒŒ์•…ํ•˜๊ณ , ๋ฐ˜๋ ค๊ฒฌ์˜ ๊ฑด๊ฐ•์„ ์ง€์†์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

๊ฐœ๋ฐœ ๋ธ”๋กœ๊ทธ์ธ๋งŒํผ ์ €์˜ ์ฝ”๋“œ์™€ ๊ฒฝํ—˜์„ ๊ณต์œ ํ•  ์˜ˆ์ •์ด์—์š”! 

ํ”„๋กœ์ ํŠธ ์ž์ฒด์˜ ์ทจ์ง€๋„ ์žŠ์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ๋ฐ˜๋ ค๊ฒฌ ์ฃผ์ธ๋“ค๊ณผ ์†Œํ†ตํ•˜๋ฉฐ, ํ•จ๊ป˜ ๊ฑด๊ฐ•ํ•œ ๋ฐ˜๋ ค๊ฒฌ ์ƒํ™œ์„ ์ง€ํ–ฅํ•  ์ƒ๊ฐ์ž…๋‹ˆ๋‹ค! 

๊ทธ๋Ÿฌ๋‹ˆ ์ด ํ”„๋กœ์ ํŠธ์— ๋งŽ์€ ๊ด€์‹ฌ๊ณผ ์ฐธ์—ฌ๋ฅผ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

์• ์ •์ด ๋‹ด๊ธด ์ฝ”๋“œ๋กœ ๊พธ์ค€ํžˆ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐœ์ „์‹œ์ผœ, ํ•จ๊ป˜ ๋ฐ˜๋ ค๊ฒฌ๋“ค์˜ ๊ฑด๊ฐ•์„ ์ง€ํ‚ค๊ณ  ํ–‰๋ณตํ•œ ์‹œ๊ฐ„์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค.

ํ•จ๊ป˜ํ•ด์š”! ๐Ÿพ

 

๐Ÿ“ƒ ์ฐธ๊ณ  ๋ฌธํ—Œ  
[Irina] ์Šˆ๋‚˜์šฐ์ € ์„ฑ๊ฒฉ, ์œ ์ „๋ณ‘, ์ง‘์—์„œ ํ‚ค์šฐ๊ธฐ ์ข‹์€ ๊ฐ•์•„์ง€

 

์ˆ˜๋ฃŒ ํ›„์—๋„ ๊ณ„์†๋˜๋Š” ๋‚˜์˜ ํ”„๋กœ์ ํŠธ!

๋ฉ˜ํ† ๋ง์„ ์‹œ์ž‘ํ•˜๊ฒŒ ๋œ ๊ณ„๊ธฐ

ํšŒ์‚ฌ์— ์ž…์‚ฌ ํ›„ ์‚ฌ์ˆ˜ ์—†๋Š” ํ™˜๊ฒฝ์—์„œ ํ˜ผ์ž ๊ฐœ๋ฐœ์— ์ž„ํ•˜๋ฉฐ ํฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์ง„ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธฐ์ง€ ์•Š์•˜๋˜ ๊ฑด ์ œ๊ฐ€ ์ž˜ํ•ด์„œ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์ด ์‹ฌํ”Œํ•ด์„œ ๊ทธ๋žฌ๋˜ ๊ฑฐ๋ผ ์ƒ๊ฐ๋๊ณ ,

์กฐ๊ธˆ ๋” ๋‹ค์–‘ํ•œ ์Šคํƒ์ด๋‚˜ ํ™˜๊ฒฝ์—์„œ ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ๋“ค์˜ ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. 

๊ทธ๋ ‡๊ฒŒ ์žฌ์ง ์ค‘ F-Lab ๋ฉ˜ํ† ๋ง์„ ์‹ ์ฒญํ•˜๊ฒŒ ๋˜์—ˆ์–ด์š”!

๋ฉ˜ํ† ๋ง์„ ์ง„ํ–‰ํ•˜๊ธฐ ์ „๊ณผ ๋น„๊ตํ–ˆ์„ ๋•Œ ๋‚˜๋Š” ์–ด๋–ป๊ฒŒ ๋ณ€ํ–ˆ๋Š”๊ฐ€?

๋ฉ˜ํ† ๋ง์„ ์‹œ์ž‘ํ•œ ์ดํ›„ ๊ณต์‹ ๋ฌธ์„œ์— ์ ‘๊ทผํ•  ๋•Œ ๋А๋ผ๋Š” ์ €ํ•ญ๊ฐ๊ณผ ๋ถˆ์•ˆ๊ฐ์ด ๋ˆˆ์— ๋„๊ฒŒ ์ค„์–ด๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋…์„œ์˜ ์ฆ๊ฑฐ์›€์„ ์ฐพ๋Š” ์ชฝ์œผ๋กœ ๋ณ€ํ™”๊ฐ€ ์ผ์–ด๋‚ฌ์–ด์š”! ํ˜„์žฌ ์ƒํ™ฉ์—์„œ๋งŒํผ์€ ๋ฌธ์ œ ํ•ด๊ฒฐ์— ๋Œ€ํ•œ ๋” ๋น ๋ฅธ ๊ธธ์„ ์ œ๊ณตํ•˜๋Š” ๋ธ”๋กœ๊ทธ๋‚˜ ์œ ํŠœ๋ธŒ ์˜์ƒ์—์„œ ์ •๋ณด๋ฅผ ์–ป์œผ๋ ค๋Š” ๊ฒฝํ–ฅ์ด ๊ฐ•ํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฝ์œผ๋ ค๋ฉด ๊ฐœ์ธ์ ์ธ ํ•ด์„์ด ํ•„์š”ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฝ๋‹ค๋Š” ์ธ์‹์ด ์žˆ์—ˆ์–ด์š”. ๋ฉ˜ํ† ๋ง์„ ๊ฑฐ์น˜๋ฉฐ ์ด๋Ÿฌํ•œ ์‚ฌ๊ณ ๋ฐฉ์‹์ด ๋ฐ”๋€Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ณต์‹ ๋ฌธ์„œ ํ•ด์„ ๋Šฅ๋ ฅ์ด ํ–ฅ์ƒ๋˜๋ฉด์„œ ๋ถˆ์•ˆ๊ฐ์€ ์ค„์–ด๋“ค์—ˆ๊ณ , ๊ธ€์„ ํ•ด์„ํ•˜๋Š” ๋Šฅ๋ ฅ๊ณผ ์ฆ๊ฑฐ์›€๋„ ์ปค์กŒ์Šต๋‹ˆ๋‹ค

์–ด๋–ค ํšŒ์‚ฌ๋ฅผ ์ง€์›ํ•˜๊ณ  ์‹ถ์€๊ฐ€?

์ž์œ ๋กญ๊ฒŒ ์˜๊ฒฌ์„ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํšŒ์‚ฌ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์š”! ๋ฉ˜ํ† ๋‹˜๊ป˜ ๋‹น๊ทผ ๋งˆ์ผ“์—์„œ ๊ฒช์œผ์‹  ์—ฌ๋Ÿฌ ๊ฒฝํ—˜์„ ๋“ค์œผ๋ฉฐ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์ด ์„ฑ์žฅ์— ์ •๋ง ์ค‘์š”ํ•˜๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค!

ํ”„๋กœ์ ํŠธ ํ€„๋ฆฌํ‹ฐ์— ๋Œ€ํ•œ ๋งŒ์กฑ๋„๋Š” ์–ด๋• ๋Š”๊ฐ€? ์–ด๋–ค ๊ฒƒ์ด ์ข‹์•˜์—ˆ๋Š”๊ฐ€? ์ƒˆ๋กœ์šด ๊ฒƒ๋“ค์€ ๋ฌด์—‡์„ ๊ฒฝํ—˜ํ–ˆ๋Š”๊ฐ€?

๋ฉ˜ํ† ๋ง์ „ ๊ฒฝํ—˜ํ•ด์˜จ ๊ฐœ๋ฐœ๊ณผ ๋น„๊ตํ–ˆ์„ ๋•Œ, ํ”„๋กœ์ ํŠธ์˜ ํ€„๋ฆฌํ‹ฐ๋Š” ๊ฝค ๋งŒ์กฑ์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค!
๋””์ž์ธ ์‹œ์•ˆ์ด ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ์ ์ด๋‚˜ ๊ฐœ๋ฐœ์ž ๊ฒฝํ—˜์„ ๊ณ ๋ คํ•˜์—ฌ Headless UI๋ฅผ ์ ์šฉํ•œ๋‹ค๋˜๊ฐ€, ์‚ฌ์šฉ์ž๋“ค์ด ์‚ฌ์ดํŠธ์˜ ๋งˆ์ง€๋ง‰ ๊ฒฝํ—˜์„ ๋” ์ค‘์š”ํ•˜๊ฒŒ ์ƒ๊ฐํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋ผ ๋‹ค์–‘ํ•œ ์˜ค๋ฅ˜ ํŽ˜์ด์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•ด ๋ดค์–ด์š”. ์ด๋ ‡๊ฒŒ ์ƒ๊ฐํ•ด ๋ณธ ์ ์ด ์—†๋Š” ๋งŽ์€ ๊ฒƒ๋“ค์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•ด ๋ณด์•˜๋‹ค๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ์ •๋ง ๋งŒ์กฑ์Šค๋Ÿฌ์› ์Šต๋‹ˆ๋‹ค!

๋ฉ˜ํ† ๋ง์˜ ์žฅ์ ๊ณผ ๋‹จ์ 

์ฃผ๋กœ ํ˜ผ์ž์„œ ๊ฐœ๋ฐœ์— ์ฐธ์—ฌํ•˜๋‹ค๋ณด๋‹ˆ ์†Œํ†ต๊ณผ ํ˜‘์—…์— ๋Œ€ํ•œ ๊ฐˆ์ฆ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ํ•ด์†Œํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒŒ ๊ฐ€์žฅ ํฐ ์žฅ์ ์ด์—ˆ์–ด์š”!
๋ฉ˜ํ† ๋ง์„ ์ž˜๋ชป ์ด์šฉํ•œ๋‹ค๋ฉด ๋” ์ˆ™๋ ฅ๋œ ๋ฉ˜ํ† ๋‹˜์—๊ฒŒ ๊ณผ๋„ํ•˜๊ฒŒ ์˜์กดํ•˜๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ, ์ ์ ˆํ•œ ์ˆœ๊ฐ„์— ์ปคํŠธ๋ฅผ ํ•ด์ฃผ์…”์„œ ์˜คํžˆ๋ ค ๊ฐ€์ ธ๋ณธ ์  ์—†๋Š” ์‚ฌ์ˆ˜์—๊ฒŒ ์ง€์ผœ์•ผ ํ•  ์„  ๊ฐ™์€ ๊ฑธ ๋ถ„๋ณ„ํ•˜๋Š” ๋ฒ•์„ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค!
์ด๋Ÿฌํ•œ ๊ฒฝํ—˜๋“ค์€ ์‚ฌ์†Œํ•˜๊ฒŒ ๋ฉด์ ‘์—์„œ์กฐ์ฐจ๋„ ์ €์˜ ๊ฒฝํ—˜์ด๋‚˜ ๋ฐฐ๊ฒฝ์ง€์‹์˜ ์ „๋‹ฌ์„ ์œ„ํ•ด ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜ ์Šคํ‚ฌ์ด ์ •๋ง ์ค‘์š”ํ•˜๋‹จ ๊ฑธ ๋‹ค์‹œ ํ•œ๋ฒˆ ๋А๋ผ๊ฒŒ ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.
๋น ๋ฅด๊ฒŒ ๊ฐœ๋ฐœํ•˜๋Š” ๊ฒƒ๋งŒ์„ ๊ณ ๋ฏผํ•˜๋˜ ์ง€๊ธˆ๊นŒ์ง€์˜ ์Šต๊ด€๋“ค ํƒ“์— ๋ฉ˜ํ† ๋‹˜์˜ ์ฝ”๋“œ ๋ฆฌ๋ทฐ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ ๊ณ ๋ฏผ ์‹œ๊ฐ„์ด ๊ธธ์–ด์กŒ๊ณ  ๊ทธ๋ ‡๊ธฐ์— ํ”„๋กœ์ ํŠธ ์ง„ํ–‰๋„์— ๋Œ€ํ•œ ๋งŒ์กฑ๋„๋Š” ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฉ˜ํ† ๋ง์€ ๋๋‚ฌ์ง€๋งŒ, ์ƒˆ๋กœ์šด ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค๊ณ  ํ•ด๋„ ๋ฝ€๊ธ€์ด(์šฐ๋ฆฌ ๊ฐ•์•„์ง€..!)๋ฅผ ์œ„ํ•ด ๋งŒ๋“ค๊ธฐ ์‹œ์ž‘ํ•œ ์ด ํ”„๋กœ์ ํŠธ๋งŒํผ์€ ๋๊นŒ์ง€ ์™„์„ฑ์‹œํ‚ค๊ณ  ์‹ถ์–ด์กŒ์–ด์š”!

๋ฉ˜ํ† ๋ง์— ๋Œ€ํ•œ ์ž์œ ๋กœ์šด ํ›„๊ธฐ

๊ฐœ๋ฐœ์— ๋Œ€ํ•œ ๊ด€์ ์— ๋งŽ์€ ๋ณ€ํ™”๋ฅผ ๊ฒช์—ˆ์Šต๋‹ˆ๋‹ค.
์ด์ „์—๋Š” ๊ฐœ๋ฐœ์— ์žˆ์–ด ๊ธฐ์ˆ ๊ณผ ๋ฐฐ๊ฒฝ์ง€์‹์ด ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค๊ณ  ๋ฏฟ์—ˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ด์ œ๋Š” '๊ธฐ์ˆ ์€ ๊ธฐ์ˆ ์ผ ๋ฟ, ํ•„์š”์— ๋”ฐ๋ผ ๋ฐฐ์šฐ๊ณ  ์ ์šฉํ•˜๋ฉด ๋œ๋‹ค. ๋ชจ๋“  ๊ฒƒ์„ ์„ ์ œ์ ์œผ๋กœ ๋งˆ์Šคํ„ฐํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์ค‘์š”ํ•œ ๋ถ€๋ถ„์„ ๊ฐ„๊ณผํ•  ์ˆ˜๋„ ์žˆ๋‹ค'๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. ์ด์ „์—๋„ ์ƒ๊ฐ์€ ํ–ˆ๋˜ ๋ฌธ์žฅ์ด์ง€๋งŒ ์ด๋ฅผ ์‹ค์ฒœํ•˜๋Š” ๊ฑด ์ƒ๋‹นํžˆ ์–ด๋ ค์šด ์ผ์ด์—ˆ์–ด์š”.

๋ฉ˜ํ† ๋ง์„ ๊ฒช์œผ๋ฉฐ ๋งŽ์€ ๋ฌธ์ œ์ƒํ™ฉ๊ณผ ํƒ€์ž„ ์–ดํƒ.. ์„ ๊ฒช์—ˆ๊ณ  ์ด๋•Œ ์ง„์ •์œผ๋กœ ๋„์›€์ด ๋๋˜ ๊ฑด ์–•์€ ์ง€์‹๋“ค์ด ์•„๋‹Œ ๊นŠ๊ฒŒ ๊ณ ๋ฏผํ•˜๊ณ  ํŒŒ๊ณ ๋“ค์—ˆ๋˜ ์Šต๊ด€๋“ค์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝํ—˜๋“ค์„ ๊ฒช์œผ๋ฉฐ ์„œ์„œํžˆ ๊ณต๋ถ€์Šต๊ด€๋“ค๊ณผ ๊ด€์ ์ด ๋ฐ”๋€Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!
์ด๋Ÿฐ ๊ฒฝํ—˜๋“ค์„ ํ•˜๊ฒŒ ํ•ด์ฃผ์‹  ๋ฉ˜ํ† ๋‹˜๊ป˜ ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

'Education > F-Lab' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

F-Lab Frontend 3๊ฐœ์›” ํ›„๊ธฐ  (0) 2024.03.29
F-Lab Frontend 2๊ฐœ์›” ํ›„๊ธฐ  (0) 2024.03.29
F-Lab Frontend 1๊ฐœ์›” ํ›„๊ธฐ  (0) 2024.03.29

๋“œ๋””์–ด ์‹œ์ž‘ํ•œ ๋‚˜๋งŒ์˜ ํ”„๋กœ์ ํŠธ ์•Œ๋ฆฌ๋‹ˆ!

ํ˜„์žฌ๊นŒ์ง€ ๋ฌด์—‡์„ ๋ฐฐ์› ๋Š”๊ฐ€

TypeScript, React.js, AWS, Bundler, CI/CD, TDD ๋“ฑ์„ ํ•™์Šตํ–ˆ์Šต๋‹ˆ๋‹ค.

์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์„ ๊ตฌํ˜„ํ•œ๋‹ค๋˜๊ฐ€..

"Suspense ๊ธฐ๋Šฅ์„ ์Šคํ…Œ์ด๋ธ”๋กœ ์ถœ์‹œํ–ˆ๋Š”๋ฐ ์ด๋Ÿฐ ๊ฑด ์™œ ๋งŒ๋“ค์—ˆ์„๊นŒ?" ๋˜๋Š” "์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์™œ ๋งŒ๋“ค์—ˆ์„๊นŒ?",

"JSX๋Š” ์™œ ๋งŒ๋“ค์—ˆ์„๊นŒ?",

"์„ ์–ธ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ž€ ๋ฌด์—‡์ผ๊นŒ?",

"์™œ setState๋ฅผ ๋น„๋™๊ธฐ๋กœ ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ์„๊นŒ?",

"์™œ ํ›…์ด๋ผ๋Š” ๊ฐœ๋…์€ ์ƒ๊ฒผ์ง€?",

"key๋Š” ์™œ ๋„ฃ์–ด์ฃผ๊ฒŒ ํ–ˆ์„๊นŒ?" ์ฒ˜๋Ÿผ ์‚ฌ์šฉ๋ฒ• ๋ฟ๋งŒ์ด ์•„๋‹ˆ๋ผ ๋ฆฌ์•กํŠธ ํŒ€์˜ ์ฒ ํ•™ ์ธก๋ฉด์œผ๋กœ๋„ ๊ณ ๋ฏผ์„ ํ•ด๋ณผ ์ˆ˜ ์žˆ๋Š” ์‹œ๊ฐ„์ด์—ˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ์ง„ํ–‰์€ ์–ด๋–ป๊ฒŒ ๋˜๊ณ  ์žˆ๋Š”๊ฐ€

์นœํ•œ ๋””์ž์ด๋„ˆ๋‹˜๊ณผ ํ˜‘์—…์„ ํ•˜๊ฒŒ ๋์Šต๋‹ˆ๋‹ค!
ํ˜„์žฌ ํšŒ์‚ฌ๋ฅผ ๋‹ค๋‹ˆ๋Š” ๋ถ„์ด๊ณ , F-Lab ๋ฉ˜ํ† ๋ง์„ ํ•˜๊ณ  ๊ณ„์‹  ๋ถ„์€ ์•„๋‹ˆ์…”์„œ ํ”„๋กœ์ ํŠธ ๊ธฐํ•œ์„ ์ •ํ•˜๊ธฐ๊ฐ€ ํž˜๋“ค์—ˆ์–ด์š”!

๊ธฐํš์ด ์—†๋˜ ์ ์€ ์žˆ์–ด๋„ ์™„์„ฑ๋œ ๋””์ž์ธ ์—†์ด ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•ด ๋ณด๋Š” ๊ฒŒ ์ฒ˜์Œ์ด๋ผ ๋งŽ์€ ๊ณ ๋ฏผ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค!

๊ณ ๋ฏผ์˜ ๊ฒฐ๊ณผ ๊ธฐ๋ณธ์ ์ธ ํ”„๋กœ์ ํŠธ ์„ธํŒ…(CRA ์—†์ด), ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค ๊ตฌ์ถ•, ๋ฐ˜๋“œ์‹œ ๋“ค์–ด๊ฐ€๊ฒŒ ๋  ๊ฒ€์ƒ‰ ์ปดํฌ๋„ŒํŠธ์˜ ๊ธฐ๋Šฅ ๋“ฑ ๋””์ž์ธ๊ณผ ์ƒ๊ด€์—†์ด ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค๋ถ€ํ„ฐ ์ง„ํ–‰ํ•˜๊ฒŒ ๋์–ด์š”!

์ด์ „์— ๊ฒฝํ—˜ํ–ˆ๋˜ ํ”„๋กœ์ ํŠธ์™€ ๋ฌด์—‡๋“ค์ด ๋‹ค๋ฅธ๊ฐ€?

์œ„์— ์ ์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋””์ž์ธ ์‹œ์•ˆ ์—†์ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•ด ๋ณธ ๊ฑด ์ฒ˜์Œ์ด์—ˆ์–ด์š”!

์‚ฌ์†Œํ•œ ์ฐจ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ์ด๊ฒƒ๋งŒ์œผ๋กœ๋„ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋ฅผ ์žก๊ธฐ ์ •๋ง ํž˜๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.
๋””์ž์ธ์— ๋”ฐ๋ผ ํŽ˜์ด์ง€๊ฐ€ ๋ฐ”๋€” ์ˆ˜๋„ ์žˆ๋Š” ์ƒํ™ฉ์ด๋ผ ํŒ๋‹จํ–ˆ์—ˆ์–ด์š”..!

๊ทธ๋ž˜์„œ ์ตœ๋Œ€ํ•œ ์œ ์—ฐํ•œ ๋ณ€๊ฒฝ์„ ์œ„ํ•ด ๊ทธ๋ฆฌ๊ณ  ๋””์ž์ด๋„ˆ๋‹˜๊ณผ์˜ ์†Œํ†ต์„ ์œ„ํ•ด Headless UI,
Compound Component, Storybook ๋“ฑ ์ฒ˜์Œ ์ ‘ํ•˜๋Š” ์—ฌ๋Ÿฌ ๊ฐœ๋…์„ ํ•™์Šตํ•˜๊ณ  ์ ์šฉํ•ด ๋ณด๊ฒŒ ๋์—ˆ๋„ค์š”!

๋‚ด๊ฐ€ ์ž˜๋ชป ์•Œ๊ณ ์žˆ์—ˆ๋˜ ๊ฒƒ์„ ๋ฐ”๋กœ ์žก์€ ๊ฒƒ์ด ์žˆ๋Š”๊ฐ€

์ž˜๋ชป ์•Œ๊ณ  ์žˆ๋˜ ๊ฐœ๋…์ด๋ผ๊ธฐ๋ณด๋‹ค๋Š”, ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹์ด ๋ณต์žกํ•ด์ง€๋Š” ๊ฒƒ์ด ์ˆ˜์ต ๋ชจ๋ธ ๊ฒ€์ฆ ๋‹จ๊ณ„์—์„œ๋Š” ์ข‹์ง€ ์•Š๋‹ค๋Š” ์„ ์ž…๊ฒฌ์„ ๊นจ๋Š” ๊ณ„๊ธฐ๊ฐ€ ๋์Šต๋‹ˆ๋‹ค.

 

์ดˆ๊ธฐ ๋น„์šฉ์ด ํฌ์ง€๋งŒ, ์ถ”ํ›„ ์œ ์ง€ ๋ณด์ˆ˜ ๊ธฐ๊ฐ„์„ ๋‹จ์ถ•์‹œ์ผœ์ฃผ๋Š” TDD์™€ ์œ ์‚ฌํ•˜๊ฒŒ, ํ—ค๋“œ๋ฆฌ์Šค ์ปดํฌ๋„ŒํŠธ์™€ ํ•ฉ์„ฑ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํŠน์ • UI๋ฅผ ๊ทœ์ •ํ•˜์ง€ ์•Š๊ณ , ๋กœ์ง๊ณผ ์ƒํƒœ ๊ด€๋ฆฌ๋งŒ์„ ์ „์ ์œผ๋กœ ์ฑ…์ž„์ง€๊ฒŒ ๋งŒ๋“ค๋ ค ๋…ธ๋ ฅํ•˜๋Š” ๊ณผ์ •์—์„œ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์€ ํ™•์žฅ์„ฑ์ด ๋›ฐ์–ด๋‚˜๊ณ  ์ด๋ฅผ ํ†ตํ•ด ์‹œ๊ฐ์  ํ‘œํ˜„์„ ์ถ”ํ›„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋งก๊ธธ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒŒ(์—ฌ๊ธฐ์„  ๋ฏธ๋ž˜์˜ ์ €๊ฒ ์ฃ ?!) ๋น ๋ฅธ ๊ฐœ๋ฐœ์„ ํ•˜๊ธฐ์— ์ •๋ง ๋“ ๋“ ํ•˜๋‹จ ๊ฑธ ๋А๊ผˆ์–ด์š”.

๋ฉ˜ํ† ๋‹˜์˜ ์‹ค๋ ฅ์— ๋Œ€ํ•œ ๋งŒ์กฑ๋„๋Š” ์–ด๋– ํ•œ๊ฐ€

์ตœ๊ณ ์ž…๋‹ˆ๋‹ค! ์ •๋ง ๋งŒ์กฑ์Šค๋Ÿฌ์›Œ์š”!
์œ„์—๋Š” ๋ค๋คํ•˜๊ฒŒ ์ ์—ˆ์ง€๋งŒ ์ž‘์—…์ˆœ์„œ์— ๋Œ€ํ•ด ๋งŽ์€ ๊ณ ๋ฏผ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋•Œ๋งˆ๋‹ค ๋ฐฉํ–ฅ์„ฑ์„ ์žƒ์ง€ ์•Š๋„๋ก ์žก์•„์ฃผ์…จ์–ด์š”.

์ ์ ˆํ•œ ํƒ€์ด๋ฐ์— ์ ์ ˆํ•œ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋˜ํ•œ ํšŒ์‚ฌ๋ฅผ ๋‹ค๋‹ˆ๋ฉฐ ๋ฉ˜ํ† ๋ง์„ ๋ฐ›๋Š” ์ œ๊ฐ€ ์ง€์น˜์ง€ ์•Š๊ณ  ๋‹ฌ๋ฆด ์ˆ˜ ์žˆ์—ˆ๋˜ ์›๋™๋ ฅ์ด์—ˆ์Šต๋‹ˆ๋‹ค!

์ตœ๊ทผ 1๊ฐœ์›” ๋™์•ˆ ๋ฉ˜ํ† ๋ง์—์„œ ์–ด๋–ค ๊ฒƒ๋“ค์ด ์ข‹์•˜๋Š”๊ฐ€

์ƒˆ๋กœ์šด ์ƒํ™ฉ, ์ƒˆ๋กœ์šด ๊ด€์ ์—์„œ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋Š” ๊ฒŒ ๊ต‰์žฅํžˆ ์žฌ๋ฐŒ์—ˆ์–ด์š”!

๋ฉ˜ํ† ๋‹˜๊ป˜์„œ ์ข…์ข… ๋“ค๋ ค์ฃผ์‹œ๋Š” ๊ฒฝํ—˜ ์ด์•ผ๊ธฐ๋‚˜ ๊ต์–‘ ๊ฐ™์€ ์ด์•ผ๊ธฐ๋“ค ๋˜ํ•œ ๋ฉ˜ํƒˆ์„ ํ™˜๊ธฐ์‹œ์ผœ ์ง‘์ค‘๋ ฅ์„ ๋†’์ด๋Š”๋ฐ ์ •๋ง ํฐ ๋„์›€์ด ๋์Šต๋‹ˆ๋‹ค!

'Education > F-Lab' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

F-Lab Frontend ์ˆ˜๋ฃŒ ํ›„๊ธฐ  (0) 2024.04.18
F-Lab Frontend 2๊ฐœ์›” ํ›„๊ธฐ  (0) 2024.03.29
F-Lab Frontend 1๊ฐœ์›” ํ›„๊ธฐ  (0) 2024.03.29

+ Recent posts