ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Gatsby의 플러그인 시스템을 제대로 이해하고, 내 플러그인 만들어보기
    Web Dev/5. Projects 2021. 4. 5. 02:15
    728x90

    Gatsby를 좀 만만하게 보고 시작했었따....

    아주 매콤한맛을 보는 중이다. Markdown을 렌더링해서 나만의 블로그를 만들고 앞으로 굳이 서버가 필요없는 서비스는 Gatsby로 필요한건 Next.js로 해야지~ 룰루~ 하고생각했는데 지금 아주 매콤한맛을 보고 있다. 다시 초심으로 돌아가서 Gatsby의 플러그인 시스템을 자세히 살펴보고 Markdown parsing 하는 플러그인이 내 성에 안차서 하나 만들려고 한다. 

     

     

    What is a Plugin?  

    Gatsby에서는 Plugin이라는 걸 사용하는데, 이건 Gatsby  APIs를 적용한 Node.js 패키지이다. 특히, 나는 Markdown파일을 변환할때 gatsby-transformer-remark란걸 사용했는데, 대체 동작원리가 이해가 안됬다. 

     

     

     

    Build your own Gatsby Source Plugin and Source Data from Anywhere 

     

     

    위의 내용은 공식문서에서 있는 내용인데, repo에 있는걸 읽어오는거면 대부분 gatsby-source-filesystem을 사용해서 해결할 수 있고, 여기서 파일의 내용을 읽어올때 transformer plugin을 사용할 수 있다. 

     

     

    - 우선 gatsby-node.js 파일을 만들어야한다. 여기가 gatsby의 플러그인을 정의하는 곳이다(node package인데, gatsby의 api가 적용되는 곳)

    gatsby 프로젝트내에 적당한 이름으로 custom plugin을 지정한다. 

     

     

    const fetch = require("node-fetch")
    const queryString = require("query-string")
    exports.sourceNodes = (
      { actions, createNodeId, createContentDigest },
      configOptions
    ) => {
      const { createNode } = actions
    
      delete configOptions.plugins
    
      console.log("testing my plugin", configOptions)
    }
    

     

    내용은 위와 같다. 여기서 sourceNodes가 gatsby프로젝트에서 node가 되는 내용들이다. 꼭 plugins 폴더 내에 만들어야한다! 그러면 gatsby가 알아서 custom plugin을 찾아준다. 

     

    프로젝트의 gatsby-config에 위와 같이 정의하면 이제 호출이 된다. 

    따라하다보니 그냥 transformer 를 내가 원하는 markdown parser로 만들어도 될것 같다. 

    - Creating a transformer Plugin  

     

     

    - gatsby에서는 gatsby-source-filesystem이라는 걸 제공하는데 로컬의 데이터를 읽어서 Gatsby application에서 사용할 수 있게 해주는 신통방통한 plugin이다(얘도 결국 node pacakge 일뿐은 잊지말자!)

     

    The plugin creates File nodes from files. The various “transformer” plugins can transform File nodes into various other types of data e.g. gatsby-transformer-json transforms JSON files into JSON data nodes and gatsby-transformer-remark transforms markdown files into MarkdownRemark nodes from which you can query an HTML representation of the markdown.

    이걸 보면 이 플러그인은 File이라는 nodes를 만드는 것인데, 다양한 transformer plugin은 이 파일들을 다양한 형태의 data로 변환할 수 있다. 특히 나는 markdown파일을 변경하기 위해서 gatsby-transformer-remark를 사용하는데 좀 안맞는것들이 있어서 너무 화가나서 내가 만들기로 생각하고 도전중이다. 이 plugin의 경우 MarkdownRemark라는 노드를 생성한다. 

     

    {
          resolve: `gatsby-source-filesystem`,
          options: {
            name: `notes`, // sourceInstance에 나타나는 이름, 이걸로 filter를 걸수가 있다.
            path: `./src/notes`,
          },
        },

     

    이 플러그인을 만들기 위해선 우선 file 노드가 있어야한다. 그래야 걔를 읽어와서 장난을 치기 때문!

     

    - 나는 remark에서 파싱해주는게 뭔가 안맞아서, github.com/markedjs/marked 이걸 사용하려고 한다. 

     

     

    const marked = require("marked");
    const _ = require(`lodash`);
    
    // https://www.gatsbyjs.com/docs/how-to/plugins-and-themes/creating-a-transformer-plugin/#convert-yaml-into-json-for-storage-in-gatsby-nodes
    async function onCreateNode({
      node,
      actions,
      createNodeId,
      createContentDigest,
      loadNodeContent,
    }) {
      function transformObject(obj, id, type, content) {
        const mdNode = {
          obj,
          id,
          children: [],
          parent: node.id,
          internal: {
            contentDigest: createContentDigest(obj),
            type,
            content,
          },
        };
        createNode(mdNode); // 노드를 생성하는 부분
        createParentChildLink({ parent: node, child: mdNode }); // 이부분은 잘 모르겠다. 
      }
    
      const { createNode, createParentChildLink } = actions; // 이런것들은 actions내에 존재한다. api들
    
      // only log for nodes of mediaType `text/markdown`
      if (node.internal.mediaType !== `text/markdown`) {
        return;
      }
    
      const content = await loadNodeContent(node);
      const marked_content = marked(content); // marked를 사용할 수 있다. 
    
      //   marked_content.forEach((obj, i) => {
      const obj = marked_content;
      const i = 1;
      transformObject(
        obj,
        obj.id ? obj.id : createNodeId(`${node.id} [${i}] >>> MD`),
        _.upperFirst(_.camelCase(`${node.name} md`)),
        content
      );
    }
    
    exports.onCreateNode = onCreateNode;
    

     

     

    이렇게 플러그인을 만들면

    이렇게 노드가 생긴다. 

     

     

    이제 이 내부의 이미지만 어떻게 처리하면 되는데 그부분이 난관이긴하다. 

     

     

     

     

    후기

    플러그인 시스템이 편한건 맞는데, 아무래도 뭐하나 고칠려면 node환경이 아니라 Gatsby를 알아야해서 좀 어려운 점이 있는 것 같다. 근데 쓰다보면 점점 편해질것 같다는 생각도 들고, 일단 filesystem을 적극 활용할 수 있다는 것은 매력적인 것 같다. 

     

    꾸준히 간단한 사이트를 만들때는 사용해도 좋을 것 같아서 계속 심심할때 공부는 하려고 하는데, 좀 큰 서비스는 아무래도 Next.js가 좋지않을까 하는 생각이 든다!

     

    댓글

Designed by Tistory.