Playwright를 사용하여 OGP 이미지를 생성할 때 막힌 이야기

플레이 wright를 이용한 OGP 이미지 생성은 자주 사용하는 캔바스를 사용하는 방법보다 개인 개발 체험이 좋아 추천하는 방법이다.
하지만 현재 플레이 wright의 OGP 이미지를 사용해 생성된 정보가 적어 개발이 어려웠기 때문에 당시 막혔던 부분과 어떻게 해결됐는지 정리했다!

컨디션


Next.js의 항목을 OGP 이미지를 생성하는 OGP 서버로 vercel에서 디버깅합니다.
그 환경 외에는 시도하지 않았기 때문에 동작이 다를 수 있다.
"next": "12.0.7",
"playwright-aws-lambda": "^0.7.0",
"playwright-core": "^1.17.1",

이른바 플레이 wright


https://playwright.dev/
node.js는 크롬, 사파리, Firefox 등 브라우저를 조작하는 데 사용되는 프로그램 라이브러리입니다.같은 라이브러리에 Puppeteer가 있습니다.
PlayWright는 주로 E2E 테스트에서 사용되며, 이번에는 PlayWright의 캡처 기능을 사용하여 OGP에 사용할 이미지를 생성합니다.

Playwright에서 OGP 이미지를 생성하는 방법


대략적인 절차로 삼다
  • OGP 이미지가 되고 싶은component
  • 만들기
  • 이 component를 PlayWright"
  • 로 변환
  • 헤드 없는 브라우저에 "그것"을 설정
  • 브라우저 캡처 가져오기
  • 이 절차를 통해 Playwright에서 OGP 이미지를 생성할 수 있습니다.
    상세한 방법은 아래의 보도에 기재되어 있으니 반드시 참고하시기 바랍니다.개발할 때 참고 가치가 있어요!
    https://zenn.dev/tdkn/articles/c52a0cc7bea561

    플레이 wright로 막힌 곳


    그림 불러오기


    component 내의 이미지 섹션에서 생성된 OGP용 이미지는 표시되지 않을 수 있습니다.
    이것은 간단한 원인입니다. 왜냐하면 그림을 읽기 전에 캡처하는 시간을 가졌기 때문입니다!
    구체적으로 말하면 코드는 다음과 같다.
    await page.setContent(html, { waitUntil: "domcontentloaded" });
    
    ReactDOMServer.renderToStaticMarkup는 페이지에 ""를 렌더링하는 방법입니다.
    https://playwright.dev/docs/api/class-page#page-set-content
    setContent 매개 변수의 waitUntil은 setContent 작업이 끝났다고 생각하는 시간을 조정합니다.처음에 설정된 경우setContentDomcontentLoaded 이벤트가 발생했을 때 작업이 끝난 것으로 간주됩니다.domcontentloaded 이벤트는 브라우저가 HTML을 완전히 읽을 때 발생하는 이벤트로 이미지와 같은 외부 자원을 아직 읽지 못했기 때문에 이번 OGP 이미지를 생성하는 데 적합하지 않습니다.
    대신 다음 코드를 수정했다.
    await page.setContent(html, { waitUntil: "load" });
    
    DOMContentLoaded 이벤트는 브라우저가 모든 자원을 읽을 때 발생하는 이벤트이기 때문에 이미지가 나타납니다!!

    일본어


    로컬에서 개발할 때 눈치채지 못했지만vercel에서 디자인한 후 일본어 부분은 나타나지 않았습니다.
    이는 vercel 내부에서 사용되는 AWS Lambda의 작동 환경이 일본어를 지원하지 않기 때문이다.
    문제는 일본어를 표시할 수 있는 일본어 글씨체가 없기 때문에 일본어 글씨체를 넣어야 한다는 것이다.
    구체적으로 다음과 같은 코드에서 cssload를 사용하여 웹 font를 읽습니다.
    const css = `
      @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap');
      html,
      body {
        margin: 0;
        padding: 0;
      }
     ...省略
      `;
    
    return (
        <html>
          <style dangerouslySetInnerHTML={{ __html: css }} />
          <body>
           ...省略
          </body>
        </html>
      );
    
    웹 폰트 대신 다운로드한 글꼴 파일을 사용할 수 있지만 큰 문제가 있습니다.
    vercel의 ServerlessFunction 최대 크기가 50MB이기 때문에 일본어 글꼴처럼 큰 파일은 제한을 초과할 수 있습니다.웹 font를 읽는 데 시간이 걸리기 때문에 로컬 설정 글꼴 파일을 초과하지 않는 것도 가능하다고 생각합니다.

    그림 문자


    일본어와 마찬가지로 그림과 문자도 대응해야 한다.
    결론은 일본어 때와 마찬가지로 해결됐지만 시행착오로 그 과정도 공유됐다.
    일본어 때처럼 도화문자도 글씨체를 넣어 해결해야 해서 도화문자 글씨체를 찾아봤습니다.사용할 수 있는 글꼴은 없지만 noto-emoji가 발견돼 이 글꼴 파일을 다운로드하고 설정했습니다.
    https://github.com/googlefonts/noto-emoji
    그러나 방금 쓴 것처럼 그림 문자 글꼴 파일의 크기가 너무 커서vercel의 제한을 넘어섰다.
    이후 사용한 라이브러리@import의 ReadMe를 읽었습니다.
    Loading additional fonts
    If you need custom font support by e.g. emojicons in your browser, you have to load it by using the loadFont(url: string) function before you launch the browser.
    await loadFont(
      'https://raw.githack.com/googlei18n/noto-emoji/master/fonts/NotoColorEmoji.ttf'
    );
    
    https://github.com/JupiterOne/playwright-aws-lambda
    기록되어 있어, 바로 이거야!!사용해 보았는데 다음과 같은 오류가 생겨서 사용하지 않았다고 생각합니다.해결책을 아는 사람이 있다면 꼭 알려주세요!!
    unhandledRejection: Error: ENOENT: no such file or directory, mkdir 'C:\tmp\fonts'
    
    상기 코드에서 사용playwright-aws-lambda하고 css에서 읽으면 됩니다. 아래의 기술을 통해 그림 문자를 성공적으로 표시하였습니다!!
    @font-face {
        font-family: 'NotoColorEmoji';
        src: url('https://raw.githack.com/googlei18n/noto-emoji/master/fonts/NotoColorEmoji.ttf') format('truetype');
        }
    .wrapper {
        font-family: 'Noto Sans JP', 'NotoColorEmoji', sans-serif;
      }
    
    이로써 장기적인 OGP생성과의 격전이 끝났다.

    총결산


    정보가 적고 막힌 곳이 많지만 플레이 wright의 OGP 이미지를 사용한 생성이 최고입니다!!!

    좋은 웹페이지 즐겨찾기