05/20 발표 - 이든/삽질의 기록…Permalink

1. PDF 너… 이자식…!Permalink

문제Permalink

PDF가 일부만 보여지고 짤려서 보임

HCMONEYBALL-4240

https://jira.daumkakao.com/browse/HCMONEYBALL-4240

여기는 두개 문제가 있었습니다.

1) ‘일부만’ ⇒ pdf가 한 페이지까지만 생성됨

// pdf.ts

const doc = new jsPDF("p", "mm", "a4", true);
const paperElements = document.querySelectorAll(
  `.preview-page`
) as NodeListOf<HTMLElement>;
// 페이지 출력
for (let el of paperElements) {
  const canvas = await html2canvas(el, { scale: 2 });

  const imgData = canvas.toDataURL("image/png");
  const imgWidth = 210; // 이미지 가로 길이(mm) A4 기준
  const imgWidthRatio = 210 / canvas.width;
  const pageHeight = imgWidthRatio * canvas.height;

  doc.addPage();
  doc.addImage(imgData, "jpeg", 0, 0, imgWidth, pageHeight);
}

doc.deletePage(1); // 첫번째 생성 이미지 삭제

기존의 로직에서는 addPage()로 페이지를 만들고 image를 추가해 줍니다.

이를 a4사이즈만큼 여러장으로 만들려면 이미지가 a4 사이즈를 넘어갈 때 잘라 주면 됩니다.

for (let el of paperElements) {
  const canvas = await html2canvas(el, { scale: 2 });

  const imgData = canvas.toDataURL("image/png");

  const imgWidth = 210;
  const pageHeight = 297;
  const imgHeight = (canvas.height * imgWidth) / canvas.width;
  let heightLeft = imgHeight;
  let position = 0;
  doc.addImage(imgData, "jpeg", 0, 0, imgWidth, imgHeight);
  heightLeft -= pageHeight;
  while (heightLeft >= 0) {
    position = heightLeft - imgHeight;
    doc.addPage();
    doc.addImage(imgData, "jpeg", 0, position, imgWidth, imgHeight);
    heightLeft -= pageHeight;
  }
}
  1. 짤려서’ ⇒ 요소 중간을 짤라버림

이친구가 사곤데…

위의 방법으로 여러 페이지에 데이터를 나눠도… 짤리는건 동일합니다.

Untitled

PastaConnect_Report_20240518_1834.pdf

문제의 원인Permalink

1)은 패스하고 2)문제의 원인을 살펴보면 우리가 pdf를 만드는 방식은

1️⃣ preview html 요소(+ag-grid) 렌더링

2️⃣ html2canvas에서 DOM에서 읽은 속성을 스크린 샷찍음

3️⃣ jsPdf를 통해 2️⃣에서 찍은 이미지를 pdf로 만듬

이러한 방식으로 동작합니다.

1)에서 시도한 방식은 2️⃣ → 3️⃣ 시에 a4사이즈만큼 이미지를 단순히 자른 것이기 때문에 요소가 짤려서 나오는 것입니다.

이런 현상을 우리만 겪었을리 없다..!라는 희망으로 구글링 중 jsPdf에서 한가지 이슈를 발견했습니다.

[https://github.com/parallax/jsPDF/issues/1699](https://github.com/parallax/jsPDF/issues/1699)

https://github.com/parallax/jsPDF/issues/1699

어어어…!!!!

html2pdf 너라면..?Permalink

2013-11-03_163B303B54.jpg

이거다..! 하고 도파민 터지며 html2pdf를 열심히 찾았습니다.

찾은 html2pdf.js 라이브러리에서 해당 내용을 확인하고 신나서 바로 적용을 해봤습니다.

[https://ekoopmans.github.io/html2pdf.js/#page-breaks](https://ekoopmans.github.io/html2pdf.js/#page-breaks)

https://ekoopmans.github.io/html2pdf.js/#page-breaks

급하게 먼저 페이지가 제대로 나눠지는지 확인하기 위해서 MealPattern 에만 바로 적용해봤습니다.

심지어 사용법도 매우 간단했습니다!!!!!! (도파민 폭팔.)

const paperElements = document.querySelectorAll(
  `.preview-content-2`
) as NodeListOf<HTMLElement>;

const opt = {
  filename: `PastaConnect_Report_${dayjs().format("YYYYMMDD_HHmm")}.pdf`,
  image: { type: "jpeg" },
  html2canvas: { scale: 2 },
  jsPDF: { unit: "mm", format: "a4", orientation: "portrait", compress: true },
  pagebreak: { mode: "avoid-all" },
};
const doc = html2pdf().from(paperElements[0]).set(opt);

바로 적용해보니

흐흐흐흫,,ㅎㅎ

흐흐흐흫,,ㅎㅎ

이게 되네??

이게 되네??

됐다..!.pdf

나눠진다!!!!!!

하지만 오른쪽에 이미지가 깨지는 현상이 있습니다.

이정도야 뭐~~ 이미지 a4사이즈로 맞추면 되겠지~~~~~(행복회로 풀가동)하고 사이즈를

이미지의 사이즈를 바꿔봤지만 jsPdf의 addImage와는 다르게 이미지를 jsPdf format에 맞춰 압축이 되지 않았습니다..

그러던 도중 html2pdf.js에서 이슈하나를 만나게 되었습니다,,,

https://github.com/eKoopmans/html2pdf.js/issues/6

https://github.com/eKoopmans/html2pdf.js/issues/6

위의 이슈 내용을 요약하자면

이미지를 pdf에 맞춰서 줄이고 싶다 → 만들 예정이다 하지만 아직은 아니다 (2017.05)

그리고 7년이 지난 2024년의 저는 이제서야 도파민에 중독되서 보이지 않던 게 보이기 시작했습니다

??

??

아.. 버려진 라이브러리구나..

아안대.>!!

아안대.>!!

절망하던 찰나에 img → pdf로 사이즈를 맞출 수 없다면 pdf → img로 사이즈를 맞춘다면??

라는 생각으로 pdf를 a4사이즈가 아닌 img에 width 사이즈에 맞추고 a4 비율만큼 height를 정해서 나줘줬습니다.

흐음…

흐음…

비참하구만…pdf

그렇게 반쪽 짜리 해결을 하고 1차전을 마무리 했습니다.

그래도 얻은 건 있습니다.

  1. ag-grid의 요소별로 page-break를 할 수 있다는 희망
  2. page-break를 해주는 건 js가 아니라 css의 page-break 속성값으로 결정한다는 정보

그리고 거스, 제로에게 공유 후 제로와 함께 2차전을 시작했습니다.

2차전 시작Permalink

1차전에서 얻은 정보를 토대로 2차전에서 해볼 시도들을 정리해봤습니다.

시도해보기Permalink

  1. css의 page-break 속성 동작방식 알아보기
  2. html2pdf 소스코드를 까보기
  3. 새로운 방식의 접근

page-break 트리거Permalink

구 page-break-inside 현 break-inside 속성은 해당 요소 내에서 페이지 나누기, 열 나누기 같은 영역 나누기가 발생해야 하는지 여부를 지정합니다.

page-break-inside : avoid;

break-inside : avoid;

를 하면 페이지를 나눌 때 요소가 걸쳐있으면 나눠지지 않고 다음 페이지에 온전히 넘어오게 됩니다.

출처 : http://www.mins01.com/mh/tech/read/1360

출처 : http://www.mins01.com/mh/tech/read/1360

MDN설명 : https://developer.mozilla.org/en-US/docs/Web/CSS/break-inside

더 확실한 설명을 위해 CSS 스팩을 찾아보면

참고(CSS 스팩): https://drafts.csswg.org/css-break/

참고(CSS 스팩): https://drafts.csswg.org/css-break/

위와 같이 설명이 되어있습니다. 딱 우리가 원하는 기능이죠ㅠㅠ

이 속성이 적용되는 breaking point도 찾아볼 수 있었습니다.

참고(CSS 스팩): https://drafts.csswg.org/css-break/

참고(CSS 스팩): https://drafts.csswg.org/css-break/

요약하자면 조각화는 블록 및 인라인 차원에서만 분할이 되며

가능한 중단점은 블록 컨테이너 사이가 페이지를 나눌 때, 열을 나눌 때, 지역을 구분할 때(지역은 무슨말인지 모르겠어요…)입니다.

그리고 이러한 조각화가 적용되지 않는 경우는

  1. 이미지, 비디오
  2. 스크롤 가능한 요소
  3. 한 줄의 텍스트
  4. 인라인 블록, 인라인 테이블 상자
  5. 너무 큰 요소

등이 있습니다.

ag-grid에서도 이를 해결하기 위해 domLayout이라는 속성이 있고 print 값을 넣어주면 스크롤이 풀리며 print용으로 레이아웃을 변경하는 식으로 해결했습니다.

화면 기록 2024-05-18 오후 9.39.06.mov

ag-grid의 page-break : https://www.ag-grid.com/react-data-grid/printing/#page-break

html2pdf 소스코드를 까보기Permalink

html2pdf라는 버려진 라이브러리를 사용할 수는 없기 때문에 어떻게 문제를 해결해 왔는지만 참고해서 합쳐보려고 했습니다.

page-break를 하는 핵심 로직은 이부분입니다.

Worker.prototype.toContainer = function toContainer() {
  return orig.toContainer.call(this).then(function toContainer_pagebreak() {
    // Setup root element and inner page height.
    var root = this.prop.container;
    var pxPageHeight = this.prop.pageSize.inner.px.height;

    // Check all requested modes.
    var modeSrc = [].concat(this.opt.pagebreak.mode);
    var mode = {
      avoidAll: modeSrc.indexOf("avoid-all") !== -1,
    };

    // Get all legacy page-break elements.
    var legacyEls = root.querySelectorAll(".html2pdf__page-break");
    legacyEls = Array.prototype.slice.call(legacyEls);

    // Loop through all elements.
    var els = root.querySelectorAll("*");
    Array.prototype.forEach.call(els, function pagebreak_loop(el) {
      // Setup pagebreak rules based on legacy and avoidAll modes.
      var rules = { avoid: mode.avoidAll };

      // Add rules for css mode.
      if (mode.css) {
        rules = { avoid: rules.avoid };
      }

      // 뷰포트와 상대적 위치정보 제공
      var clientRect = el.getBoundingClientRect();

      // Avoid: Check if a break happens mid-element.
      if (rules.avoid && !rules.before) {
        var startPage = Math.floor(clientRect.top / pxPageHeight);
        var endPage = Math.floor(clientRect.bottom / pxPageHeight);
        var nPages =
          Math.abs(clientRect.bottom - clientRect.top) / pxPageHeight;

        // Turn on rules.before if the el is broken and is at most one page long.
        if (endPage !== startPage && nPages <= 1) {
          rules.before = true;
        }
      }

      // Before: Create a padding div to push the element to the next page.
      if (rules.before) {
        var pad = createElement("div", {
          style: {
            display: "block",
            height: pxPageHeight - (clientRect.top % pxPageHeight) + "px",
          },
        });
        el.parentNode.insertBefore(pad, el);
      }
    });
  });
};

그리고 html2pdf가 작동하는 순서를 보면

Untitled

.toContainer() 이후 .toCanvas()를 하는 것을 알 수 있습니다.

미리 요소를 짤리지 않게 페이지를 나눈 후(패딩을 주는식으로 format에 맞춤) canvas로 그려내고 pdf를 만드는 식으로 작동합니다.

새로운 방식의 접근Permalink

먼저 ag-grid에 있는 domLayout = "print" 속성이 어떻게 작동하는지를 까보니

ag-layout-print라는 클래스를 추가하여

css 속성을 변경하는 식으로 작동했습니다.

/*ag-grid*/
.ag-layout-print {
  &.ag-body {
    display: block;
    height: unset;
  }

  &.ag-root-wrapper {
    /* this has to be inline-block otherwise the grid gets constrained by
        the viewport (AG-5616) and other values like `inline-flex` will add a
        small gap at the top (AG-9296) */
    display: inline-block;
  }

  .ag-body-vertical-scroll {
    display: none;
  }

  .ag-body-horizontal-scroll {
    display: none;
  }

  &.ag-force-vertical-scroll {
    overflow-y: visible !important;
  }
}

@media print {
  .ag-root-wrapper.ag-layout-print {
    display: table;

    .ag-root-wrapper-body,
    .ag-root,
    .ag-body-viewport,
    .ag-center-cols-container,
    .ag-center-cols-viewport,
    .ag-body-horizontal-scroll-viewport,
    .ag-virtual-list-viewport {
      /* Need auto height because 100% height elements with overflow hidden
      cause printing issues in Edge */
      height: auto !important;
      /* Overflow hidden, because otherwise scroll bars print in IE */
      overflow: hidden !important;
      /* flex elements cause printing issues in Firefox
            https://bugzilla.mozilla.org/show_bug.cgi?id=939897 */
      display: block !important;
    }
    .ag-row,
    .ag-cell {
      break-inside: avoid;
    }
  }
}

여기서도 알 수 있듯, 결국 page-break를 해주기 위해서 break-inside, display, height, overflow 속성을 변경하는 식으로 구현하였습니다…ㅜㅜ

ag-grid커뮤니티에 pdfmake라이브러리와 함께 구현한 예시가 있습니다.

Exporting AG Grid to PDF with pdfMake

이것도 작동 방식을 보니 ag-grid의 값들을 가공해서 개별 페이지 만큼 자른 후 document를 생성 후 pdfMake에게 보내서 pdf를 만듭니다.

여러 삽질 끝에 얻은 결론은…

결국 ‘이미지로 만들기 전’ or ‘pdf로 만들기 전’에 정해진 영역만큼 나눠야지만 짤림현상을 해결할 수 있다… 라는 결론이 나왔습니다.

그 과정에서 css 스팩에 명시되어있는 page-break 중단점 부분을 살펴보면 페이지 뿐만 아니라 우리가 정한 기준으로 나눌 수 있지 않을까? 하는 기대가 있습니다,,,🥹

2. next-i18next에게 뒷통수 맞은 썰Permalink

next-i18next에서 설정바꾸면 accept-language 기준으로 locale정할 수 있다고 했지만… locale만 바뀔뿐 lang는 url을 따라갑니다ㅜ (해준다메에에에!!!!)

에잉 쯧쯧쯧,,,

에잉 쯧쯧쯧,,,

문제Permalink

url에 ja를 붙이지 않으면 일어 폰트가 깨지는 현상(body에 font 적용이 안됨)

폰트가 깨지는 상황을 정리하면

  url included 브라우저 언어 초기렌더링 lang 이후 렌더링 lang  
case1 ja ja en ja 폰트깨짐
case2 ja ko en ja  
case3 ko ja en ko 폰트깨짐
case4 ko ko en ko  

case1, 3인경우에 깨지는 것을 알 수 있습니다.

원인Permalink

폰트가 깨지는 이유는 html lang가 제대로 입력 되지 않았기 때문이었습니다!! (대장님짱)

이를 해결하기 위해 두가지 문제를 해결해야 했습니다.

  1. 초기 렌더링 시 폰트 적용 안되는 현상

: _ducument.tsx에 html lang가 en으로 고정되어있었고, next-i18next가 작동하는 시점이 _document 이후 이기 때문에 초기 렌더링 시에 accept-language가 적용이 안됐습니다.

  1. 이후 렌더링 시 적용 안되는 현상

현재 구성되어있는 next-i18next에서 언어를 변경하는 로직이 sub-path Routing을 따르며 자동 로케일 감지를 하고 있습니다.(localeDetection: true (기본값))

이게 동작하는 방식이 애플리케이션 ‘루트’를 방문했을 때 accept-language를 감지하고

  1. locales 배열 안에 있는 값이 있으면 locale이 붙은 경로로 리다이렉션 시켜주며 이후 하위 경로 라우팅합니다.

  2. locales배열 안에 없을 경우 defaultLocale로 리다이렉션됩니다. 이때 각각 페이지에서 SSR, SSG를 통해 locales은 맞췄지만 langdefaultLocale 그대로 따라갑니다.

테스트 결과 SSR시에는 accept-language를 따라 lang가 결정되지만 하이드레이션 이후 url을 따라 lang가 변경 됩니다.(url에 ko, en, ja 가 포함안되어있으면 deafultLocale값인 ko 선택)

(참고 : https://nextjs.org/docs/pages/building-your-application/routing/internationalization#automatic-locale-detection)

이때 의료진 모드의 각각 환자 정보를 들어갈 경우 router를 통한게 아닌 window.open으로 새창이 열리며 로케일이 풀립니다.

⇒ 현재 임시로 window.open을 accept-language 기준으로 로케이션이 붙은 url로 보내도록 util화해 해결한 상태입니다.

결과Permalink

원인1) 초기 렌더링 시에 lang에 accept-language 적용

이를 위해 _document가 렌더링 시 lang를 적용하기 위해서 lang가 accept-language에 따라 바뀌도록 동적으로 변경했습니다.

(참고 : https://nextjs.org/docs/pages/building-your-application/routing/custom-document)

적용 후 결과는 아래와 같습니다.

  • lang=”ko” : ko폰트적용
  • lang=”ja” : ja폰트적용
  url included 브라우저 언어 초기렌더링 이후 렌더링  
case1 ja ja lang=”ja” lang=”ja”  
case2 ja ko lang=”ko” lang=”ja”  
case3 ko ja lang=”ja” lang=”ko” 폰트깨짐
case4 ko ko lang=”ko” lang=”ko”  

case1, 4는 정상이고

case2는 한국어에서 ja폰트를 사용할 때는 jp가 없어서 Pretendard로 적용이 되어 문제가 없지만

case3에서 일어로 렌더링 되는데 lang=”ko”로(ko폰트) 적용되서 깨지는 현상이 남아있습니다.

이 경우가 원인 2)에 해당합니다.

그럼 어디서 어떻게 lang가 바뀌는지를 보면…

_document ⇒ accept 기준

_app / server ⇒ accept 기준

_app / client ⇒ accept 기준

각 하위페이지 server ⇒ accept 기준

각 하위페이지 client ⇒ url 기준

문제 상황 : 하이드렉션 이후 client에서 인터렉션 하면 url 기준으로 lang가 정해진다.

시도

  1. layout으로 감싸서 document.lang 변경 ⇒ 실패

  2. 각페이지에서 docuemnt.lang 변경 ⇒ 랜덤하게 성공(순서 꼬이는듯)

이것저것 별 짓 다해봤지만,,, next-i18next는 url 기반으로 동작하기 때문에 수정할 수 없을 것 같다는 결론이 나왔습니다… (각 페이지에서 document.lang도 바꿔봤지만 랜덤하게 적용되며 깜빡거린다ㅜ )

제가 생각한 결론은 아래와 같습니다.

  1. window.open ⇒ router.push로 변경

이렇게 하면 행복하지만, 새창의 띄운 히스토리를 몰라서 제가 바꾸기가 애매해 냄겨뒀슴돠,,ㅎ,,

⇒ 추후 로케일을 뺄 것이기 때문에 반려.

  1. window.open 시 로케일 탐색

이렇게 할 경우 모든 곳에 적용을 위해 window.open을 감싸서 utils화 하는게 좋을 것 같습니다!!

⇒ 현재 방법 window.open 사용시 accept-language에서 locale을 검색하여 새창을 띄울 url 앞에 추가해주는 식으로 감싸서 사용하는 것을 의미했습니다!

const windowOpen = (url: string) => {
  const lang = navigator.languages[0]; //사용자가 브라우저 설정에서 지정한 선호 언어 목록 중 1위
  const newWindowURL = `/${lang}${url}`;
  window.open(newWindowURL);
};
  1. next-i18next에서 accept-langue를 탐색하도록 변경

현재 이렇게 동작을 하는 것으로 알고있는데 langdefaultLocale을 따라가는 거 보니 lang는 루트에서 만 accept-language에 따라 변경 후 하위 라우팅에서는 url을 따르는게 아닐까 의심됩니다.(관련 자료를 못찾았어요ㅜ )

  1. next-i18next ⇒ next-translate 로 이사가기

⇒ 유력 후보

기본적으로 next-i18next는 url을 기준으로 locale을 정합니다. 우리는 이거를 accept-language를 기준으로 하도록 설정해서 사용하는 것이었구요

비슷한 기능을하는 국제화 라이브러리인 next-translateaccept-language를 기준으로 loacle을 정합니다.

이후 url에서 locale을 뺄 예정이라면 next-translate로 마이그레이션 하는게 좋을 듯합니다(좀 더 찾아보고 테스트 후에,,,)

이렇게 하면 유저가 루트(/)에서 접근했을 경우 locale이 항상 붙어있어서 임의로 url을 수정하지 않는 이상 locale이 항상 붙어있어서 정상적으로 작동합니다.

3. 다음 스터디 발표 스포Permalink

겪고 있는 문제점Permalink

저에게 온 티켓들을 구현하면서 애매함을 느낄때가 있었습니다.

  1. 새로만든 컴포넌트를 어디에 넣지?
  2. 내가 이거 수정하면 어디 터지는거 아니야..?
  3. A의 동작을 어디서 확인해야 하지..?

규모가 커질수록 개개인이 구현한 기능과 연관된 코드를 탐색하는 것도 어려워 질 것이고,

특정 도메인에 사용되는 코드들이 흩어져 있으면 찾기 힘들 것입니다.

내가 수정하는 코드가 다른 사람이 미리 만들어 놓은 기능에 어디까지 영향을 끼치며 버그를 불러일으키는지 확신할 수 없기 때문에 두려움을 안고 수정하게 됩니다.

images.jpg

여기에 알맞은 FSD 아키텍쳐를 발견했습니다.

FSD(Feature-sliced Design)Permalink

FSD는 FE앱을 스캐폴딩하기 위한 아키텍처 방법론입니다.

BasePermalink

FSD의 구성은 크게 Layers, Slices, Segments로 이루어져있습니다.

visual_schema-e826067f573946613dcdc76e3f585082.jpg

각각의 역할은

LayersPermalink

  1. app

    — 앱 전체 설정, 스타일 및 공급자.

  2. pages

    — 엔터티, 기능 및 위젯으로 전체 페이지를 구성하는 구성 레이어입니다.

  3. widgets

    — 엔터티와 기능을 의미 있는 블록으로 결합한 독립적인 UI (예: IssuesList, UserProfile)

  4. features

    — 사용자 상호 작용, 사용자에게 비즈니스 가치를 제공하는 기능 (예: SendComment, AddToCart, UsersSearch)

  5. entities

    — 비즈니스 엔티티(예: 사용자, 제품, 주문)

  6. shared

    — 프로젝트/비즈니스의 세부 사항과 분리된 재사용 가능한 기능입니다. (예: UIKit, libs, i18n, API)

    ** 비즈니스와 분리된 곳이기 때문에 slices 단계가 없습니다.

SlicesPermalink

feature-sliced-design-04.png

비즈니스 도메인 별로 분리된 폴더이며 특정 비즈니스 엔티티에 대한 것으로 그룹화 한 것입니다.

동일한 layer에 다른 slice를 사용할 수 없다 는 규칙을 갖고 있습니다. (<= 높은 응집력, 낮은 결합도)

SegmentsPermalink

기술적 목적에 따라 slice내 코드를 분리하는데 도움을 주는 작은 모듈입니다.

몇 가지 표준화된 segment 로는 아래와 같이 있습니다.

  1. ui

    — UI 구성 요소, 데이터 형식 지정 기능

  2. model

    — 비즈니스 로직, 데이터 저장 및 이 데이터를 조작하는 기능

  3. lib

    — 보조 및 인프라 코드

  4. api

    — 외부 API, 백엔드 API 메소드와의 통신

이 아키텍쳐의 핵심은

  1. 자신보다 낮은 layer의 코드만 가져올 수 있다. (추상화, 다형성, 상속)
  2. 공개 API를 사용해서만 import 가능하다. (캡슐화)

를 통해

코드는 영향 범위(레이어), 도메인(슬라이스), 기술적 목적(세그먼트)별로 구성되고

이는 신규 사용자가 쉽게 이해할 수 있는 표준화된 아키텍처를 생성합니다. (라고 공식 문서에서 말합니다)

그리고 우리가 생각하고 있는 도메인 별 분리(slice가 대체) / 디자인 시스템 개선(shared에 ui키트) 시에도 시너지가 날 것 같습니다.

하지만 아토믹 디자인때도 그랬듯 이상과 현실을 다르기때문에 조금이라도 써보고 실제 사용 경험을 토대로 주장하는 것이 맞다고 생각합니다.

그래서 다음 발표(06/17)는 지금 구현중인 처방전을 완료 후 FSD로 마이그레이션 해보겠습니다…!

마이그레이션 전략Permalink

기존의 서비스에서 FSD로 넘어가기 위해서는 점진적인 채택이 불가피 합니다.

공식문서의 추천방법은

  1. 가장 작은 규모부터 채워나간다.(1st. app 2nd. shared)
  2. FSD 규칙을 위반 하더라도 일단 기존 UI를 모두 widgets에 박는다.
  3. features와 entities를 분리하고 page와 widgets을 로직이 있는 layer에서 pure한 layer로 옮긴다.

리팩토링 기간에 새로운 대규모 엔티티를 추가하지 않는게 좋다…

⇒ 큰 작업이 걸려있지 않을 때 시도해보자!!


참고Permalink

공식문서 : https://feature-sliced.design/docs/get-started/overview

공식문서(튜토리얼) : https://feature-sliced.design/docs/get-started/tutorial

정리본0 : https://www.youdad.kr/feature-sliced-design/#google_vignette

정리본1(한국어 번역) : https://emewjin.github.io/feature-sliced-design/

정리본2(단테): https://velog.io/@jay/fsd

예시(react-query) : https://github.com/ani-team/github-client

마치며…Permalink

주저리주저리 썼지만 쓰다보니 무엇하나 완벽하게 마무리 한 게 없다는 아쉬움만 남네요🥹

다음 발표에서는 고난과 역경뿐만 아니라 해결사례도 함께 담을 수 있기를 소망합니다,,,

PDF 너…이자식…

PDF 너 이자식…2

다국어 지원 에러 해결

댓글남기기