원시 텍스트를 드라이브의 형식화된 Word Doc으로

발행: (2026년 5월 10일 AM 04:29 GMT+9)
5 분 소요
원문: Dev.to

Source: Dev.to

문제점

대부분의 메모 앱은 너무 복잡하거나 Word 문서를 제공하지 않는다. 나는 최소한의 기능만 원했다: 텍스트를 입력하고, 폴더를 선택하고, .docx 파일로 Drive에 저장한다. 간단해 보였지만 구현하면서 몇 가지 예상치 못한 어려움이 나타났다.

사용한 기술

  • ReactVite를 프론트엔드에 사용.
  • docx.js(CDN 로드) – 브라우저에서 Word 문서를 생성 (npm 버전은 Node.js 전용).
  • mammoth.js(CDN) – 기존 .docx 파일을 읽어 “추가” 기능을 구현.
  • Google Identity ServicesGoogle Drive REST API v3 – 인증 및 Drive 접근.

Google Drive API 설정

1단계

Google Cloud Console에 들어가 새 프로젝트를 만든다.

2단계

Google Drive API를 활성화한다.

3단계

OAuth 동의 화면을 설정한다:

  • 앱을 External 로 지정.
  • 테스트 사용자로 자신의 이메일을 추가(403 오류 방지).
  • drive.file(업로드)와 drive.readonly(폴더 목록) 스코프를 추가.

4단계

Credentials 아래에 OAuth 2.0 Client ID를 만든다:

  • Application type: Web Application.
  • Vite용 로컬 URL(http://localhost:5173/)을 추가(포트 3000이 아님).

5단계

Client ID를 복사해 .env 파일에 VITE_GOOGLE_CLIENT_ID 변수로 저장한다.

앱 작동 방식

사용자가 로그인하면 앱은 Google Identity Services Token Client를 이용해 브라우저만으로 OAuth 액세스 토큰을 얻는다—서버 콜백이 필요 없다. 이후:

  1. Google userinfo 엔드포인트에서 사용자의 이름을 가져온다.
  2. Drive API를 통해 모든 Drive 폴더를 불러온다.

사용자 흐름

  • 기존 폴더를 드롭다운에서 선택 또는 새 폴더 이름을 입력해 즉시 생성한다.
  • 폴더를 선택한 뒤 제목과 원시 텍스트를 입력하고 Save 버튼을 클릭한다.

핵심: Word 문서 생성

원시 텍스트는 docx.js에 전달되어 메모리 상에 올바른 Word 문서가 만들어진다. 구성 요소는:

  • 헤딩
  • 타임스탬프
  • 각 텍스트 라인을 포맷된 단락으로 변환

중요: Packer.toBlob()을 사용한다—브라우저에서는 Packer.toBuffer()Packer.toArrayBuffer()가 조용히 실패하거나 오류를 발생시킨다.

Google Drive에 업로드

생성된 Blobmultipart upload 엔드포인트에 FormData로 전송한다:

  • 파일 메타데이터(부모 폴더 ID 포함)를 담은 파트 하나
  • 실제 파일 내용을 담은 파트 하나

기존 파일을 업데이트하려면 POST 대신 PATCH를 사용한다.

“기존 파일에 추가” 기능

  1. 선택한 .docx 파일을 Drive에서 다운로드한다.
  2. mammoth.js로 텍스트를 추출한다.
  3. 새 섹션 헤딩 아래에 기존 내용과 새 내용을 병합한다.
  4. 전체 문서를 다시 만든다.
  5. 원본 파일을 교체하도록 재업로드한다.

Netlify에 배포

  1. npm run build 실행.
  2. dist 폴더를 Netlify에 드래그.
  3. 사이트 설정에서 VITE_GOOGLE_CLIENT_ID를 환경 변수로 추가.
  4. Google Cloud Console에서 OAuth 클라이언트의 Authorized JavaScript Origins에 Netlify URL을 등록한다.

참고: Google Cloud에서 앱이 Testing 모드일 경우 테스트 사용자로 추가된 이메일만 로그인할 수 있다. OAuth 동의 화면에서 Production으로 전환하면 일반 사용자도 접근 가능해진다.

내가 겪은 흔한 실수들

  • Vite용 포트 5173 대신 3000을 사용.
  • 테스트 사용자를 추가하지 않아 403 오류 발생.
  • Packer.toBuffer() 대신 Packer.toBlob()을 사용하지 않음.
  • Netlify URL을 Authorized JavaScript Origins에 추가하지 않음.

링크

0 조회
Back to Blog

관련 글

더 보기 »