이 글은 Craft Extension을 통해 전송되었습니다

✍🏼 작성일 2021년 12월 08일    💡 수정일 2022년 02월 28일
❗️ 참고: 이 글이 작성된 지 이미 일이 지났습니다. 시의성에 유의하세요

이 글에서 설명하는 일부 프로세스 방식은 더 이상 사용되지 않으며, 새로운 프로세스 로직은 여기에서 확인할 수 있습니다: https://www.xheldon.com/tech/my-blog-ci-in-2022.html

2일 동안의 작업으로, Craft에서 콘텐츠를 작성한 후 직접 만든 플러그인을 통해 내용을 Github 저장소에 동기화하고, Github 저장소가 자동으로 Github Pages를 빌드하는 과정을 간단히 구현했습니다.

저장소 주소: https://github.com/craft-extension/craft-github-extension

블로그 업데이트 프로세스 변경

이전 프로세스

VSCode로 작성 → x_blog_src 저장소에 제출 → Gihutb Action 트리거 → 빌드 후 x_blog 저장소에 제출 → 성공

하지만 이 과정에는 몇 가지 문제점이 있었습니다:

  1. 한 번에 글을 완성하지 않고 중간중간 작성하는 경우가 많습니다. 회사 컴퓨터에서 일부 작성 후 Github에 제출하면, 집 컴퓨터에서 이어서 작업할 때마다 제출할 때마다 Github Action이 트리거됩니다. 특정 접두사가 포함된 커밋 메시지일 때만 빌드하고, 그렇지 않으면 해당 제출을 무시하는 방식으로 해결했지만, 여전히 우아한 방법은 아닙니다.

  2. 또 다른 방법은 _draft 디렉토리에서 작성하고 자유롭게 제출한 후, 완성된 글을 _post로 이동시키는 것입니다. 하지만 앞서 말한 것처럼 여전히 우아하지 않습니다.

  3. Jekyll 설정에서 미래 날짜의 글을 표시하지 않도록 하는 방법도 있습니다. 즉, 미완성 글의 메타데이터에 2099년 같은 날짜를 설정하면 Jekyll이 빌드하지 않지만, 여전히 Github Action이 트리거되고 파일이 업데이트되므로 우아한 해결책은 아닙니다.

  4. 때로는 Craft의 매력적인 디자인(시각적으로 아름답고)과 편의성(언제 어디서나 편집 및 다중 기기 동기화) 때문에 Craft에서 글을 작성한 후, 완성된 Markdown을 내보내고 수동으로 이미지를 x_blog-static 저장소에 업로드한 다음 Markdown의 이미지 참조 링크를 수정하고 Github 저장소에 제출하는 긴 과정을 거쳤습니다.

현재 프로세스

Craft에서 작성 → x_blog_src 저장소에 제출 → Gihutb Action 트리거 → 빌드 후 x_blog 저장소에 제출 → 성공

이전과의 차이점은 VSCode에서 작성하는 대신 Craft에서 직접 작성하는 것으로, 이전의 네 번째 방법과 유사하지만 Github로 동기화하는 번거로운 과정이 줄었습니다. 이미지(아래에서 별도로 설명)를 제외하면 문서만 동기화하는 것은 매우 완벽한 솔루션입니다. 따라서 앞으로는 블로그를 더 자주 업데이트할 수 있을 것 같습니다(이전에 작성 속도가 느렸던 큰 이유 중 하나는 과정이 너무 복잡했기 때문입니다). 이제는 콘텐츠 자체에 더 집중할 수 있게 되었습니다, 훌륭합니다!

설명

사용 시 다음과 같은 설정이 있습니다:

  1. 현재 이 플러그인은 개인 사용만을 위해 제작되었기 때문에, 일부 설정은 개인화되어 하드코딩되어 있습니다. 예를 들어 파일은 _posts 디렉토리에만 업로드할 수 있도록 되어 있습니다. 사용자가 많아지면 더 범용적으로 개선할 계획이지만, 현재는 개인적으로 사용 중이라 크게 신경쓰지 않고 있습니다.

  2. Github의 Rest API를 통해 Markdown 내용을 지정된 Github 저장소에 동기화하기 위해서는 Github Personal Token이 필요합니다.

  3. Github API는 내용을 저장소에 전송할 때, 원본 저장소와 기존 저장소의 내용 sha 값을 비교합니다. 만약 두 값이 완전히 동일하면, 업데이트된 파일은 커밋 정보에 표시되지 않으며, 커밋 정보를 확인할 때 0 files changes로 표시됩니다.

  4. 글의 첫 번째 블록은 Jekyll의 메타 정보로 사용되는 두 열의 테이블이어야 합니다. 현재 메타 정보는 path를 제외한 모든 내용을 포함합니다.

  5. 글의 제목은 블로그 글의 제목으로 사용되며, 메타 정보에 작성할 필요가 없습니다.

  6. 2021년 12월 9일 기준, Craft에서 제공하는 API craftBlockToMarkdown으로 출력된 Markdown은 문서 내의 Blockquote 스타일( Craft Block에서는 Decoration의 Focus로 불리며, 공식적으로 버그로 인정되어 이후 버전에서 수정될 예정입니다)을 출력하지 못하는 것으로 확인되었습니다. 사용자 정의 Markdown을 생성하려면 직접 Block을 순회해야 합니다. 다른 기능은 테스트하지 않았습니다.

  7. 현재 플러그인의 설정 항목은 사용자 친화적이지 않으며, 추후 최적화할 예정입니다.

  8. Craft의 Markdown 스타일은 상당히 보기 좋게 구성되어 있습니다. 예를 들어 list 아래에 paragraph나 image를 삽입하여 list 내용과 정렬을 맞출 수 있습니다. 하지만 일반 Markdown은 이를 지원하지 않기 때문에, 출력된 스타일은 다소 보기 좋지 않을 수 있습니다.

  9. 메타 정보에 tags와 같이 여러 줄의 정보가 포함된 경우, -:로 구분할 수 있습니다. 예: -:테스트-:서버.

  10. Craft의 Markdown API는 common 형식(기본값, 현재 이 플러그인에서는 구성 불가)을 사용할 것을 권장합니다. bear 형식을 사용하면 이미지 앞에 !가 없어 Github에서 이미지가 아닌 링크로 인식할 수 있습니다.

  11. Craft의 "심층 Markdown 링크"와 같은 일부 기능은 표준 Markdown 문법이 아니기 때문에, 여기서는 지원 여부를 테스트하지 않았습니다.

  12. 공식 설명에 따르면, storageApi는 웹 버전에서 암호화되지 않으므로 저장 시 사용자에게 주의를 요구해야 합니다. 자세한 내용은 여기를 참조하세요. Mac 버전에서는 이 문제가 없습니다. 분석 결과 웹의 storageApi가 SessionStorage에 저장되어 있는 것으로 확인되었지만, 다시 확인해 보니 IndexedDB로 변경되었습니다 (개발자 프리뷰 버전이라 변경이 빠르네요…). plugindata-storage라는 이름의 DB에 저장됩니다. Mac 버전의 경우, 사용자 작업 공간을 전환했을 때 Storage도 사라지는 현상이 있어 이슈를 제출했지만, 아직 공식 답변은 없습니다 :-(.

  13. Mac의 storageApi에는 경쟁 상태(race condition) 문제가 있어, 플러그인 로딩 초기에 storageApi로 데이터를 읽으려고 하면 읽어오지 못합니다. 따라서 제 플러그인에서는 Mac인 경우 3초 지연 후 플러그인 내용을 초기화하도록 처리했으며, 웹 버전에는 이 제한이 없습니다.

  14. 더 많은 구성 지원이 진행 중입니다…

이미지 관련 문제

  1. 웹이든 앱이든 Craft에 업로드한 이미지는 웹에서 요소 검사 시 반드시 .jpg 형식으로 표시됩니다. 하지만 Craft의 Markdown API로 생성하면 .png 형식으로 변환되는 오해가 있었는데, 실제로는 이미지 확장자는 업로드 당시 형식과 동일하게 유지되며 Craft가 형식을 변환하지는 않습니다.

  2. 문서에서 요소 검사 시 표시되는 이미지 주소 도메인은 res.craft.do이며, Github 저장소에서 소스 파일을 볼 때도 이 주소가 표시됩니다. 하지만 Github에서 이미지를 미리 보기(즉, 저장소의 md 파일을 직접 클릭하여 열 때)하면 https://camo.githubusercontent.com 주소가 나타납니다. Github이 md 이미지를 자체 서버에 백업해 주는 줄 알았는데, 사실은 Github이 보안상의 이유로 제3자 이미지를 렌더링할 때 임시로 저장해 주는 것뿐입니다.

  3. 서버를 사용하지 않는 경우, Craft에 업로드한 이미지를 Craft API로 가져올 때 프론트엔드의 fetch 등의 방법으로는 가져올 수 없으며 CORS 오류가 발생합니다. 따라서 글을 Github에 업로드할 때 글 내부의 이미지를 추출하여 자신의 이미지 호스팅/COS/Github 저장소에 업로드하려면 순수 프론트엔드로는 불가능하며, 서버를 통해 해당 이미지를 가져온 후 전송해야 합니다. 또한 Craft imageBlock의 이미지 주소는 AWS의 S3에 위치해 있어, 국내 서버(예: 텐센트 클라우드)에서 가져올 경우 타임아웃이나 속도 저하가 발생할 수 있습니다. 하지만 해외 서버에서 국내로 전송할 때는 속도가 괜찮은 편이므로, AWS 서비스를 이용해 이미지를 전송하는 것이 좋습니다 (업데이트: 현재는 Vercel을 사용하고 있으며, 자세한 내용은 이 글을 참조하세요).


여기에 이미지 하나를 넣어 속도를 테스트해 보겠습니다:

Image

더보기

  1. 템플릿 플러그인 개발을 계획 중이며, 주소는 다음과 같습니다: https://github.com/craft-extension/craft-template-extension

  2. 모든 플러그인은 이 도구를 기반으로 개발되었습니다: https://github.com/craft-extension/craft-dev-toolkit 공식 예제에 UI에 antd 사용 등의 몇 가지 설정을 추가했습니다. 이후 사용자가 생기면 플러그인 개발 환경을 생성하는 스캐폴딩 지원 등 더 많은 설정을 추가할 계획입니다.

  3. 더 많은 플러그인을 기대해주세요…

2022.01.24 업데이트

이미지 문제에 대한 아이디어로 Github에 이미지를 백업하지 않고(이미 Craft에 있는 이미지는 백업과 동일하므로) 직접 Tencent Cloud COS에 업로드하는 방안을 고려했습니다. 하지만 Tencent Cloud COS는 요청을 보내야 하며, 사용하는 요청 방법은 request 라이브러리이며, 여기에 서명 정보 등을 추가하기 위해 한 레이어를 더 감싸고 있습니다. COS 소스 코드를 확인해 본 결과 요청 도구를 구성할 수 있다는 것을 발견했고, 현재 두 가지 방법으로 목적을 달성할 수 있습니다:

  1. COS에서 사용하는 request 라이브러리의 메서드를 재정의합니다.

  2. COS의 요청 코드를 재작성합니다.

  3. 문서에 제공된 예제에 따라 서명을 직접 구성하여 요청을 보냅니다.

당연히 세 번째 방법이 가장 간단하기 때문에 최종적으로 이 방법을 채택했습니다.

2022.02.28 업데이트

01.24의 방안은 폐기되었습니다. 비용이 너무 큽니다. 최종 해결책은 이미지를 Github에 업로드하지 않고 Vercel 서비스를 통해 Tencent Cloud에 저장하는 것입니다. 이로써 이미지 문제가 해결되어 Craft로 글을 편안하게 작성할 수 있게 되었습니다.

- EOF -
이 글의 최초 게시: 이 글은 Craft Extension을 통해 전송되었습니다 - Xheldon Blog