201026 블로그 제작일지

제작일지 · 2 ·

지난번엔 외적인 변화가 많았다면, 이번엔 외적인 변화는 크게 없이 내적인 변화가 많습니다.

Typescript!

타입스크립트

블로그에 사용하는 메인 자바스크립트 파일을 타입스크립트로 전환했습니다.
별다른 오류도 없고, 혼자 하는 프로젝트에다 규모가 아직은 코드를 거의 다 외울만한 수준이기에, 필요성이 높진 않습니다. 하지만 뭘 어떻게 개떡같이 써도 오류 없이 실행되게 하는 인자한 자바스크립트는 작은 실수를 쌓아가기 쉽고, 작은 실수들이 모이고 모여 결국 거대해져 건들기도 힘든 코드가 된다고 생각해 전환을 시작했습니다. 블로그 존재 이유가 프론트엔드 최신 기술 마음껏 테스트하는 공간이기도 하고요.

전환하면서 느낀 거지만, 생각보다 자잘한 실수가 잦았더라고요.
number를 넘겨야 하는데 string을 넘긴다거나, string이랑 number를 더한다거나, Date 객체끼리 뺄셈을 한다거나…사실 new Date() - new Date('2020-10-26')는 타입스크립트가 하지 말라고 눈치 줄 때까지 몰랐습니다.

확실히 마이크로소프트에서 제작해서 그런가 공식 문서가 상당히 깔끔히 정리돼있습니다. 자칫 거칠 수 있는 여정에 큰 힘이 되더라고요.

(<HTMLElement>headerContent.querySelector(".date")).innerText = humanTime(
    json.date.posted
);

물론 매번 이렇게 HTMLElement, HTMLImageElement 같은 거 일일이 추가해주고 interface 만들어다 추가해주고 이래저래 손보는 게 여간 귀찮은 게 아니었긴 합니다.

블로그 테마 언어

결국, 자바스크립트가 분화되며 CSS에게 1위 자리를 내줬네요.

모듈화

웹팩 빌드
웹팩으로 빌드하기

지금까지도, 제 블로그의 프론트엔드에서 돌아가는 자바스크립트는 head 태그에 있는 head.js, body 태그 끝에 있는 main.js가 끝입니다.
중요한 건, head.js는 정말 중요한 것만 들어있는 짧은 파일이니 그렇다 쳐도, 3,500줄가량 되는 main.js도 하나의 파일로 개발하고 있었단 겁니다.

이렇게 하다 보니, 이래저래 참조하는 것들이 얽히고설켜서 도무지 import / export를 똑바로 할 자신이 없어서 모듈로 뜯을 엄두도 못 냈는데, 날 잡고 얽힌 걸 풀기 시작하니 생각보다 금방 끝나더라고요.
덕분에 스크롤의 중압감에서 조금은 벗어났습니다. 이제 제일 긴 ts 파일(SPA로 업데이트하며 제작한 메인 컨테이너 업데이트하는 스크립트)이 1,300줄을 조금 넘네요.

웹팩 설정

자바스크립트만 있을 땐, 개발할 땐 script 태그에 type="module"을 추가하면 모든 게 끝났지만, 타입스크립트로 전환 후엔 자바스크립트로 빌드해야 해서 이래저래 손을 봐줘야 했습니다.
개발할 땐 Source Map이 필요하고, 난독화는 필요 없으나, 배포할 땐 Source Map이 필요 없고, 난독화가 필요합니다.

const path = require("path");
const WebpackObfuscator = require("webpack-obfuscator");

module.exports = (env=> {
    const isDevMode = env.mode === "development";
    let useSettings;

    if (isDevMode) {
        useSettings = "ts-loader";
    } else {
        useSettings = [
            {
                loaderWebpackObfuscator.loader,
                options: {
                    rotateStringArraytrue,
                },
            },
            "ts-loader",
        ];
    }

    return {
        modeenv.mode,
        entry"./src/js/main.ts",
        devtoolisDevMode ? "eval-source-map" : false,
        output: {
            filename"[name].js",
            pathpath.resolve(__dirname"dist"),
        },
        module: {
            rules: [
                {
                    test: /\.tsx?$/,
                    useuseSettings,
                    exclude: /node_modules/,
                },
            ],
        },
        resolve: {
            extensions: [".tsx"".ts"".js"],
        },
    };
};

module.exports를 함수로 만들고, 받아오는 인자를 확인해 개발 모드인지 배포 모드인지 확인하도록 했습니다.
처음 해보는 설정이라 잘 된 설정인진 모르겠네요…

"scripts": {
    "build""npx webpack --env.mode='production'",
    "devbuild""npx webpack --env.mode='development'"
}

그 후, package.json에 위 두 스크립트를 추가해 마무리했습니다.

링크 디자인

링크 디자인

메인 / 서브 색상을 배경색과 최대한 조화롭게 변경하니, 서브 색상으로 밑줄 그어서 링크임을 표시하는 게 눈에 거의 띄질 않게 되더라고요.
결국 링크에 사용할 색상을 테마별로 추가하고(Light - 짙은 파랑, Sepia - 보라, Dark - 밝은 파랑), 같은 탭에서 열리는 링크인지, 새 탭에서 열리는 링크인지 직관적으로 알 수 있는 아이콘도 추가했습니다.

글꼴

고도체

전 도무지 Noto Sans 같은 '기본 글꼴스러운' 폰트는 못 봐주겠습니다.
어지간한 피드백은 수용하는 편이며, "피드백을 수용하기 싫으면 디자이너를 하지 말고 아티스트를 해라"란 말에 동감 또한 하는 편입니다만, 블로그에 쓰는 글꼴은 도무지 양보 못 하겠네요.

못생긴 기본 글꼴 같은 폰트를 보고 있자니, 화딱지가 나서 가독성이 떨어질 지경이라 마음에 드는 폰트로 바꿨습니다.

지금까지 폰트를 고르는 제1순위는 소이 말하는 '외계어'의 지원이었는데, 이번엔 그냥 외계어 지원 여부는 제쳐놓고 마음에 드는 폰트를 골라봤습니다.
애당초 정말 특수한 경우가 아니면 표준어의 사용을 지향하기에, 폰트가 지원하지 않는 글자를 써본 적도 없네요.

Header & Navigation

HTML 태그에도 제가 모르는 게 하나 있었습니다.

지금까진 상단에 고정되는 내비게이션을 헤더라 부르며 header 태그를 사용하고, 썸네일과 제목 등이 들어가는 부분을 배너라 부르며 div(배너 태그는 당연히 없음) 태그를 사용했는데, 세상에나 제가 이상하게 쓰고 있었습니다.

상단에 고정되는 걸 내비게이션이라 부르고 nav 태그를 쓰고, 썸네일과 제목 등이 들어가는 부분을 헤더라 부르며 header 태그를 쓰더라고요.

올바르게 수정했습니다.

네비게이션 블러

이건 이전 제작일지에 포함되었어야 하는 건데, 써야 한다고 메모는 실컷 해놓고 쓰질 않아 이번에 씁니다.

상단 네비게이션에 backdrop-filter를 추가했으며, 블러, 채도 향상 두 가지 필터를 이용해 최대한 자연스러운 블러 효과를 구현해봤습니다.
채도(saturation)를 안 건드리니까 네비게이션 배경색이 섞여 색이 좀 이질적으로 나오더라고요.

CDN 서버 변경

지금까진 이미지 캐시 서버가 CDN 서버도 겸하고 있었는데, 이번에 jsdelivr라는 CDN을 이용해 이미지 캐시 서버에서 CDN 서버를 떼어냈습니다.
속도는 얼추 비슷비슷한 것 같네요.

Textarea 자동 높이 조절

textarea의 높이가 입력한 글자에 맞게 자동으로 조정되는 스크립트에 textarea의 높이가 너무 길어져버리면 스크롤이 최하단에 박혀버리는 문제가 있었는데, 이를 스크롤을 textarea의 최하단에 고정하는 방식으로 해결했었습니다.
이는 뷰포인트 밖의 글자를 수정할 수 없는 문제가 있었는데, 아주 간단하게 이를 해결했습니다.

const autoExpand = () => {
    const { scrollY } = window;
    const textarea = document.getElementById("myTextarea");
    textarea.style.height = "auto";
    textarea.style.height = `calc(${textarea.scrollHeight}px + 1rem)`;
    window.scrollTo(0scrollY);
};

이렇게 textarea의 높이를 조절하기 전에 scrollY를 저장해두고, 높이를 조절한 뒤 다시 그 위치로 스크롤 해주면 되는 문제였습니다.

로더, 다운로드 아이콘 수정

로더를 돌리느라 추가했던 css를 제거하고, 순수 svg만으로 애니메이션을 제작했습니다.
다운로드 아이콘에도 마찬가지로 순수 svg만으로 애니메이션을 추가해뒀습니다.

이제 svg도 필요한 만큼은 다룰 줄 알겠네요.

검색

  • ESC 버튼으로 검색을 취소할 수 있게 업데이트했습니다.
  • 검색 후 확인 버튼을 누르면 검색창에 포커스된 게 취소됩니다.

기타

  • 404 페이지에서 링크를 클릭해 넘어오면 404 페이지에서 추가된 CSS가 블로그 전체에 영향을 주는 걸 수정했습니다.
  • 이미지 레이어의 이미지가 이미지 레이어를 닫고 350ms(애니메이션 표시되는 시간)가 지나면 로더 이미지로 변경되게 했습니다.
  • 댓글에 링크와 메일을 추가해주는 기능에서, 메일을 감지하던 정규표현식을 업데이트해 골뱅이만 들어가면 일단 메일로 감지하고 보는 걸 수정했습니다.
  • IE를 지원하지 않는다는 문구를 표시하는 CSS를 제거했습니다.
  • 답글을 입력할 때 확인 버튼의 화살표가 위를 향하게 업데이트했습니다.
  • humanTime(시간을 2일 전 등으로 표시해주는 함수)의 의미 없는 Math.ceil을 제거했습니다.
  • 페이지 하단에 고정된 버튼(구독, 최상단으로 스크롤)의 색상을 배경색과 좀 더 어울리게 수정했습니다.
  • 테마 변경 버튼의 위치를 드로어 최상단으로 옮겼습니다.
  • 스크롤바의 그래디언트를 제거했습니다.
  • 텍스트가 사라지는 것처럼 보이게 하는 그래디언트의 위치와 크기를 조정해 좀 더 텍스트가 사라지는 것처럼 보이게 업데이트했습니다.
profile

이메일은 공개되지 않습니다.

주의 : 비밀 댓글 사용 시 수정 기능을 이용할 수 있는 시간이 지나면 작성자도 내용 확인이 불가능합니다.
    카카오페이 qr코드 모바일이시라면 클릭