<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>es mio</title>
    <link>https://spaines.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 14 Jul 2026 23:31:38 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>esoesmio</managingEditor>
    <image>
      <title>es mio</title>
      <url>https://tistory1.daumcdn.net/tistory/5837179/attach/51d0531e9bd449f28355bd86a4d616c3</url>
      <link>https://spaines.tistory.com</link>
    </image>
    <item>
      <title>터미널에서 gui 여는법 - open ./</title>
      <link>https://spaines.tistory.com/465</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서&amp;nbsp;gui&amp;nbsp;여는법&amp;nbsp;-&amp;nbsp;open&amp;nbsp;./&lt;/p&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/465</guid>
      <comments>https://spaines.tistory.com/465#entry465comment</comments>
      <pubDate>Tue, 25 Jun 2024 23:24:34 +0900</pubDate>
    </item>
    <item>
      <title>컨트롤러 코드 취약점 오류</title>
      <link>https://spaines.tistory.com/464</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;컨트롤러&amp;nbsp;코드에서&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;여러&amp;nbsp;보안&amp;nbsp;취약점&amp;nbsp;및&amp;nbsp;오류를&amp;nbsp;살펴보고,&amp;nbsp;그&amp;nbsp;예시와&amp;nbsp;예방&amp;nbsp;방법을&amp;nbsp;설명하겠습니다.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;잠재적인&amp;nbsp;보안&amp;nbsp;취약점&amp;nbsp;및&amp;nbsp;오류&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;**Cross-Site&amp;nbsp;Scripting&amp;nbsp;(XSS)**&lt;br /&gt;2.&amp;nbsp;**SQL&amp;nbsp;Injection**&lt;br /&gt;3.&amp;nbsp;**Input&amp;nbsp;Validation&amp;nbsp;부족**&lt;br /&gt;4.&amp;nbsp;**Unauthorized&amp;nbsp;Access**&lt;br /&gt;5.&amp;nbsp;**Data&amp;nbsp;Exposure**&lt;br /&gt;6.&amp;nbsp;**Improper&amp;nbsp;Error&amp;nbsp;Handling**&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;1.&amp;nbsp;Cross-Site&amp;nbsp;Scripting&amp;nbsp;(XSS)&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;사용자가&amp;nbsp;입력한&amp;nbsp;데이터를&amp;nbsp;검증하지&amp;nbsp;않고&amp;nbsp;그대로&amp;nbsp;렌더링할&amp;nbsp;때&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;`description`&amp;nbsp;필드에&amp;nbsp;스크립트를&amp;nbsp;삽입할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&lt;br /&gt;```json&lt;/p&gt;
&lt;pre id=&quot;code_1718720406971&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;description&quot;: &quot;&amp;lt;script&amp;gt;alert('XSS');&amp;lt;/script&amp;gt;&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;이&amp;nbsp;데이터가&amp;nbsp;검증&amp;nbsp;없이&amp;nbsp;렌더링되면,&amp;nbsp;스크립트가&amp;nbsp;실행되어&amp;nbsp;XSS&amp;nbsp;공격이&amp;nbsp;발생합니다.&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;입력&amp;nbsp;데이터&amp;nbsp;검증&amp;nbsp;및&amp;nbsp;이스케이프&amp;nbsp;처리&lt;br /&gt;-&amp;nbsp;서버에서&amp;nbsp;데이터&amp;nbsp;저장&amp;nbsp;전에&amp;nbsp;sanitize&amp;nbsp;처리&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720414530&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sanitizeHtml from 'sanitize-html';

// Sanitize description to prevent XSS
const sanitizedDescription = sanitizeHtml(body.description);
await this.sellersService.changeDescription(sellerId, sanitizedDescription);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;2.&amp;nbsp;SQL&amp;nbsp;Injection&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;사용자&amp;nbsp;입력이&amp;nbsp;직접&amp;nbsp;SQL&amp;nbsp;쿼리에&amp;nbsp;포함될&amp;nbsp;때&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;ORM을&amp;nbsp;사용하면&amp;nbsp;대부분의&amp;nbsp;경우&amp;nbsp;방지할&amp;nbsp;수&amp;nbsp;있지만,&amp;nbsp;직접&amp;nbsp;쿼리를&amp;nbsp;작성할&amp;nbsp;때는&amp;nbsp;주의해야&amp;nbsp;합니다.&lt;br /&gt;&lt;br /&gt;**예시**:&lt;br /&gt;```json&lt;/p&gt;
&lt;pre id=&quot;code_1718720422697&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;sellerId&quot;: &quot;1 OR 1=1&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;파라미터화된&amp;nbsp;쿼리&amp;nbsp;사용&lt;br /&gt;-&amp;nbsp;ORM을&amp;nbsp;사용할&amp;nbsp;경우&amp;nbsp;ORM의&amp;nbsp;보안&amp;nbsp;기능&amp;nbsp;사용&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;ORM을&amp;nbsp;사용하면&amp;nbsp;보통&amp;nbsp;안전하지만,&amp;nbsp;직접&amp;nbsp;쿼리를&amp;nbsp;작성할&amp;nbsp;경우&amp;nbsp;다음과&amp;nbsp;같이&amp;nbsp;작성해야&amp;nbsp;합니다:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720429785&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const seller = await this.sellerRepository.findOne({
  where: { id: sellerId }
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;3.&amp;nbsp;Input&amp;nbsp;Validation&amp;nbsp;부족&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;입력&amp;nbsp;값의&amp;nbsp;유효성을&amp;nbsp;검증하지&amp;nbsp;않으면,&amp;nbsp;예상치&amp;nbsp;못한&amp;nbsp;입력이&amp;nbsp;시스템에&amp;nbsp;영향을&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&lt;br /&gt;-&amp;nbsp;`sellerId`에&amp;nbsp;숫자가&amp;nbsp;아닌&amp;nbsp;값을&amp;nbsp;입력&lt;br /&gt;-&amp;nbsp;`shippingCharge`에&amp;nbsp;음수&amp;nbsp;값을&amp;nbsp;입력&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;DTO(Data&amp;nbsp;Transfer&amp;nbsp;Object)와&amp;nbsp;class-validator를&amp;nbsp;사용하여&amp;nbsp;입력&amp;nbsp;값&amp;nbsp;검증&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720448517&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { IsInt, IsString, IsPositive } from 'class-validator';

class SellerIdParam {
  @IsInt()
  sellerId: number;
}

class ModifyUserRequest {
  @IsString()
  description: string;

  @IsString()
  csPath: string;

  @IsString()
  shippingType: string;

  @IsPositive()
  shippingCharge: number;

  @IsString()
  plan: string;

  @IsArray()
  @IsString({ each: true })
  imageUrls: string[];

  @ValidateNested()
  bankInformation: BankInformation;
}

class BankInformation {
  @IsString()
  bank: string;

  @IsString()
  accountNumber: string;

  @IsString()
  customerName: string;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;4.&amp;nbsp;Unauthorized&amp;nbsp;Access&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;인증되지&amp;nbsp;않은&amp;nbsp;사용자가&amp;nbsp;리소스에&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;인증이&amp;nbsp;필요한&amp;nbsp;엔드포인트에&amp;nbsp;인증&amp;nbsp;없이&amp;nbsp;접근&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;JWT&amp;nbsp;또는&amp;nbsp;OAuth를&amp;nbsp;사용하여&amp;nbsp;인증&amp;nbsp;처리&lt;br /&gt;-&amp;nbsp;권한&amp;nbsp;검사를&amp;nbsp;통해&amp;nbsp;특정&amp;nbsp;사용자만&amp;nbsp;접근&amp;nbsp;가능하도록&amp;nbsp;설정&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720457978&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 인증 및 권한 검사 미들웨어 사용
import { UseGuards } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@UseGuards(AuthGuard('jwt'))
@Patch('update')
async updateSeller(
  @User() user,
  @Body() body: ModifyUserRequest,
  @Param() param: SellerIdParam,
) {
  // ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;5.&amp;nbsp;Data&amp;nbsp;Exposure&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;민감한&amp;nbsp;정보가&amp;nbsp;외부에&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;응답&amp;nbsp;데이터에&amp;nbsp;민감한&amp;nbsp;정보가&amp;nbsp;포함될&amp;nbsp;경우&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;필요하지&amp;nbsp;않은&amp;nbsp;민감한&amp;nbsp;정보는&amp;nbsp;응답에서&amp;nbsp;제외&lt;br /&gt;-&amp;nbsp;데이터&amp;nbsp;전달&amp;nbsp;전에&amp;nbsp;필요한&amp;nbsp;부분만&amp;nbsp;선택적으로&amp;nbsp;전달&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720466086&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const seller = await this.sellersService.findSeller(sellerId);
// 필요한 데이터만 응답
return {
  id: seller.id,
  name: seller.name,
  description: seller.description,
  // 기타 필요한 필드만 포함
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;6.&amp;nbsp;Improper&amp;nbsp;Error&amp;nbsp;Handling&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;에러&amp;nbsp;메시지가&amp;nbsp;너무&amp;nbsp;상세하여&amp;nbsp;공격자에게&amp;nbsp;시스템&amp;nbsp;정보를&amp;nbsp;제공할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;데이터베이스&amp;nbsp;에러&amp;nbsp;메시지를&amp;nbsp;그대로&amp;nbsp;사용자에게&amp;nbsp;전달&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;에러&amp;nbsp;메시지를&amp;nbsp;사용자&amp;nbsp;친화적으로&amp;nbsp;작성&lt;br /&gt;-&amp;nbsp;내부&amp;nbsp;에러&amp;nbsp;메시지를&amp;nbsp;로깅&amp;nbsp;시스템에만&amp;nbsp;기록&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720471816&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;if (!seller) {
  throw new NotFoundException({
    status: HttpStatus.NOT_FOUND,
    error: 'Not Found Seller',
    message: '셀러를 찾을 수 없습니다.',
  });
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;결론&lt;br /&gt;&lt;br /&gt;위에서&amp;nbsp;언급한&amp;nbsp;보안&amp;nbsp;취약점&amp;nbsp;및&amp;nbsp;오류를&amp;nbsp;예방하기&amp;nbsp;위해서는&amp;nbsp;입력&amp;nbsp;데이터의&amp;nbsp;철저한&amp;nbsp;검증,&amp;nbsp;인증&amp;nbsp;및&amp;nbsp;권한&amp;nbsp;검사,&amp;nbsp;민감한&amp;nbsp;정보의&amp;nbsp;보호,&amp;nbsp;그리고&amp;nbsp;적절한&amp;nbsp;에러&amp;nbsp;처리가&amp;nbsp;필요합니다.&amp;nbsp;각&amp;nbsp;예시에&amp;nbsp;대한&amp;nbsp;해결&amp;nbsp;방법을&amp;nbsp;통해&amp;nbsp;보안을&amp;nbsp;강화할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론입니다.&amp;nbsp;더&amp;nbsp;많은&amp;nbsp;보안&amp;nbsp;취약점&amp;nbsp;및&amp;nbsp;오류를&amp;nbsp;포함한&amp;nbsp;예시와&amp;nbsp;그에&amp;nbsp;대한&amp;nbsp;예방&amp;nbsp;방법을&amp;nbsp;추가로&amp;nbsp;설명하겠습니다.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;7.&amp;nbsp;**Mass&amp;nbsp;Assignment**&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;사용자가&amp;nbsp;의도하지&amp;nbsp;않은&amp;nbsp;데이터&amp;nbsp;필드를&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;클라이언트에서&amp;nbsp;전달된&amp;nbsp;데이터가&amp;nbsp;직접적으로&amp;nbsp;객체에&amp;nbsp;할당될&amp;nbsp;때,&amp;nbsp;악의적인&amp;nbsp;사용자가&amp;nbsp;권한이&amp;nbsp;없는&amp;nbsp;필드를&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;DTO(Data&amp;nbsp;Transfer&amp;nbsp;Object)를&amp;nbsp;사용하여&amp;nbsp;변경&amp;nbsp;가능한&amp;nbsp;필드를&amp;nbsp;명시적으로&amp;nbsp;정의&lt;br /&gt;-&amp;nbsp;안전한&amp;nbsp;객체&amp;nbsp;할당&amp;nbsp;방법&amp;nbsp;사용&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720483492&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class UpdateSellerDto {
  @IsString()
  description: string;

  @IsString()
  csPath: string;

  @IsString()
  shippingType: string;

  @IsPositive()
  shippingCharge: number;

  @IsString()
  plan: string;

  @IsArray()
  @IsString({ each: true })
  imageUrls: string[];

  @ValidateNested()
  bankInformation: BankInformation;
}

// 서비스 메서드에서만 DTO를 통해 값을 할당
await this.sellerRepository.update(sellerId, updateSellerDto);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;8.&amp;nbsp;**File&amp;nbsp;Upload&amp;nbsp;Security**&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;파일&amp;nbsp;업로드&amp;nbsp;기능에서&amp;nbsp;악성&amp;nbsp;파일을&amp;nbsp;업로드할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;악의적인&amp;nbsp;사용자가&amp;nbsp;스크립트나&amp;nbsp;바이러스가&amp;nbsp;포함된&amp;nbsp;파일을&amp;nbsp;업로드&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;파일&amp;nbsp;확장자&amp;nbsp;및&amp;nbsp;MIME&amp;nbsp;타입&amp;nbsp;검증&lt;br /&gt;-&amp;nbsp;파일&amp;nbsp;크기&amp;nbsp;제한&lt;br /&gt;-&amp;nbsp;업로드된&amp;nbsp;파일의&amp;nbsp;경로를&amp;nbsp;안전하게&amp;nbsp;처리&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720494272&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { diskStorage } from 'multer';
import { extname } from 'path';

const storage = diskStorage({
  destination: './uploads',
  filename: (req, file, callback) =&amp;gt; {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    callback(null, file.fieldname + '-' + uniqueSuffix + extname(file.originalname));
  },
});

const fileFilter = (req, file, callback) =&amp;gt; {
  if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
    return callback(new Error('Only image files are allowed!'), false);
  }
  callback(null, true);
};

@Controller('upload')
export class UploadController {
  @Post('image')
  @UseInterceptors(FileInterceptor('file', { storage, fileFilter }))
  uploadFile(@UploadedFile() file) {
    // 파일 업로드 처리
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;9.&amp;nbsp;**Rate&amp;nbsp;Limiting**&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;서비스가&amp;nbsp;무차별&amp;nbsp;대입&amp;nbsp;공격&amp;nbsp;또는&amp;nbsp;과도한&amp;nbsp;요청으로&amp;nbsp;인해&amp;nbsp;장애가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;동일한&amp;nbsp;IP에서&amp;nbsp;다수의&amp;nbsp;로그인&amp;nbsp;시도&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;요청&amp;nbsp;횟수&amp;nbsp;제한&amp;nbsp;(Rate&amp;nbsp;Limiting)&lt;br /&gt;-&amp;nbsp;특정&amp;nbsp;시간&amp;nbsp;동안&amp;nbsp;허용된&amp;nbsp;요청&amp;nbsp;횟수를&amp;nbsp;초과하면&amp;nbsp;요청을&amp;nbsp;차단&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720501857&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { Throttle, ThrottlerGuard } from '@nestjs/throttler';
import { UseGuards } from '@nestjs/common';

@Controller('auth')
@UseGuards(ThrottlerGuard)
export class AuthController {
  @Throttle(5, 60) // 1분에 최대 5번 요청 가능
  @Post('login')
  async login(@Body() loginDto: LoginDto) {
    // 로그인 처리
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;10.&amp;nbsp;**CSRF&amp;nbsp;(Cross-Site&amp;nbsp;Request&amp;nbsp;Forgery)**&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;사용자가&amp;nbsp;의도하지&amp;nbsp;않은&amp;nbsp;요청을&amp;nbsp;다른&amp;nbsp;사이트에서&amp;nbsp;보낼&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;악의적인&amp;nbsp;웹사이트에서&amp;nbsp;사용자의&amp;nbsp;인증&amp;nbsp;정보를&amp;nbsp;사용하여&amp;nbsp;요청을&amp;nbsp;보냄&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;CSRF&amp;nbsp;토큰&amp;nbsp;사용&lt;br /&gt;-&amp;nbsp;서버에서&amp;nbsp;요청&amp;nbsp;시마다&amp;nbsp;CSRF&amp;nbsp;토큰을&amp;nbsp;검증&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;br /&gt;import&amp;nbsp;{&amp;nbsp;CsrfModule,&amp;nbsp;CsrfGuard&amp;nbsp;}&amp;nbsp;from&amp;nbsp;'nestjs-csrf';&lt;/p&gt;
&lt;pre id=&quot;code_1718720509618&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { UseGuards } from '@nestjs/common';

@Module({
  imports: [CsrfModule],
})
export class AppModule {}

@Controller('form')
@UseGuards(CsrfGuard)
export class FormController {
  @Post('submit')
  submitForm(@Body() formData: FormData) {
    // 폼 처리
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;11.&amp;nbsp;**Sensitive&amp;nbsp;Data&amp;nbsp;Exposure**&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;로그&amp;nbsp;또는&amp;nbsp;응답에서&amp;nbsp;민감한&amp;nbsp;데이터가&amp;nbsp;노출될&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;비밀번호나&amp;nbsp;신용카드&amp;nbsp;정보가&amp;nbsp;로그에&amp;nbsp;기록됨&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;민감한&amp;nbsp;데이터는&amp;nbsp;절대&amp;nbsp;로그에&amp;nbsp;기록하지&amp;nbsp;않음&lt;br /&gt;-&amp;nbsp;필요&amp;nbsp;시&amp;nbsp;민감한&amp;nbsp;데이터를&amp;nbsp;마스킹&amp;nbsp;처리&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720517965&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class UserDto {
  @Exclude()
  password: string;

  @Expose()
  username: string;

  @Expose()
  email: string;
}

// User 엔티티를 UserDto로 변환하여 응답
const userDto = plainToClass(UserDto, user);
return userDto;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;12.&amp;nbsp;**Insecure&amp;nbsp;Direct&amp;nbsp;Object&amp;nbsp;References&amp;nbsp;(IDOR)**&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;사용자가&amp;nbsp;권한이&amp;nbsp;없는&amp;nbsp;리소스에&amp;nbsp;접근할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;URL에&amp;nbsp;다른&amp;nbsp;사용자의&amp;nbsp;ID를&amp;nbsp;입력하여&amp;nbsp;그&amp;nbsp;사용자의&amp;nbsp;정보에&amp;nbsp;접근&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;접근&amp;nbsp;권한을&amp;nbsp;철저히&amp;nbsp;검증&lt;br /&gt;-&amp;nbsp;사용자의&amp;nbsp;요청에&amp;nbsp;대해&amp;nbsp;권한&amp;nbsp;확인&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720528113&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;async updateSeller(
  @User() user,
  @Body() body: ModifyUserRequest,
  @Param() param: SellerIdParam,
) {
  const sellerId = param.sellerId;
  const detail = await this.sellersService.isExist(sellerId);
  if (!detail || detail.ownerId !== user.id) {
    throw new NotFoundException({
      status: HttpStatus.NOT_FOUND,
      error: 'Not Found Seller',
      message: '셀러를 찾을 수 없거나 접근 권한이 없습니다.',
    });
  }
  // 업데이트 로직
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;13.&amp;nbsp;**Improper&amp;nbsp;Logging**&lt;br /&gt;&lt;br /&gt;**문제**:&amp;nbsp;로그에&amp;nbsp;민감한&amp;nbsp;정보가&amp;nbsp;포함될&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;**예시**:&amp;nbsp;사용자&amp;nbsp;비밀번호,&amp;nbsp;토큰,&amp;nbsp;신용카드&amp;nbsp;정보&amp;nbsp;등이&amp;nbsp;로그에&amp;nbsp;기록&lt;br /&gt;&lt;br /&gt;**예방&amp;nbsp;방법**:&lt;br /&gt;-&amp;nbsp;민감한&amp;nbsp;정보는&amp;nbsp;로그에&amp;nbsp;포함하지&amp;nbsp;않음&lt;br /&gt;-&amp;nbsp;로그&amp;nbsp;레벨을&amp;nbsp;적절히&amp;nbsp;설정&lt;br /&gt;&lt;br /&gt;**코드**:&lt;br /&gt;```typescript&lt;/p&gt;
&lt;pre id=&quot;code_1718720535495&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const sensitiveFields = ['password', 'token', 'creditCard'];
const filteredBody = Object.keys(body)
  .filter(key =&amp;gt; !sensitiveFields.includes(key))
  .reduce((obj, key) =&amp;gt; {
    obj[key] = body[key];
    return obj;
  }, {});

this.logger.log(`Request body: ${JSON.stringify(filteredBody)}`);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;결론&lt;br /&gt;&lt;br /&gt;위에서&amp;nbsp;설명한&amp;nbsp;보안&amp;nbsp;취약점&amp;nbsp;및&amp;nbsp;오류들은&amp;nbsp;실무에서&amp;nbsp;자주&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;문제들입니다.&amp;nbsp;이를&amp;nbsp;예방하기&amp;nbsp;위해서는&amp;nbsp;철저한&amp;nbsp;입력&amp;nbsp;검증,&amp;nbsp;적절한&amp;nbsp;인증&amp;nbsp;및&amp;nbsp;권한&amp;nbsp;검사,&amp;nbsp;민감한&amp;nbsp;정보&amp;nbsp;보호,&amp;nbsp;그리고&amp;nbsp;적절한&amp;nbsp;에러&amp;nbsp;처리가&amp;nbsp;필요합니다.&amp;nbsp;각&amp;nbsp;예시에&amp;nbsp;대한&amp;nbsp;해결&amp;nbsp;방법을&amp;nbsp;통해&amp;nbsp;시스템의&amp;nbsp;보안성을&amp;nbsp;강화할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/464</guid>
      <comments>https://spaines.tistory.com/464#entry464comment</comments>
      <pubDate>Tue, 18 Jun 2024 23:22:20 +0900</pubDate>
    </item>
    <item>
      <title>[javascript] 프로토타입이 무엇인가</title>
      <link>https://spaines.tistory.com/463</link>
      <description>&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-id=&quot;8ad00c78-fff9-4c29-ad3e-f8aef845210f&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토타입은 자바스크립트의 객체 지향 프로그래밍에서 매우 중요한 개념으로, 객체가 다른 객체의 메서드와 속성을 상속받을 수 있게 하는 메커니즘입니다. 이를 이해하기 위해 프로토타입의 정의와 동작 방식, 그리고 실생활 비유와 예제를 통해 설명하겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로토타입의 정의&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로토타입&lt;/b&gt;은 자바스크립트의 모든 객체가 가지고 있는 숨겨진 속성으로, 다른 객체로부터 메서드와 속성을 상속받는 데 사용됩니다. 자바스크립트는 프로토타입 기반 언어로, 클래스 기반 언어와 달리 상속을 구현하기 위해 프로토타입 체인을 사용합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실생활 비유&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토타입을 실생활에 비유하면 이해가 쉬워집니다. 예를 들어, 가구 공장에서 테이블을 만드는 과정을 생각해봅시다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;템플릿(원형)&lt;/b&gt;: 공장에서는 테이블을 만들기 위해 &quot;테이블 템플릿&quot;을 가지고 있습니다. 이 템플릿에는 테이블의 기본 구조와 기능이 정의되어 있습니다. 이 템플릿이 프로토타입이라고 생각할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;개별 테이블&lt;/b&gt;: 이 템플릿을 사용하여 만들어진 각각의 테이블은 개별 객체입니다. 모든 테이블은 템플릿의 특성을 공유하지만, 개별 테이블마다 색상이나 크기와 같은 고유한 특성을 가질 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;상속&lt;/b&gt;: 만약 &quot;책상&quot;이라는 새로운 종류의 테이블을 만든다면, 이 책상은 &quot;테이블 템플릿&quot;을 기반으로 만들되, 추가적으로 서랍이나 책꽂이 같은 기능을 더할 수 있습니다. 이때 책상은 테이블 템플릿의 특성을 상속받아 기본 기능을 유지하면서도 새로운 기능을 추가합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;자바스크립트에서 프로토타입&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트에서 모든 객체는 프로토타입이라는 숨겨진 속성을 가집니다. 이 프로토타입은 객체가 다른 객체의 메서드와 속성을 사용할 수 있게 합니다. 객체의 프로토타입은 [[Prototype]]이라는 내부 프로퍼티로 참조되며, 이는 Object.getPrototypeOf(obj)를 통해 접근할 수 있습니다.'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718202636003&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Bird 생성자 함수
function Bird(name, sound) {
    this.name = name;
    this.sound = sound;
}

// Bird 프로토타입에 메서드 추가
Bird.prototype.fly = function () {
    console.log(`${this.name} ${this.sound} 비행중`);
};

// Eagle 생성자 함수
function Eagle(name, sound, prey) {
    Bird.call(this, name, sound);  // Bird 생성자 호출
    this.prey = prey;
}

// Eagle이 Bird를 상속받도록 설정
Eagle.prototype = Object.create(Bird.prototype);
Eagle.prototype.constructor = Eagle;

// Eagle 프로토타입에 메서드 추가
Eagle.prototype.hunt = function () {
    console.log(`${this.name} ${this.prey} 사냥중`);
};

// 인스턴스 생성
const eagle = new Eagle('독돌이', '푸드덕', '토끼');

// 메서드 호출
eagle.fly();  // 독돌이 푸드덕 비행중
eagle.hunt(); // 독돌이 토끼 사냥중

// 프로토타입 체인 확인
console.log(eagle instanceof Eagle); // true
console.log(eagle instanceof Bird);  // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로토타입 체인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 객체는 프로토타입 체인을 통해 다른 객체의 속성과 메서드를 사용할 수 있습니다. 프로토타입 체인은 객체가 특정 속성이나 메서드를 찾지 못하면, 프로토타입 체인을 따라 상위 객체의 프로토타입에서 해당 속성이나 메서드를 찾는 방식으로 동작합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;예제 설명&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;객체 생성&lt;/b&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1718202658583&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const eagle = new Eagle('독돌이', '푸드덕', '토끼');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Eagle 생성자를 통해 eagle 객체가 생성됩니다. 이 객체는 Eagle의 프로토타입을 통해 Bird의 메서드도 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 메서드 호출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718202720979&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;eagle.fly();  // 독돌이 푸드덕 비행중
eagle.hunt(); // 독돌이 토끼 사냥중&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;eagle.fly()를 호출하면 Eagle의 프로토타입 체인을 따라 Bird.prototype에 있는 fly 메서드가 호출됩니다. eagle.hunt()는 Eagle.prototype에 정의된 메서드를 직접 호출합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 프로토타이 ㅂ체인 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718202749991&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;console.log(eagle instanceof Eagle); // true
console.log(eagle instanceof Bird);  // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;eagle 객체는 Eagle과 Bird의 인스턴스입니다. 이는 Eagle이 Bird를 상속받았기 때문에 가능한 일입니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토타입은 자바스크립트의 객체가 다른 객체의 메서드와 속성을 상속받는 데 사용하는 메커니즘입니다. 이를 통해 객체는 메모리를 절약하고, 공통 기능을 공유하며, 객체 간 상속 관계를 설정할 수 있습니다. 프로토타입 체인은 객체가 특정 속성이나 메서드를 찾을 때 상위 객체의 프로토타입을 따라가는 경로로, 이를 통해 효율적인 코드 재사용과 상속을 구현할 수 있습니다.&lt;/p&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/463</guid>
      <comments>https://spaines.tistory.com/463#entry463comment</comments>
      <pubDate>Wed, 12 Jun 2024 23:32:47 +0900</pubDate>
    </item>
    <item>
      <title>정적바인딩, 동적바인딩</title>
      <link>https://spaines.tistory.com/462</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript의 this 키워드는 함수 호출 방식에 따라 동적으로 바인딩되거나, 특별한 경우에 정적으로 바인딩될 수 있습니다. 이를 이해하기 위해 먼저 동적 바인딩과 정적 바인딩이 무엇인지 살펴보겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;동적 바인딩 (Dynamic Binding)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동적 바인딩은 함수 호출 시점에 this가 결정되는 것을 의미합니다. 이는 JavaScript의 일반적인 함수 호출 방식에서 주로 발생합니다. this는 호출 컨텍스트에 따라 다르게 바인딩될 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;주요 동적 바인딩 예시&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;전역 컨텍스트에서 호출된 함수&lt;/b&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718184865241&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function foo() {
    console.log(this);
}
foo(); // window (브라우저 환경에서) 또는 global (Node.js 환경에서)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 객체의 메서드로 호출된 함수&lt;/b&gt;:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1718184886270&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const obj = {
    name: 'Alice',
    greet: function() {
        console.log(this.name);
    }
};
obj.greet(); // &quot;Alice&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;함수에서 call, apply, bind 메서드를 사용한 경우&lt;/b&gt;:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1718184904140&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function greet() {
    console.log(this.name);
}
const user = { name: 'Bob' };
greet.call(user);  // &quot;Bob&quot;
greet.apply(user); // &quot;Bob&quot;

const boundGreet = greet.bind(user);
boundGreet(); // &quot;Bob&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 생성자함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718184919606&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Person(name) {
    this.name = name;
}
const person = new Person('Charlie');
console.log(person.name); // &quot;Charlie&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;정적 바인딩 (Static Binding)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적 바인딩은 this가 함수 정의 시점에 결정되는 것을 의미합니다. JavaScript에서는 주로 화살표 함수(arrow function)에서 발생합니다. 화살표 함수는 자신만의 this 바인딩을 가지지 않고, 정의될 때의 상위 스코프의 this를 그대로 사용합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;화살표 함수의 정적 바인딩 예시&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;상위 스코프의 this를 사용하는 화살표 함수&lt;/b&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1718184941968&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const obj = {
    name: 'Dave',
    greet: function() {
        const inner = () =&amp;gt; {
            console.log(this.name);
        };
        inner();
    }
};
obj.greet(); // &quot;Dave&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;전역 컨텍스트에서 화살표 함수&lt;/b&gt;:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1718184957087&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const arrowFunc = () =&amp;gt; {
    console.log(this);
};
arrowFunc(); // window (브라우저 환경에서) 또는 global (Node.js 환경에서)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;차이점 요약&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;동적 바인딩&lt;/b&gt;: 함수 호출 방식에 따라 this가 달라짐. 일반적인 함수 및 메서드에서 주로 발생.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;정적 바인딩&lt;/b&gt;: this가 함수 정의 시점에 결정됨. 주로 화살표 함수에서 발생.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예제 코드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동적 바인딩 예제:'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1718184983624&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function dynamicThis() {
    console.log(this);
}

const obj = {
    name: 'Eve',
    dynamicThis: dynamicThis
};

dynamicThis(); // 전역 객체 (window 또는 global)
obj.dynamicThis(); // obj 객체&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정적 바인딩 예제:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1718184997282&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const staticThis = () =&amp;gt; {
    console.log(this);
};

const anotherObj = {
    name: 'Frank',
    staticThis: staticThis
};

staticThis(); // 전역 객체 (window 또는 global)
anotherObj.staticThis(); // 여전히 전역 객체&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div data-message-id=&quot;f187dee3-93ee-4f75-a02a-619f43e2a22f&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 this의 동적 바인딩과 정적 바인딩은 함수가 어떻게 호출되었는지에 따라 달라지며, 특히 화살표 함수는 정의 시점의 상위 스코프의 this를 사용함으로써 정적 바인딩의 특성을 가집니다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/462</guid>
      <comments>https://spaines.tistory.com/462#entry462comment</comments>
      <pubDate>Wed, 12 Jun 2024 18:36:51 +0900</pubDate>
    </item>
    <item>
      <title>[nestJS] nesJS 설명 좋은 블로그</title>
      <link>https://spaines.tistory.com/461</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cdragon.tistory.com/entry/NestJS-1-NestJS%EC%9D%98-%EA%B5%AC%EC%A1%B0-%EB%B0%8F-%EA%B4%80%EB%A0%A8-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC%EB%B0%B1%EC%97%94%EB%93%9C%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cdragon.tistory.com/entry/NestJS-1-NestJS%EC%9D%98-%EA%B5%AC%EC%A1%B0-%EB%B0%8F-%EA%B4%80%EB%A0%A8-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC%EB%B0%B1%EC%97%94%EB%93%9C%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83&lt;/a&gt;&lt;/p&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/461</guid>
      <comments>https://spaines.tistory.com/461#entry461comment</comments>
      <pubDate>Sat, 25 May 2024 16:55:23 +0900</pubDate>
    </item>
    <item>
      <title>[nestJS] 경로파라미터 일반경로 충돌 /seller/search  /seller/:sellerID</title>
      <link>https://spaines.tistory.com/460</link>
      <description>&lt;pre id=&quot;code_1716531269787&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  @ApiOperation({
    summary: &quot;셀러 상세 조회&quot;,
    description: &quot;&quot;
  })
  @Get(&quot;:sellerId&quot;)
  async detail(@User() user, @Param() param: SellerIdParam) {
    const isExist = await this.sellersService.isExist(param.sellerId);
    if (!isExist) {
      throw new NotFoundException({
        status: HttpStatus.NOT_FOUND,&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 위에있고&lt;/p&gt;
&lt;pre id=&quot;code_1716531290718&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  @ApiOperation({
    summary: &quot;특정 셀러 조회&quot;,
    description: &quot;핸드폰 번호 또는 닉네임을 기반으로 특정 셀러 정보를 조회합니다.&quot;
  })
  @Get(&quot;search&quot;)
  async findOne(
    @Query(&quot;information&quot;) information: string
  ) {
    console.log(&quot;wecametoinformation&quot;);
    console.log(&quot;information&quot;, information);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 아래있었을때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sellerID를 안쳤다고 에러가 남. 왜그럴까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/////////////////////////////////////////////////////////////////&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NestJS에서&amp;nbsp;메소드의&amp;nbsp;순서가&amp;nbsp;영향을&amp;nbsp;미치는&amp;nbsp;이유는&amp;nbsp;특히&amp;nbsp;라우팅과&amp;nbsp;관련하여&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;NestJS는&amp;nbsp;데코레이터를&amp;nbsp;사용하여&amp;nbsp;라우트를&amp;nbsp;등록하고,&amp;nbsp;이&amp;nbsp;라우트&amp;nbsp;등록은&amp;nbsp;컨트롤러&amp;nbsp;파일을&amp;nbsp;파싱하는&amp;nbsp;순서대로&amp;nbsp;이루어집니다.&amp;nbsp;따라서&amp;nbsp;메소드의&amp;nbsp;순서가&amp;nbsp;라우트&amp;nbsp;처리&amp;nbsp;순서에&amp;nbsp;영향을&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;경로&amp;nbsp;파라미터와&amp;nbsp;일반&amp;nbsp;경로의&amp;nbsp;충돌&lt;br /&gt;예를&amp;nbsp;들어,&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;두&amp;nbsp;경로가&amp;nbsp;있을&amp;nbsp;때:&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;`@Get(&quot;:sellerId&quot;)`&amp;nbsp;&amp;ndash;&amp;nbsp;동적&amp;nbsp;경로&amp;nbsp;파라미터를&amp;nbsp;포함하는&amp;nbsp;경로&lt;br /&gt;2.&amp;nbsp;`@Get(&quot;search&quot;)`&amp;nbsp;&amp;ndash;&amp;nbsp;고정&amp;nbsp;경로&lt;br /&gt;&lt;br /&gt;만약&amp;nbsp;`@Get(&quot;:sellerId&quot;)`가&amp;nbsp;`@Get(&quot;search&quot;)`보다&amp;nbsp;먼저&amp;nbsp;정의되어&amp;nbsp;있다면,&amp;nbsp;`search`라는&amp;nbsp;문자열도&amp;nbsp;`:sellerId`의&amp;nbsp;파라미터로&amp;nbsp;해석될&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;이는&amp;nbsp;`search`가&amp;nbsp;동적&amp;nbsp;경로&amp;nbsp;파라미터&amp;nbsp;`:sellerId`에&amp;nbsp;해당할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;유효한&amp;nbsp;문자열로&amp;nbsp;인식되기&amp;nbsp;때문입니다.&amp;nbsp;따라서&amp;nbsp;`/sellers/search`&amp;nbsp;경로를&amp;nbsp;호출하면&amp;nbsp;`:sellerId`가&amp;nbsp;`search`로&amp;nbsp;설정된&amp;nbsp;`detail`&amp;nbsp;메소드가&amp;nbsp;호출될&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;문제&amp;nbsp;해결&lt;br /&gt;메소드의&amp;nbsp;순서를&amp;nbsp;변경하여&amp;nbsp;고정&amp;nbsp;경로를&amp;nbsp;먼저&amp;nbsp;처리하도록&amp;nbsp;하면,&amp;nbsp;NestJS는&amp;nbsp;먼저&amp;nbsp;고정&amp;nbsp;경로를&amp;nbsp;확인하고&amp;nbsp;일치하는&amp;nbsp;경로가&amp;nbsp;없을&amp;nbsp;때만&amp;nbsp;동적&amp;nbsp;경로를&amp;nbsp;확인합니다.&amp;nbsp;따라서,&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;순서로&amp;nbsp;메소드를&amp;nbsp;정의하면:&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;`@Get(&quot;search&quot;)`&amp;nbsp;&amp;ndash;&amp;nbsp;고정&amp;nbsp;경로&lt;br /&gt;2.&amp;nbsp;`@Get(&quot;:sellerId&quot;)`&amp;nbsp;&amp;ndash;&amp;nbsp;동적&amp;nbsp;경로&amp;nbsp;파라미터&lt;br /&gt;&lt;br /&gt;`/sellers/search`&amp;nbsp;요청이&amp;nbsp;들어올&amp;nbsp;때&amp;nbsp;`search`라는&amp;nbsp;문자열을&amp;nbsp;`sellerId`&amp;nbsp;파라미터로&amp;nbsp;해석하는&amp;nbsp;것이&amp;nbsp;아니라,&amp;nbsp;`search`&amp;nbsp;경로를&amp;nbsp;처리하는&amp;nbsp;`findOne`&amp;nbsp;메소드를&amp;nbsp;정상적으로&amp;nbsp;호출하게&amp;nbsp;됩니다.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;권장&amp;nbsp;사항&lt;br /&gt;라우팅&amp;nbsp;관련&amp;nbsp;이슈를&amp;nbsp;방지하기&amp;nbsp;위해,&amp;nbsp;가능하면&amp;nbsp;다음과&amp;nbsp;같은&amp;nbsp;규칙을&amp;nbsp;따르는&amp;nbsp;것이&amp;nbsp;좋습니다:&lt;br /&gt;&lt;br /&gt;-&amp;nbsp;고정&amp;nbsp;경로는&amp;nbsp;동적&amp;nbsp;경로보다&amp;nbsp;먼저&amp;nbsp;정의합니다.&lt;br /&gt;-&amp;nbsp;동적&amp;nbsp;경로&amp;nbsp;파라미터를&amp;nbsp;포함하는&amp;nbsp;경로는&amp;nbsp;가장&amp;nbsp;마지막에&amp;nbsp;위치시키는&amp;nbsp;것이&amp;nbsp;안전합니다.&lt;br /&gt;-&amp;nbsp;라우트의&amp;nbsp;구조와&amp;nbsp;순서를&amp;nbsp;명확히&amp;nbsp;문서화하여&amp;nbsp;유지보수&amp;nbsp;시&amp;nbsp;혼란을&amp;nbsp;방지합니다.&lt;br /&gt;&lt;br /&gt;이러한&amp;nbsp;접근&amp;nbsp;방식은&amp;nbsp;경로&amp;nbsp;해석&amp;nbsp;과정에서의&amp;nbsp;예기치&amp;nbsp;않은&amp;nbsp;충돌과&amp;nbsp;버그를&amp;nbsp;방지하는&amp;nbsp;데&amp;nbsp;도움이&amp;nbsp;됩니다.&lt;/p&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/460</guid>
      <comments>https://spaines.tistory.com/460#entry460comment</comments>
      <pubDate>Fri, 24 May 2024 15:16:12 +0900</pubDate>
    </item>
    <item>
      <title>Swagger 사용법</title>
      <link>https://spaines.tistory.com/458</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cdragon.tistory.com/entry/NestJS-NestJS%EC%97%90%EC%84%9C-Swagger-%EC%82%AC%EC%9A%A9%EB%B2%95-feat-API-Documentation&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cdragon.tistory.com/entry/NestJS-NestJS%EC%97%90%EC%84%9C-Swagger-%EC%82%AC%EC%9A%A9%EB%B2%95-feat-API-Documentation&lt;/a&gt;&lt;/p&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/458</guid>
      <comments>https://spaines.tistory.com/458#entry458comment</comments>
      <pubDate>Tue, 21 May 2024 12:47:54 +0900</pubDate>
    </item>
    <item>
      <title>[nestJS] 실행 오류 해결</title>
      <link>https://spaines.tistory.com/457</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;NestJS&amp;nbsp;프로젝트에서&amp;nbsp;`npm&amp;nbsp;install`&amp;nbsp;실행&amp;nbsp;중&amp;nbsp;발생한&amp;nbsp;오류는&amp;nbsp;`@nestjs/typeorm`&amp;nbsp;모듈과&amp;nbsp;`typeorm`&amp;nbsp;모듈&amp;nbsp;간의&amp;nbsp;의존성&amp;nbsp;충돌&amp;nbsp;때문입니다.&amp;nbsp;오류&amp;nbsp;메시지에&amp;nbsp;따르면,&amp;nbsp;`@nestjs/typeorm@8.1.4`는&amp;nbsp;`typeorm`의&amp;nbsp;`^0.3.0`&amp;nbsp;버전을&amp;nbsp;요구하지만,&amp;nbsp;현재&amp;nbsp;프로젝트에&amp;nbsp;설치된&amp;nbsp;`typeorm`의&amp;nbsp;버전은&amp;nbsp;`0.2.45`입니다.&amp;nbsp;이는&amp;nbsp;`@nestjs/typeorm`의&amp;nbsp;필요&amp;nbsp;조건을&amp;nbsp;충족시키지&amp;nbsp;못하기&amp;nbsp;때문에&amp;nbsp;발생하는&amp;nbsp;문제입니다.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;해결&amp;nbsp;방법&lt;br /&gt;&lt;br /&gt;1.&amp;nbsp;**의존성&amp;nbsp;버전&amp;nbsp;명시적&amp;nbsp;업데이트**&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;프로젝트에서&amp;nbsp;사용&amp;nbsp;중인&amp;nbsp;`typeorm`의&amp;nbsp;버전을&amp;nbsp;`^0.3.0`&amp;nbsp;이상으로&amp;nbsp;업데이트해야&amp;nbsp;합니다.&amp;nbsp;이는&amp;nbsp;`@nestjs/typeorm@8.1.4`가&amp;nbsp;요구하는&amp;nbsp;최소&amp;nbsp;버전과&amp;nbsp;호환됩니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;다음&amp;nbsp;명령을&amp;nbsp;사용하여&amp;nbsp;`typeorm`을&amp;nbsp;업데이트할&amp;nbsp;수&amp;nbsp;있습니다:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;```bash&lt;/p&gt;
&lt;pre id=&quot;code_1716212999692&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;     npm install typeorm@^0.3.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;```&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;이렇게&amp;nbsp;하면&amp;nbsp;최신&amp;nbsp;버전의&amp;nbsp;`typeorm`이&amp;nbsp;설치되며,&amp;nbsp;`@nestjs/typeorm`과의&amp;nbsp;의존성&amp;nbsp;충돌이&amp;nbsp;해결됩니다.&lt;br /&gt;&lt;br /&gt;2.&amp;nbsp;**`--force`&amp;nbsp;옵션&amp;nbsp;사용**&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;`npm&amp;nbsp;install&amp;nbsp;--force`&amp;nbsp;명령을&amp;nbsp;사용하여&amp;nbsp;강제로&amp;nbsp;의존성을&amp;nbsp;설치할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;이&amp;nbsp;방법은&amp;nbsp;충돌을&amp;nbsp;간단히&amp;nbsp;무시하고&amp;nbsp;설치를&amp;nbsp;강제로&amp;nbsp;진행하지만,&amp;nbsp;호환성&amp;nbsp;문제로&amp;nbsp;인해&amp;nbsp;실행&amp;nbsp;시&amp;nbsp;예상치&amp;nbsp;못한&amp;nbsp;오류가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;사용&amp;nbsp;방법:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;```bash&lt;/p&gt;
&lt;pre id=&quot;code_1716213006626&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;     npm install --force&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;```&lt;br /&gt;&lt;br /&gt;3.&amp;nbsp;**`--legacy-peer-deps`&amp;nbsp;옵션&amp;nbsp;사용**&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;NPM&amp;nbsp;7&amp;nbsp;이상에서는&amp;nbsp;기본적으로&amp;nbsp;피어&amp;nbsp;의존성&amp;nbsp;충돌을&amp;nbsp;엄격하게&amp;nbsp;처리합니다.&amp;nbsp;`--legacy-peer-deps`&amp;nbsp;옵션을&amp;nbsp;사용하면&amp;nbsp;이전&amp;nbsp;버전의&amp;nbsp;NPM처럼&amp;nbsp;피어&amp;nbsp;의존성&amp;nbsp;충돌을&amp;nbsp;덜&amp;nbsp;엄격하게&amp;nbsp;처리할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;사용&amp;nbsp;방법:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;```bash&lt;/p&gt;
&lt;pre id=&quot;code_1716213013675&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;     npm install --legacy-peer-deps&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;추천&amp;nbsp;방법&lt;br /&gt;&lt;br /&gt;의존성&amp;nbsp;문제를&amp;nbsp;근본적으로&amp;nbsp;해결하기&amp;nbsp;위해서는&amp;nbsp;프로젝트의&amp;nbsp;`typeorm`&amp;nbsp;버전을&amp;nbsp;업데이트하는&amp;nbsp;것이&amp;nbsp;가장&amp;nbsp;권장되는&amp;nbsp;방법입니다.&amp;nbsp;이렇게&amp;nbsp;하면&amp;nbsp;나중에&amp;nbsp;다른&amp;nbsp;의존성&amp;nbsp;문제를&amp;nbsp;방지하고,&amp;nbsp;최신&amp;nbsp;기능과&amp;nbsp;버그&amp;nbsp;수정&amp;nbsp;혜택을&amp;nbsp;받을&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;`--force`나&amp;nbsp;`--legacy-peer-deps`는&amp;nbsp;일시적인&amp;nbsp;해결책으로,&amp;nbsp;잠재적인&amp;nbsp;호환성&amp;nbsp;문제가&amp;nbsp;있을&amp;nbsp;수&amp;nbsp;있으므로&amp;nbsp;주의해서&amp;nbsp;사용해야&amp;nbsp;합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃 오류.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1716215962104&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git rm -r --cached node_modules
git commit -m &quot;Remove node_modules from tracking&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;`.gitignore`&amp;nbsp;파일이&amp;nbsp;있음에도&amp;nbsp;불구하고&amp;nbsp;`node_modules`&amp;nbsp;디렉터리&amp;nbsp;내의&amp;nbsp;파일들이&amp;nbsp;git&amp;nbsp;커밋에&amp;nbsp;포함되는&amp;nbsp;문제는&amp;nbsp;일반적으로&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;가능한&amp;nbsp;원인으로&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;여기서&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;가능성과&amp;nbsp;그에&amp;nbsp;따른&amp;nbsp;해결&amp;nbsp;방법을&amp;nbsp;살펴보겠습니다.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;1.&amp;nbsp;`.gitignore`&amp;nbsp;파일의&amp;nbsp;위치&lt;br /&gt;`.gitignore`&amp;nbsp;파일이&amp;nbsp;프로젝트의&amp;nbsp;루트&amp;nbsp;디렉터리에&amp;nbsp;위치해&amp;nbsp;있는지&amp;nbsp;확인하세요.&amp;nbsp;`.gitignore`&amp;nbsp;파일은&amp;nbsp;그것이&amp;nbsp;위치한&amp;nbsp;디렉터리와&amp;nbsp;그&amp;nbsp;하위&amp;nbsp;디렉터리에만&amp;nbsp;영향을&amp;nbsp;미칩니다.&amp;nbsp;따라서,&amp;nbsp;이&amp;nbsp;파일이&amp;nbsp;프로젝트의&amp;nbsp;루트가&amp;nbsp;아닌&amp;nbsp;다른&amp;nbsp;곳에&amp;nbsp;위치해&amp;nbsp;있다면&amp;nbsp;`node_modules`&amp;nbsp;폴더를&amp;nbsp;올바르게&amp;nbsp;무시하지&amp;nbsp;못할&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;2.&amp;nbsp;이미&amp;nbsp;추적&amp;nbsp;중인&amp;nbsp;파일&lt;br /&gt;`.gitignore`&amp;nbsp;파일은&amp;nbsp;아직&amp;nbsp;추적(tracked)되지&amp;nbsp;않은&amp;nbsp;파일에만&amp;nbsp;영향을&amp;nbsp;미칩니다.&amp;nbsp;만약&amp;nbsp;`node_modules`&amp;nbsp;폴더의&amp;nbsp;파일들이&amp;nbsp;이미&amp;nbsp;git에&amp;nbsp;의해&amp;nbsp;추적되고&amp;nbsp;있다면,&amp;nbsp;`.gitignore`에&amp;nbsp;해당&amp;nbsp;경로를&amp;nbsp;추가해도&amp;nbsp;이미&amp;nbsp;추적&amp;nbsp;중인&amp;nbsp;파일들은&amp;nbsp;계속&amp;nbsp;추적됩니다.&lt;br /&gt;&lt;br /&gt;####&amp;nbsp;해결&amp;nbsp;방법:&lt;br /&gt;-&amp;nbsp;`node_modules`&amp;nbsp;폴더를&amp;nbsp;git&amp;nbsp;추적에서&amp;nbsp;제거합니다.&amp;nbsp;이&amp;nbsp;작업은&amp;nbsp;폴더를&amp;nbsp;실제로&amp;nbsp;삭제하지는&amp;nbsp;않지만,&amp;nbsp;git&amp;nbsp;추적&amp;nbsp;목록에서는&amp;nbsp;제거됩니다.&lt;br /&gt;&amp;nbsp;&amp;nbsp;```bash&lt;/p&gt;
&lt;pre id=&quot;code_1716216011619&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  git rm -r --cached node_modules
  git commit -m &quot;Remove node_modules from tracking&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;```&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;3.&amp;nbsp;`.gitignore`&amp;nbsp;파일의&amp;nbsp;규칙&amp;nbsp;확인&lt;br /&gt;`.gitignore`&amp;nbsp;파일&amp;nbsp;내의&amp;nbsp;규칙을&amp;nbsp;정확히&amp;nbsp;작성했는지&amp;nbsp;다시&amp;nbsp;한번&amp;nbsp;확인하세요.&amp;nbsp;예를&amp;nbsp;들어,&amp;nbsp;`/node_modules`는&amp;nbsp;프로젝트&amp;nbsp;루트&amp;nbsp;디렉터리&amp;nbsp;바로&amp;nbsp;아래의&amp;nbsp;`node_modules`&amp;nbsp;폴더만을&amp;nbsp;지칭합니다.&amp;nbsp;만약&amp;nbsp;프로젝트&amp;nbsp;구조가&amp;nbsp;다르거나&amp;nbsp;`node_modules`&amp;nbsp;폴더가&amp;nbsp;다른&amp;nbsp;위치에&amp;nbsp;있을&amp;nbsp;경우,&amp;nbsp;이&amp;nbsp;경로가&amp;nbsp;정확히&amp;nbsp;매치되지&amp;nbsp;않을&amp;nbsp;수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;4.&amp;nbsp;기타&amp;nbsp;`.gitignore`&amp;nbsp;충돌&lt;br /&gt;다른&amp;nbsp;`.gitignore`&amp;nbsp;파일(예:&amp;nbsp;전역&amp;nbsp;`.gitignore`&amp;nbsp;파일)이&amp;nbsp;있어서&amp;nbsp;설정이&amp;nbsp;충돌하는&amp;nbsp;경우도&amp;nbsp;있습니다.&amp;nbsp;프로젝트&amp;nbsp;또는&amp;nbsp;사용자의&amp;nbsp;홈&amp;nbsp;디렉터리에&amp;nbsp;다른&amp;nbsp;`.gitignore`&amp;nbsp;설정이&amp;nbsp;있는지&amp;nbsp;확인해&amp;nbsp;보세요.&lt;br /&gt;&lt;br /&gt;###&amp;nbsp;5.&amp;nbsp;Git&amp;nbsp;캐시&amp;nbsp;확인&lt;br /&gt;위의&amp;nbsp;단계를&amp;nbsp;완료한&amp;nbsp;후에도&amp;nbsp;문제가&amp;nbsp;해결되지&amp;nbsp;않는다면,&amp;nbsp;git&amp;nbsp;캐시를&amp;nbsp;리셋해&amp;nbsp;보는&amp;nbsp;것이&amp;nbsp;좋습니다.&amp;nbsp;때로는&amp;nbsp;이전의&amp;nbsp;git&amp;nbsp;인덱스가&amp;nbsp;영향을&amp;nbsp;줄&amp;nbsp;수&amp;nbsp;있기&amp;nbsp;때문입니다.&lt;br /&gt;```bash&lt;/p&gt;
&lt;pre id=&quot;code_1716216018548&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git rm -r --cached .
git add .
git commit -m &quot;Fixed untracked files&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;```&lt;br /&gt;&lt;br /&gt;위의&amp;nbsp;명령은&amp;nbsp;모든&amp;nbsp;파일을&amp;nbsp;캐시에서&amp;nbsp;제거한&amp;nbsp;다음&amp;nbsp;다시&amp;nbsp;추가하고,&amp;nbsp;`.gitignore`의&amp;nbsp;규칙에&amp;nbsp;따라&amp;nbsp;제외할&amp;nbsp;파일을&amp;nbsp;제외한&amp;nbsp;상태로&amp;nbsp;커밋합니다.&amp;nbsp;이&amp;nbsp;방법으로&amp;nbsp;`node_modules`가&amp;nbsp;정상적으로&amp;nbsp;무시되는지&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/457</guid>
      <comments>https://spaines.tistory.com/457#entry457comment</comments>
      <pubDate>Mon, 20 May 2024 22:50:20 +0900</pubDate>
    </item>
    <item>
      <title>[nestJS] pm2를 쓰는 이유</title>
      <link>https://spaines.tistory.com/456</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;pm2 공식 사이트의 한줄 소개를 보면 ,&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&quot;Advanced, production process manager for node.js&quot; 라고 소개되어있다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;node.js를 위한 발전된 상품 프로세스 매니져 !&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;*process : 컴퓨터에 저장된 프로그램이 실행돼서 메모리에 올라간 상태. 즉 동작중인 프로그램을 말함.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;즉 pm2란 node.js로 만들어진 프로그램을 잘 관리해주는 아이라는 것.&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;pm2는 여러가지 기능이 있는데, 예를들어&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;1. 프로그램이 꺼지면 자동으로 다시 켜줄 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;pm2로 start한 경우 , pm2로 끄 지 않으면&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로세스가 예기치 못하게 꺼졌을때, pm2로 시작한 경우 그냥 재시작 된다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;# pm2 start app.js&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 명령을 해주면 app.js 라는 프로그램을 프로세스로 만든것이고 , 이 프로세스는 백그라운드로 돌아가게 된다. 그래서 바로 다른 명령을 수행할 수 있는 상태인채로 실행되는것 !&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;2. 코드가 바뀌었을 때 , 자동으로 프로세스를 컸다 켜준다&amp;nbsp; (즉, 리소스 수정시 자동 반영)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;# pm2 start app.js --watch&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;만약 내가 개발을 하다가 파일의 코드를 수정했다고 치자.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이때 파일이 수정됐다고 해서 메모리 상에서 동작되고있는 프로세스에 반영되는 것은 아니다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;즉 , 내가 코드를 수정해서 저장버튼을 누른다고 해서, 실행중인 앱에 변화가 생기지는 않는다는 것.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 pm2를 쓰면 코드를 수정했을 때 자동으로 프로세스를 껐다가 켜준다.(--watch 지켜보고있다가 변화가 생기면 껐다 켜준다 !)&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;3. 로그를 한번에 볼수있는 화면 지원&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;# pm2 log&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 현재 실행중인 프로세스들의 로그들을 하나의 화면에서 모아서 보여줌. 콘솔이랑 리로드됐을때 표시 등등&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;4. 짱편한 개발자 모드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;# pm2-dev app.js&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;=&amp;gt;&amp;nbsp; watch + log 기능 이라고 생각하면 됨&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;5. pm2 클러스트 기능&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;-&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;# pm2 start app.js -i max&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로세스를 실행시킬 때 가능한 스레드의 숫자만큼 실행시키라는 뜻.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;node.js 는 싱글 스레드라서 하나의 스레드만 사용함. 하지만 그 컴퓨터의 가능한 스레드가 더 많은데 하나만 쓰는것보다,&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여러대의 스레드에 프로세스를 돌리면 더 많은 사용자의 접속을 받을 수 있음 .&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;16개의 스레드를 지원하는 컴퓨터 환경인데 1개의 스레드만 쓴다면 아까우니까 , 16개의 프로세스를 돌리는거임 ! (싱글 스레드 x 16개)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;390&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mgTXg/btsHu2CeQkZ/okZH8z87jEeE1FWoSKERZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mgTXg/btsHu2CeQkZ/okZH8z87jEeE1FWoSKERZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mgTXg/btsHu2CeQkZ/okZH8z87jEeE1FWoSKERZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmgTXg%2FbtsHu2CeQkZ%2FokZH8z87jEeE1FWoSKERZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;862&quot; height=&quot;390&quot; data-origin-width=&quot;862&quot; data-origin-height=&quot;390&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-alt=&quot;이렇게!!!&quot; data-lightbox=&quot;lightbox&quot; data-url=&quot;https://blog.kakaocdn.net/dn/p8sYW/btrMjXqjCV3/74mQKLiBPfOYJU7k7OXCL1/img.png&quot;&gt;&lt;/span&gt;이렇게!!!&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;6. 컴퓨터가 꺼졌다가 켜졌을 때 , 프로세스를 자동으로 실행시켜주는 기능&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;# pm2 start app.js&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;# pm2 save&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 해당 경로에 현재 실행되고 있는 프로세스들에 대한 상태가 저장됨.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;# pm2 startup&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 각각의 운영체제별로, 그 운영체제가 실행됐을 때 프로세스들을 실행시켜주는 명령어가 있는데 , 그 명령어를 알려줌.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이제 그 명령어를 복사해서 붙여넣고 실행 시키면, 컴퓨터가 꺼졌다가 켜졌을 때&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;save를 통해 저장해놓은 프로세스들의 상태를 복원해서 재실행시켜준다. pm2가 이걸 대신 다~~~~ 해주는 매니져 !&lt;/p&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/456</guid>
      <comments>https://spaines.tistory.com/456#entry456comment</comments>
      <pubDate>Mon, 20 May 2024 22:49:11 +0900</pubDate>
    </item>
    <item>
      <title>[nestJS] webpack을 쓰는 이유</title>
      <link>https://spaines.tistory.com/455</link>
      <description>&lt;h3 style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Webpack을 사용해야 하는 이유&lt;/h3&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Webpack을 사용하는 이유를 이해하기 위해 간단한 예시를 통해 설명해보겠습니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;상황&lt;/b&gt;: 웹 애플리케이션을 개발하고 있으며, 여러 개의 JavaScript 파일과 CSS 파일이 프로젝트에 포함되어 있습니다. 각 파일은 모듈화되어 있어서 코드를 구성하고 유지 관리하기 용이하지만, 이들을 브라우저에서 로드하려면 여러 번의 HTTP 요청이 필요하고, 파일 크기가 큰 경우 로딩 시간이 길어질 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이제 Webpack을 사용하는 이유를 예시로 설명해보겠습니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 전&lt;/b&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1716191408555&quot; class=&quot;xml&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;웹 애플리케이션&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;style1.css&quot;&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;style2.css&quot;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;script src=&quot;module1.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;module2.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src=&quot;module3.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 예시에서는 각 모듈과 스타일 시트를 별도의 파일로 로드하고 있으며, 각각의 파일은 별도의 HTTP 요청을 생성합니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용 후(Webpack 적용)&lt;/b&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;: Webpack을 사용하면 이러한 파일들을 번들로 묶을 수 있습니다. 예를 들어,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;app.js&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;app.css&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;로 번들링한 경우:&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1716191408557&quot; class=&quot;xml&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;웹 애플리케이션&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; href=&quot;app.css&quot;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;script src=&quot;app.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;Webpack을 사용한 경우, 모든 JavaScript 모듈과 스타일 시트가 하나의 번들로 묶여 하나의 HTTP 요청으로 처리됩니다. 이로써 다음과 같은 이점이 있습니다:&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #374151; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;로딩 속도 향상&lt;/b&gt;: 하나의 번들 파일을 로드하기 때문에 초기 로딩 속도가 향상됩니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;모듈 관리 용이성&lt;/b&gt;: 모듈화된 코드를 사용하여 개발 및 유지 관리가 쉽습니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;최적화 기회&lt;/b&gt;: Webpack은 코드 최적화 및 압축을 수행할 수 있으며, 불필요한 코드를 제거하고 성능을 향상시킬 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;이것은 Webpack의 간단한 예시이며, 실제 프로젝트에서는 더 복잡한 모듈 시스템 및 플러그인을 사용하여 더 많은 기능을 활용할 수 있습니다. Webpack은 모던 웹 개발에서 코드 관리와 최적화에 큰 도움을 주는 핵심 도구 중 하나입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;Webpack을 사용하는 실제 사례&lt;/span&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Webpack은 많은 웹 개발 프로젝트에서 사용되며, 다양한 실제 사례가 있습니다. 이 중에서도 가장 대표적인 몇 가지 실제 사례를 살펴보겠습니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #374151; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;React 프로젝트&lt;/b&gt;: React는 단일 페이지 애플리케이션(SPA)을 개발하기 위한 인기 있는 라이브러리 중 하나입니다. React 프로젝트에서는 Webpack을 주로 사용하여 모듈 번들링 및 개발 서버 설정을 관리합니다. React 앱은 컴포넌트 기반으로 구성되며, 각 컴포넌트는 자체적인 JavaScript 및 CSS 파일을 가지고 있습니다. Webpack은 이러한 컴포넌트 및 리소스 파일을 번들로 묶어 최적화된 번들을 생성합니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;Vue.js 프로젝트&lt;/b&gt;: Vue.js 역시 React와 마찬가지로 모듈 번들링에 Webpack을 사용하는 프레임워크입니다. Vue.js는 컴포넌트 기반의 웹 애플리케이션을 개발할 때 사용되며, Vue 파일 내에 HTML, JavaScript, CSS 코드를 포함하는데, Webpack은 이러한 Vue 파일을 처리하고 번들로 묶어줍니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;Angular 프로젝트&lt;/b&gt;: Angular는 Google에서 개발한 웹 애플리케이션 프레임워크로, Webpack을 사용하여 애플리케이션의 모듈과 의존성을 효과적으로 관리합니다. Angular 애플리케이션은 TypeScript로 작성되며, Webpack은 TypeScript 코드를 컴파일하고 번들로 묶어 최적화된 결과물을 생성합니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;웹 애플리케이션 번들링&lt;/b&gt;: 이전에 언급한 프레임워크 외에도 많은 웹 애플리케이션에서 Webpack을 사용합니다. 예를 들어, 웹 애플리케이션의 스크립트 파일, 스타일 시트, 이미지, 폰트 등을 효과적으로 번들로 묶어 최적화된 형태로 서비스하는 데 사용됩니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;라이브러리 개발&lt;/b&gt;: 라이브러리 및 패키지 개발자들도 Webpack을 사용하여 라이브러리를 번들로 묶고 제공합니다. 번들된 라이브러리를 사용하는 개발자들은 쉽게 가져와서 자신의 프로젝트에 통합할 수 있습니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;코드 스플리팅&lt;/b&gt;: 대규모 웹 애플리케이션에서 코드 스플리팅을 사용하여 초기 로딩 시간을 최소화하고 필요한 코드만 로드하는 경우에도 Webpack이 사용됩니다. 이것은 라우팅 기반의 웹 애플리케이션에서 특히 유용합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 실제 사례들은 Webpack이 얼마나 다양한 웹 프로젝트에서 사용되고 있다는 것을 보여줍니다. Webpack을 사용하면 모듈화된 코드를 효과적으로 관리하고 최적화하여 웹 애플리케이션의 성능을 향상시킬 수 있습니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Webpack 직접 사용하는 법&lt;/h3&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;Webpack을 사용하여 웹 애플리케이션을 번들링하고 최적화하는 기본적인 단계를 소개합니다. Webpack의 사용법은 다양하고 프로젝트에 따라 다를 수 있지만, 아래는 가장 기본적인 예제와 사용법입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Node.js 설치&lt;/b&gt;: Webpack을 사용하려면 Node.js가 설치되어 있어야 합니다. Node.js를 설치하지 않았다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://nodejs.org/&quot;&gt;공식 웹사이트&lt;/a&gt;에서 다운로드하고 설치하세요.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 프로젝트 디렉토리 생성&lt;/b&gt;: 웹 애플리케이션 프로젝트 디렉토리를 생성하고 해당 디렉토리로 이동합니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 프로젝트 초기화&lt;/b&gt;: 프로젝트 디렉토리에서 다음 명령을 실행하여 프로젝트를 초기화합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1716191408558&quot; class=&quot;coffeescript&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;npm init -y&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 명령은 package.json 파일을 생성합니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. Webpack 및 관련 모듈 설치&lt;/b&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;: 다음 명령을 사용하여 Webpack과 필요한 모듈을 설치합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1716191408559&quot; class=&quot;q&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;npm install webpack webpack-cli --save-dev&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 웹팩 설정 파일 생성&lt;/b&gt;: 프로젝트 루트 디렉토리에 webpack.config.js라는 웹팩 설정 파일을 생성합니다. 이 파일은 웹팩 번들링의 설정을 정의합니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어, 간단한 설정 파일은 다음과 같이 생길 수 있습니다:&lt;/p&gt;
&lt;pre id=&quot;code_1716191408559&quot; class=&quot;java&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const path = require('path');

module.exports = {
  entry: './src/index.js', // 애플리케이션 진입점 파일
  output: {
    filename: 'bundle.js', // 번들된 결과물 파일 이름
    path: path.resolve(__dirname, 'dist'), // 번들된 파일의 출력 경로
  },
};&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. 번들링 스크립트 작성&lt;/b&gt;: 프로젝트 디렉토리에 애플리케이션 코드 파일(index.js)을 생성하고, 이 파일에 자바스크립트 코드를 작성합니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7. 번들링 실행&lt;/b&gt;: 다음 명령을 사용하여 웹팩을 실행하고 번들링합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1716191408560&quot; class=&quot;ebnf&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;npx webpack&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8. HTML 파일 생성&lt;/b&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;: 프로젝트 디렉토리에 HTML 파일을 생성하고, 번들된 스크립트를 로드하도록 설정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1716191408560&quot; class=&quot;xml&quot; style=&quot;color: #555555; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Webpack 예제&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;script src=&quot;dist/bundle.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;9. 애플리케이션 실행&lt;/b&gt;: 생성한 HTML 파일을 브라우저에서 열어 애플리케이션을 실행합니다.&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;이것은 가장 기본적인 Webpack 사용법 예제입니다. 물론 복잡한 프로젝트에서는 추가 설정 및 모듈 로더, 플러그인 등을 사용하여 세부적으로 구성할 수 있습니다. 또한, 개발 환경과 프로덕션 환경 간의 설정을 분리하고 최적화 설정을 추가할 수도 있습니다. Webpack의 공식 문서와 강좌를 참조하여 더 자세한 사용법을 학습하실 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Wbpack의 정의&lt;/h3&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Webpack은 자바스크립트 애플리케이션을 위한 모듈 번들러(Module Bundler)입니다. 모듈 번들러는 다수의 모듈로 나뉜 자바스크립트 파일 및 다른 종속성 파일들을 하나로 묶어서 웹 애플리케이션을 최적화하고 관리하는 도구입니다. Webpack은 웹 개발에서 자주 사용되며, 다음과 같은 주요 기능을 제공합니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #374151; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;모듈 번들링&lt;/b&gt;: Webpack은 여러 개의 자바스크립트 파일 및 다른 리소스 파일을 하나의 번들로 묶어줍니다. 이를 통해 여러 파일을 하나의 HTTP 요청으로 처리할 수 있어 웹 페이지의 로딩 속도를 향상시킵니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;로더(Loader)&lt;/b&gt;: Webpack은 다양한 로더를 사용하여 이미지, 스타일 시트, JSON 파일 등 다양한 유형의 파일을 처리할 수 있습니다. 로더를 통해 파일을 변환하거나 최적화할 수 있습니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;플러그인(Plugin)&lt;/b&gt;: Webpack은 다양한 플러그인을 제공하며, 이를 사용하여 코드 최적화, 환경 변수 주입, 번들 분석, 코드 스플리팅 등 다양한 작업을 수행할 수 있습니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;번들 최적화&lt;/b&gt;: Webpack은 코드 스플리팅(Code Splitting)을 지원하여 애플리케이션의 번들을 여러 청크로 나눌 수 있습니다. 이를 통해 초기 로딩 시간을 줄이고 필요한 코드만 로드할 수 있습니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;HMR(Hot Module Replacement)&lt;/b&gt;: Webpack은 개발 서버와 함께 사용할 때 HMR을 지원하여 코드 수정 시 브라우저를 새로 고치지 않고도 모듈을 업데이트할 수 있습니다. 이로써 개발자는 실시간으로 코드 변경을 확인할 수 있습니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal; color: #666666;&quot;&gt;&lt;b&gt;다양한 환경 지원&lt;/b&gt;: Webpack은 브라우저 환경 뿐만 아니라 Node.js 환경에서도 사용할 수 있으며, 서버 사이드 렌더링 및 다른 환경에서도 유용하게 활용됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #374151; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Webpack은 모던 웹 개발에서 필수적인 도구 중 하나로, 모듈화된 코드를 효율적으로 관리하고 최적화하여 웹 애플리케이션의 성능을 향상시키는 데 도움을 줍니다.&lt;/p&gt;</description>
      <author>esoesmio</author>
      <guid isPermaLink="true">https://spaines.tistory.com/455</guid>
      <comments>https://spaines.tistory.com/455#entry455comment</comments>
      <pubDate>Mon, 20 May 2024 16:50:14 +0900</pubDate>
    </item>
  </channel>
</rss>