Skip to main content

직접 만든 라이브러리로 Next.js 페이지 메타 정보 관리하기

info

2023년 12월 6일 한국신용데이터 기업 기술블로그에 게재한 내용입니다. 원본 확인하러 가기

안녕하세요, 한국신용데이터 프론트엔드 개발자 이원국(Lee)입니다.

Next.js 애플리케이션의 페이지 메타 정보를 하나의 JSON 파일에서 일률적으로 관리하기 위해 next-pathmap이라는 cli 라이브러리를 재미삼아 만들어 보았습니다. 어떤 필요에 의해 만들게 되었고 어떻게 만들었는지 소개해드립니다.

manage nextjs page metadata
https://www.npmjs.com/package/next-pathmap

요약

  • Next.js의 모든 페이지마다 메타 정보를 일률적으로 관리하기 위한 라이브러리를 만들었습니다.
  • page directory 또는 page extension 패턴에 맞추어 프로젝트 폴더를 파싱하고 JSON으로 path별 메타 정보를 담는 객체를 만들어줍니다.
  • 사내 자원 명명 컨벤션에 맞춘 PV 이벤트 트래킹용 페이지 명칭, PV 추적 여부, 서비스 카테고리 등을 하나의 파일에서 누락 없이 관리하기 위해 만들었습니다.

feat-1. Next.js의 파일 시스템 기반 라우팅(src/pages/*)을 활용

파일 시스템 상 pages 하위 디렉토리 구조와 확장명에 따라 페이지가 구성되는 next.js의 특징을 활용하여, 페이지 컴포넌트 파일을 파싱합니다.

.
├─ insurance
│ ├─ index.page.tsx
│ ├─ join
│ │ ├─ index.page.tsx # 설정/관리자/화면_1
│ │ ├─ product-A.page.tsx # 설정/관리자/화면_1
│ │ ├─ product-B.page.tsx # 설정/관리자/화면_2
│ │ └─ ...
│ │
│ ├─ submit
│ │ ├─ index.page.tsx
│ │ ...
│ └─ ...
...

feat-2. 프롬프트 입력 또는 config 파일을 통한 라이브러리 세팅

프롬프트 입력 또는 config 파일을 통해 페이지 루트의 위치, 만들어진 pathmap의 저장 위치 및 파일명, 파싱 포함 또는 제외 스코프, 맵핑할 페이지의 메타 데이터 구조, 상위 위계(카테고리) 라우트의 별칭을 설정할 수 있습니다.

const PathmapConfig = {
pathToPages: "src/pages",
pathToSave: "src/pathmap/pathmap.json",
includes: ["insurance/**/*.page.{ts,tsx}"],
excludes: ["!**/_*", "!**/!api"],
schema: {
alias: "",
trackPageView: true,
useCategories: true,
passQueryParams: true,
},
categories: [
{
insurance: "금융/보험",
},
],
};

module.exports = PathmapConfig;

feat-3. JSON으로 출력되는 pathmap 파일

(2)의 설정에 따라 지정된 위치에 JSON으로 라우트 파싱 데이터에 입력된 스킴을 맵핑한 output을 저장합니다.
여기서 한번 지정된 설정 값은 파싱을 다시 실행해도 덮어쓰지 않고 새로운 라우트에 대해서만 구조를 갱신합니다.

{
"/insurance": {
"alias": "보험",
"trackPageView": true,
"categories": ["금융/보험"],
"query": []
},
"/insurance/join": {
"alias": "보험/가입",
"trackPageView": true,
"categories": ["금융/보험"],
"query": []
},
"/insurance/join/[:product]": {
"alias": "보험/가입/{{product}}", // 동적 할당 값
"trackPageView": true,
"categories": ["금융/보험"],
"query": ["product"]
},

위 산출물을 통해 PV 한글 이벤트명을 자동으로 참조하거나, 페이지마다 지정해야 하는 특정한 공통 설정 등을 관리할 수 있습니다. (특정 이벤트 추적 여부, 동적 쿼리, 특정 기능 사용 여부 등)

feat-4. git hook, Ci 등 자동화에 연계시켜 사용할 목적

next-pathmap 라이브러리가 수행하는 기능은 너무 간단합니다. 파일 시스템을 특정 규칙에 따라 파싱하고, JSON 포맷의 데이터로 만들어주는 것입니다.

해당 라이브러리의 제작 목적은 페이지와 관련된 이벤트 명명 규칙과 메타 태그를 사용한 페이지 명세 등을 일관된 규칙으로 관리하는것에 의의가 있습니다.

PV 이벤트 누락, 이벤트명 컨벤션이 틀어지는 문제, 더 이상 사용하지 않지만 제거되지 않은 페이지 등 관리의 필요성을 느끼게 되었고, 자동으로 pathmap을 생성해서 single source에서 라우트를 관리할 수 있는 사내 표준을 만들고 싶었습니다.



어떤 문제를 해결하기 위해 만들었나요?

기존 한글명 디렉토리 구조로부터 파생된 페이지 명명 규칙

저희 프론트엔드는 주요 기술 스택으로 React, Next.js를 사용하고 있습니다. 일부 SPA 기반 프로젝트는 마이그레이션, 신규 도메인 서비스에 대해선 Next.js로 프로젝트를 만들어 AWS ECS에 서버 런타임을 띄워 운영하고 있습니다.

SPA(CSR) 프로젝트의 Router에서 Next.js의 파일 시스템 기반 라우팅으로 이관하는 중 기존에 정의된 규칙이 변경되어야 하는 상황이 생겼는데 그 중 하나가 바로 한글 pathname입니다.

# root
.
├─ 설정
│ ├─ 관리자
│ │ ├─ 화면_1 # 설정/관리자/화면_1
│ │ ├─ 화면_2 # 설정/관리자/화면_2
│ │ └─ ...
│ │
│ ├─ 수신설정
│ └─ ...

├─ 고객
│ └─ ...
├─ 리뷰
│ └─ ...
└─ 대출
└─ ...

예를 들어 OO은행대출서비스/페이지명/하위세그먼트 등 한글 그대로 하위 경로가 되기 때문에 PV 이벤트 트래킹, 지표 추적 등을 위한 Sementic Segmentation에 URL을 그대로 사용하고 있었습니다.

URL의 한글명 pathname이 PV 이벤트상 페이지 명으로 그대로 사용되고 있었다.
URL의 한글명 pathname이 PV 이벤트상 페이지 명으로 그대로 사용되고 있었다.

물론 한글 경로를 사용하면서 아래의 편의성을 얻을 수 있었습니다.

  • 한글명으로 라우트를 표기해서 코드 베이스, URL의 인지적 매칭이 쉬웠고, 영문으로 표현하기 애매한 서비스, 제도, 관련 용어들이 많았기 때문에 한글 표기가 오히려 개발 시간을 아껴주었다고 할 수 있습니다.
  • 한글명으로 라우팅을 쉽게 할 수 있도록 보일러플레이트 생성을 자동화(Script Automations) 해놓았기 때문에 일관된 규칙이 오랫동안 유지될 수 있었다고 생각합니다.

하지만 언제나 Trade-off입니다.

Next.js 환경으로 이관하게 되면서 Next.js에선 한글명 라우트가 지원되지 않아 별도의 주소 맵핑을 해주는 등의 조치가 필요했고 일반적인 방법으론 작동되지 않았습니다. 또한 URL 세그먼트의 한글 표기가 이중 인코딩 등의 문제로 이어지는 등 아래와 같이 관리 차원의 문제도 무시할 수 없었습니다.

한글 경로명으로 인한 관리상의 문제

정리하자면 문제를 인식하게 된 배경은 아래와 같습니다.

  • 조직 내 어떤 URL을 사용해야 하는지 일관적인 규칙이 충분히 공유되지 않아 한글 세그먼트가 포함된 URL과 퍼센트(Percent) 인코딩으로 표현된 URL이 혼재했습니다.
  • 딥링크 등 타 서비스와의 연계 과정에서 퍼센트 인코딩 된 URL을 등록시 이중 인코딩이 되어 링크가 깨지는 등 점점 관리에 부담이 가기 시작합니다.
  • 그러나 당장 영문 라우트 그대로 사용하자니, PageView(PV) 이벤트 명명 규칙도 한글명 세그먼트에 따라 하나의 컨벤션으로 사용되고 있습니다.

위 배경으로부터 아래의 문제가 파생되기 시작했습니다.

  • URL 이중 인코딩 등의 문제로 링크가 깨지는 등 운영 관리 측면에서 실수가 잦았다.
  • 한글명 라우트를 사용하지 못하는 환경에서 이전 이벤트 트래킹 명명 컨벤션을 맞추려다보니 개발자가 일일히 PageView 이벤트를 한글명으로 하드 코딩하여 기입하고 있다.
  • 페이지가 새로 만들어지거나 라우트명이 변경되는 등 변화가 발생하면 관리되는 규칙과 실제 코드 베이스의 동기화가 쉽게 깨진다.


어떻게 일관된 규칙을 유지할 수 있을까요?

개발 조직 내 일관된 규칙을 어떻게 유지할 수 있을까?

제가 생각한 대안은 편의를 제공하는 도구가 자연스럽게 규칙을 지킬 수 있도록 유도하는 것이었습니다. 개발 편의를 위해 미리 규칙이 규정된 도구를 이용하다보면 자연스럽게 모든 자원이 일관된 규칙으로서 관리될 수 있다는 판단이었습니다.

어떻게 하면 기존 방식을 유지하되 누락과 중복 없이 PV 이벤트를 관리할 수 있을까?

페이지별 메타 데이터를 담은 pathmap을 자동으로 만들자

제일 먼저 Next.js가 파일시스템 기반으로 라우트를 구성해주는 것에 착안하여 파일 시스템의 하위 구조를 읽어 패스맵(Pathmap)으로 변환하는 도구를 만드는 것이 좋을 것 같다고 생각되었습니다.

처음엔 Next.js에서 빌드할때 TTY에 빌드 artifact에서 라우트 구성을 브리프하는 시퀀스가 있는데 여기서 출력되는 라우트를 이용하면 어떨지 생각해 보았습니다.

빌드 후 생성된 NX cache
빌드 후 생성된 NX cache

모노레포 관리 툴로 NX를 사용하고 있으니, Build Cache에 나타나는 Terminal Output의 문자열을 파싱해서 사용하면 되지 않을까 생각했습니다.

빌드가 완료되면 콘솔에 출력되는 애플리케이션 Route 정보
빌드가 완료되면 콘솔에 출력되는 애플리케이션 Route 정보

하지만 리모트 환경(배포 서버)에서 프로젝트를 빌드하는 타이밍에 pathmap을 만들고자 한 것은 의도와 다릅니다. 그렇다고 pathmap을 만들기 위해 개발자의 로컬 머신에서 별도의 build를 수행하는 것은 비효율적입니다.

다행히 Next.js는 파일 시스템 기반 라우트를 지원하기 때문에 pages 폴더를 재귀적으로 탐색하며 페이지를 구성하는 파일을 파싱하고, 루트 하위의 세그먼트를 딕셔너리 형태로 구성하면 원하는 형태의 pathmap을 자동으로 만들 수 있다고 생각했습니다.

Next.js 13버전부터 app directory라는 피쳐가 나와 페이지를 구성하는 컴포넌트들을 역할별로 colocation 시키는 방식을 지원하기 시작했지만, 저희 서비스에 본격적으로 도입하진 않았기 때문에 당장은 page extension으로 라우트를 구분하였습니다.



그렇게 만들어진 next-pathmap 라이브러리

간단하게 생각대로 잘 되는지 실험해보기 위해 next-pathmap이라는 라이브러리를 만들어 보았습니다.

문제 해결의 목적도 있지만 반쯤 재미삼아 만들었기 때문에 나름 아이콘도 신경써보았습니다.
문제 해결의 목적도 있지만 반쯤 재미삼아 만들었기 때문에 나름 아이콘도 신경써보았습니다.

간단하게 설명하자면, 미리 정의해둔 config 파일의 데이터 모델, 또는 CLI 인터페이스 입력 시퀀스를 통해 Next.js의 모든 페이지 구조를 JSON으로 전환할 수 있는 라이브러리입니다.

config 파일을 사용한 라이브러리 셋업
config 파일을 사용한 라이브러리 셋업

위와 같이 프로젝트 루트에 config 파일을 미리 설정할 수도 있고

프롬프트 명령행 인터랙션
프롬프트 명령행 인터랙션

npx로 CLI 입력을 통해 pathmap을 생성할 수도 있고, 라이브러리 실행을 통해 아래와 같은 JSON 데이터를 얻을 수 있습니다.

JSON으로 표현된 페이지 라우트
JSON으로 표현된 페이지 라우트

저는 페이지의 메타 정보를 담기 위해 만들었기 떄문에 페이지 별칭, 카테고리, PV 트래킹 여부 등을 담았지만 이외에도 페이지마다 다양한 프로퍼티를 넣을 수 있어서 그 용도는 사용자가 활용하기 나름입니다.

그럼 어떤 생각으로, 어떻게 만들었는지 정리한 내용을 공유드립니다.

작동 순서

  • 유저의 CLI 입력 또는 프로젝트 루트의 *.config.js(or json)의 설정을 미리 읽어 파싱할 위치, 확장자, 출력되는 스키마 모델 등 사용자 정의를 읽어옵니다.
  • 라우트를 구성하는 프로젝트 하위의 모든 폴더와 파일 명을 특정 규칙에 따라 파싱합니다.
  • 동적(Dynamic) 라우트 등 가변 세그먼트는 추후 재사용 할 수 있도록 파라미터로 추출합니다. (e.g. [param]/index.js or […slugs])
  • 지정된 위치에 완성된 pathmap 파일을 저장합니다.

라이브러리의 의존성

파일 시스템의 구조를 읽어 패스맵으로 만드는 것은 아래 라이브러리들을 사용하여 간단히 해결할 수 있었습니다.

  • globby
    glob 패턴을 사용해서 특정 디렉토리 내 하위 디렉토리, 파일들을 파싱해주는 라이브러리입니다.

  • inquirer
    대화형 프롬프트 인터페이스를 쉽게 만들 수 있도록 돕는 라이브러리입니다. TTY 환경에서 stdin/stdout으로 특정 옵션을 선택하거나 값을 입력하는 등 프로젝트 기본 설정을 위한 설정값 입력 프로세스에 사용되었습니다.

  • json-format
    완성된 패스맵 JSON을 보기 좋게 formatting 해주는 라이브러리입니다.



라이브러리를 설정(configure)하는 두 가지 방법

pathmap은 두 가지 방법으로 configuration을 설정할 수 있습니다.

  • *.config.js 등의 설정 파일을 루트 경로에 명시.
  • Command Line의 대화형 인터랙션을 통한 순차적 입력 방식.

처음엔 CLI 인터페이스로 설정을 직접 입력하는 것을 생각했지만, 매번 경로가 수정될 때마다 설정을 입력하는 것이 번거롭기 때문에 흔히 사용하는 .confg.js 설정 파일을 루트 경로에 명시하는 것도 옵션으로 제공했습니다.

JS 개발 환경에서 써드파티 라이브러리를 사용할때 흔히 *.config.js의 포맷을 사용하는 것이 FE 개발자들에게 익숙하고, 프리셋이 있는 편이 더 편하다고 생각하여 next.config.js를 참조하여 만들어보았습니다.

1. *.config.js 설정 파일로 Configuration을 참조하는 방법

pathmap.config.js
pathmap.config.js

JSDoc Annotations

JSDoc 어노테이션을 사용하면 Config 객체에 어떤 프로퍼티를 입력해야 하는지 IDE에서 AutoSuggestion을 보여줍니다.

/** @type {import('path').member} */

다른 파일에서 사용하고 있는 타입들은 import 선언을 통하여 가져올 수 있습니다. 이 구문은 TypeScript에 따라 다르며 JSDoc 표준과 다릅니다.

JSDocs로 설정한 config 객체 프로퍼티 정보
JSDocs로 설정한 config 객체 프로퍼티 정보

개별 프로퍼티에 대한 설명을 JSDoc으로 명시하면 특정 프로퍼티가 어떤 역할을 할 수 있는지 사용자가 확인할 수 있습니다.

IDE 환경에서 편하게 사용할 수 있습니다
IDE 환경에서 편하게 사용할 수 있습니다

JSDocs에 대한 더 자세한 내용은 링크를 참조해주세요.

2. 인터랙티브 프롬프트를 통해 Configuration을 입력하는 방법

Interactive Command Line Interface

패키지 등을 설치할때 CLI에서 값을 입력하거나 옵션을 선택하는 등의 인터랙션을 통해 셋업을 전달하는 방식을 경험해 보셨을 겁니다.

개발 환경에서 흔히 볼 수 있는 프롬프트 인터랙션
개발 환경에서 흔히 볼 수 있는 프롬프트 인터랙션

처음엔 CLI로 pathmap을 만들기 위한 몇가지 설정을 개발자가 입력할 수 있게 하고 싶었습니다.

  • pages 폴더의 위치 — 프로젝트마다 위계가 다를 수 있으므로 pages 폴더의 위치를 별도로 설정할 수 있게 하고 싶었습니다.
  • 페이지 파일 접미사 및 확장자 선택 — js, ts, tsx, jsx 또는 현재 우리가 사용하고 있는 페이지 컴포넌트 전용 확장자인 *.page.tsx로 세그먼트를 구성할 확장자를 선택하게 합니다.
  • outdir — 만들어진 pathmap을 저장하는 위치와 파일 명을 선택, JSON 포맷으로 export 합니다.

이는 앞서 언급한 Inquirer 라이브러리를 사용하면 매우 간단하게 대화형 인터랙션을 구성할 수 있습니다.

블럭화된 인터페이스 타입을 사용하여 손쉽게 인터랙션을 만들 수 있다 (inquirer)
블럭화된 인터페이스 타입을 사용하여 손쉽게 인터랙션을 만들 수 있다 (inquirer)

inquirer를 사용해서 대화형 인터랙션이 작동하는 모습을 간단하게 도식화하면 아래와 같습니다.

더 직관적으로 표현할 방법이 없었습니다
더 직관적으로 표현할 방법이 없었습니다

https://github.com/SBoudrias/Inquirer.js
inquirer에 대한 자세한 내용은 inquirer 레포에서 확인하세요.



NPX 명령은 어떻게 작동하는가?

npm 의존성을 사용해본 분이시라면 npx 명령으로 특정 패키지의 바이너리를 작동시켜본 경험이 있으실 겁니다.

npx란 Node Package Execute의 약어로써 NPM 패키지를 프로젝트에 설치하지 않고 즉시 실행해주는 executer입니다. 마치 윈도우 브라우저에서 파일을 다운로드 할때 저장 또는 열기에서 열기를 선택해서 다운로드가 끝나자마자 즉시 실행하는 것과 개념적으론 비슷합니다.

npx package-name

그렇다면 제가 만든 라이브러리를 npx 명령으로 작동되게 하려면 아래의 것들이 필요합니다.

  • package.json에 binary 위치 (bin as a key) 명시
  • Node.js 인터프리터로 실행시킬 수 있는(executable) 스크립트 파일 작성 (*.js)

NPX가 작동하는 시나리오들

로컬 노드 모듈에 있는 node_modules/.bin 폴더에 있는 스크립트를 실행 global .bin에 있는 스크립트를 실행 remote에서 일화용(one-off)으로 package를 설치한 후 bin 실행

package.json

package.json이 존재하는 루트 디렉토리에 bin/scripts.js 경로와 파일이 존재한다는 가정 하에 아래와 같이 작성합니다.

{
"name": "next-pathmap",
"bin": "./bin/script.js"
}

위와 같이 작성하면 npx를 통해 실행하고자 할때 bin 디렉토리의 파일을 실행 가능한 스크립트로 보고 작동시키게 됩니다.

package.json에 명시된 executable의 경로
package.json에 명시된 executable의 경로

인터프리터 디렉티브 #!/usr/bin/env node

쉘 스크립트를 다뤄보신 분들은 쉬뱅(Shebang — 욕 아닙니다)이라고 부르는 디렉티브를 아실겁니다.

#!/bin/sh

이것은 유닉스 계열(Unix-like) 플랫폼에서 프로그램 로더에게 해당 문서의 문자열들이 실행 가능한(executable) 스크립트이며 어떤 인터프리터를 사용해야 하는지 바이너리 경로를 알려주는 표식의 역할을 합니다. 그렇다면 자바스크립트(Node.js 런타임)는 어떻게 디렉티브를 사용해서 실행시킬 수 있을까요?

#!/usr/bin/env <executableName>
#!/usr/bin/env node

인터프리터의 위치를 절대 경로로 표시하는 대신 /usr/bin/env 뒤에 인터프리터를 명시하는 목적은, POSIX 시스템마다 인터프리터의 경로가 달라질 수 있기 때문에 절대 경로 대신 $PATH에 지정된 해당 인터프리터의 디렉토리를 찾아 실행시키기 위함입니다.

너무나 단순한 pathmap executable
너무나 단순한 pathmap executable

빌드 타임에 컴파일된 index.js의 pathmap 프로그램을 호출하여 node 런타임에서 실행시켜주는 역할을 합니다.

런타임에서 라이브러리의 프로그램이 어떤 기능을 수행하는지는 아래 링크를 통해 소스 코드를 참조하시기 바랍니다.
https://github.com/wonkooklee/next-pathmap?search=1



프로젝트에 next-pathmap 셋업하기

1) config 파일 셋업

우선 프로젝트 루트 레벨에 프로젝트에 맞는 설정 파일을 생성합니다.

pathmap.config.json
pathmap.config.json

2) script 설정

편하게 스크립트를 사용하기 위해 워크스페이스의 package.json에 명령을 미리 등록합니다.
pnpm을 사용하기 때문에 npx 대신 pnpm dlx (executable 실행 명령)을 사용합니다. shell 환경에서 next-pathmap을 명령어로 인식할 수 있도록 글로벌 설치 또는 로컬 node_modules의 bin 폴더에 있는지 확인합니다.

{
"scripts": {
"gen:pathmap": "pnpm dlx next-pathmap"
}
}

3) next-pathmap 실행

명령을 실행하면 npm registry 또는 로컬 binary 디렉토리에서 executable을 가져와 실행시킵니다. 자세히 보면 프로그램이 pathmap.config.js has been detected를 출력하는 것을 확인할 수 있습니다. config를 잘 찾아서 정상적으로 참조하였다는 피드백입니다.

몇 초의 파싱 과정이 끝나면 SUCCESS 메시지가 출력되고 명령 실행 위치(pwd) 기준으로 어디에 파일이 생성되었는지 OUTPUT을 통해 알려줍니다.

만약 파싱 과정에서 문제가 발생한다면 process.exit의 각 예외처리된 코드를 통해 문제를 알려줍니다.

지정된 위치(src/pathmap/pathmap.json)에 패스맵 파일이 생성되었습니다.
이제 이 파일을 활용해서 URL 루트에 맞는 이벤트 명을 맵핑하거나 여러 메타 데이터를 담을 수 있습니다.

4) githook 연동

git-hook 관련 솔루션은 많지만 husky로 간단한 예시를 보여드립니다.

.husky/pre-push

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

pnpm nx gen:pathmap finance
if [ $? -eq 0 ]; then
onsuccess=$(cat <<EOF
\n
-------------------------------------------------\n
✅ YAY!!! You are good to go! ✅ \n
-------------------------------------------------\n
)
echo $onsuccess
exit 0
else
onfailure=$(cat <<EOF
\n
-------------------------------------------------\n
❌ Oops, CANNOT build pathmap, Try again! ❌ \n
-------------------------------------------------\n
)
echo $onfailure
exit 1
fi

push 과정에서 페이지 메타 정보를 누락시키진 않았는지 앞선 next-pathmap의 프로세스 종료 코드를 참조하여 성공/실패 여부를 판가름합니다.

pathmap 생성에 성공하고, alias 등 자원 관리상 작업자가 지정해주어야 하는 정보의 누락이 없을 경우 코드 저장소에 커밋을 올릴 수 있게 됩니다.



개발자의 고민

개발자로서 일을 하다보면 ‘어떻게 만들것인가’보다 ‘어떻게 관리할 것인가’에 대해 훨씬 많은 고민을 하게 됩니다.
이번엔 블로그 글로 적기 좋은 소재로써 URL과 이벤트명 컨벤션에 대한 라이브러리 구현기를 다뤘지만, 평소에도 용이하고 일관적인 유지 관리 방법에 대해 많은 시도와 고민을 하고 있습니다.

서비스의 일환으로 사용되는 페이지와 에셋, 소스 코드 등 모든 것은 관리의 대상이고 조직의 자원이기 때문에 만들기만 하는 것보단 잘 활용되고 있는지, 누락이나 보완해야 하는 사항은 없는지, 어떻게 하면 더 손쉽게 관리가 가능할지 고민한다면 더 좋은 개발자로 성장할 수 있는 계기가 되지 않을까 생각해봅니다.