Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"plugins": ["import"],
"extends": ["next/core-web-vitals", "plugin:import/recommended"],
"rules": {
"no-unused-vars": [
"warn",
{
"argsIgnorePattern": "^_",
"varsIgnorePattern": "^_"
}
],
"import/named": 0,
"import/order": [
"error",
{
"newlines-between": "always",
"groups": [
"type",
"builtin",
"external",
"internal",
"parent",
"sibling",
"index",
"unknown"
],
"pathGroups": [
{
"pattern": "next*",
"group": "external",
"position": "before"
},
{
"pattern": "react*",
"group": "external",
"position": "before"
},
{
"pattern": "src/@hooks/**",
"group": "internal",
"position": "after"
},
{
"pattern": "src/@Component/**",
"group": "internal",
"position": "after"
},
{
"pattern": "src/@utils/**",
"group": "internal",
"position": "after"
}
],
"pathGroupsExcludedImportTypes": [
"next*",
"react*",
"src/@hooks/**",
"src/@Component/**",
"src/@utils/**"
],
"alphabetize": {
"order": "asc",
"caseInsensitive": true
}
}
]
}
}
67 changes: 67 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# lighthouseci
.lighthouseci
/lhci_reports/

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

.env

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

.lighthouserc.js
.commitlint.config.js

# typescript
*.tsbuildinfo
next-env.d.ts

# Sentry Auth Token
.sentryclirc
.sentry.client.config.ts
.sentry.edge.config.ts
.sentry.server.config.ts

.tsconfig.json

public

posts
.next
.vercel
.lighthouseci
.husky

lhci_reports
.vscode
# package.json
package-lock.json

public
108 changes: 108 additions & 0 deletions lib/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import fs from 'fs';
import { join, basename } from 'path';

import matter from 'gray-matter';

const PostDirectory = join(process.cwd(), 'posts');
const ImageDirectory = join(process.cwd(), 'public/images');

export function getPostSlugs() {
return fs.readdirSync(PostDirectory);
}

export function getPostBySlug(slug: string, fields: string[] = []) {
const realSlug = decodeURIComponent(slug.replace(/\.md/, ''));
const fullPath = join(PostDirectory, `${realSlug}.md`);
const fileContent = fs.readFileSync(fullPath, 'utf-8');
const { data, content } = matter(fileContent);

type Item = {
[key: string]: string;
};
const items: Item = {};

fields.forEach((field) => {
if (field === 'slug') {
items[field] = realSlug;
}
if (field === 'content') {
items[field] = content;
}
if (typeof data[field] !== 'undefined') {
items[field] = data[field];
}
if (field === 'image') {
const imagePath = join(ImageDirectory, data[field]);
}
});

return items;
}

export function getAllPosts(fields: string[] = []) {
const slugs = getPostSlugs();
const posts = slugs
.map((slug) => getPostBySlug(slug, fields))
// sort posts by date in descending order
.sort((post1, post2) => (post1.date > post2.date ? -1 : 1));
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

내림차순으로 정렬을 하고 싶은 경우 sort((a, b) => b - a) 를 하면 됩니다!
이 경우 sort((post1, post2) => post2.date - post1.date)가 될 것 같네요.


return posts;
}

export function getInitPosts(fields: string[] = []) {
const slugs = getPostSlugs();
const posts = slugs
.map((slug) => getPostBySlug(slug, fields))
.sort((post1, post2) => (post1.date > post2.date ? -1 : 1))
.slice(0, 5);

return posts;
}

export function getAllPostRequest(fields: string[] = []) {
const slugs = getPostSlugs();
const posts = slugs
.map((slug) => getPostBySlug(slug, fields))
// sort posts by date in descending order
.sort((post1, post2) => (post1.date > post2.date ? -1 : 1));
Comment on lines +54 to +67
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Post를 받아오고 내림차순하는 로직이 여러번 반복되고 있는 것 같아요!

코드의 반복을 개선할 수 있는 방법이 있지 않을까요??

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 코드의 반복을 막기 위해
Post를 받아오고 내림차순으로 반환하는 역할을 하는 함수를 만들고 이 함수를 재사용하면 될 것 같아요!
혹시 더 좋은 방법이 있을까요?!?!

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 그렇게 할 것 같아요!!


return {};
}

//리팩토링 필요한 부분
export function getAllCategories() {
const allPosts = getAllPosts(['category']);

const allCategory = new Map<string, number>();

allPosts.map((post) => {
const getCategory = allCategory.get(post.category);
if (getCategory) {
allCategory.set(post.category, getCategory + 1);
return;
}

allCategory.set(post.category, 1);
});
Comment on lines +78 to +86
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mapforEach의 차이를 한번 생각해보시면, 이 상황에서는 map이 적절한지, forEach가 적절한지 알 수 있을 것 같아요!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 상황에서는 forEach가 더 적당한 것 같네요..!! 감사합니당


return Array.from(allCategory).map(([category, categoryCount]) => {
return {
category: category,
categoryCount: categoryCount + '',
};
});
}
Comment on lines +88 to +94
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

객체를 바로 반환하려고 의도하신 것 같아요! 이렇게 할 수도 있지 않을까요??

Array.from(allCategory).map(([category, categoryCount]) => (
  {
    category: category,
    categoryCount: categoryCount + '',
  }
));


export function getCategoryFilteredPosts(
fields: string[] = [],
category: string
) {
const slugs = getPostSlugs();
const posts = slugs
.map((slug) => getPostBySlug(slug, fields))
// sort posts by date in descending order
.sort((post1, post2) => (post1.date > post2.date ? -1 : 1))
Comment on lines +101 to +104
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀

.filter((post) => post.category === category);

return posts;
}
3 changes: 3 additions & 0 deletions lib/makeToc.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function makeToc({ children }: { children: string }) {
return children.match(/(?:##|###)(.*)/g);
}
Comment on lines +1 to +3
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Table of Content의 약자로 Toc라고하신 것 같은데, Toc같은 경우 하나의 단어인 것 처럼 느껴져요.
저는 약자의 경우 모두 대문자로 처리해서 확실하게 약자라는 것을 보여주려고 하는 편이에요!

그리고 TOC라고 하더라도, 경우의 수가 적지 않을 것 같은데 명시적으로 TableOfContent는 어떨까요?

13 changes: 13 additions & 0 deletions lib/markdowntoHTML.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { remark } from 'remark';
import html from 'remark-html';

export default async function markdownToHtml(markdown: string) {
const result = await remark()
.use(html, {
sanitize: false,
})

.process(markdown);

return result.toString();
}
13 changes: 13 additions & 0 deletions lib/replaceStr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default function replaceStrWithBlank([input, target]: [
string,
string | string[]
]) {
if (target instanceof Array) {
const result = target.map((eachTarget) => {
return input.replaceAll(eachTarget, '');
});
return result[0].trim();
}

return target.replaceAll(input, '');
}
Comment on lines +1 to +13
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아마 주어진 input 문자열에서 target 문자열 또는 target 배열안에 있는 문자열을 input 문자열에서 지우는 함수인 것 같은데, 구현에 오류가 있지 않을까 싶습니다.

우선 target이 array인 경우, 각 target에 대해서 map을 하고, input.replaceAll(eachTarget, '')를 합니다. 그리고 최종적으로 result[0].trim()을 반환하는데, 0번째 인덱스에 있는 문자열은 모든 target을 지운 문자열이 아닌, 첫번째 target만 지운 문자열입니다.

그리고 두번째, target이 string인 경우 target.replaceAll(input, '')를 하는데, 이 경우 target 문자열에서 input을 찾아서 바꾸는 것이기에 역할이 뒤바뀐 상태입니다.

따라서 만약 제가 이 함수를 구현하려 했다면,

export default function removeTargetFromInput(input: string, target: string | string[]) {
  if (target instanceof Array) {
    return target.reduce((currentInput, eachTarget) => {
      return currentInput.replaceAll(eachTarget, '');
    }, input);
  }

  return input.replaceAll(target, '');
}

이런식으로 구현하지 않았을까 싶네요!

함수명 역시 조금 더 직관적으로 target을 input에서 없애는걸 보여주려고 할 것 같고, 값들을 굳이 배열로 받지 않을 것 같습니다!

29 changes: 29 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});

const nextConfig = {
experimental: {
optimizePackageImports: ['styled-components,sentry,lodash,react-markdown'],
},
reactStrictMode: true,
compiler: {
styledComponents: true,
},
images: {
remotePatterns: [
{
protocol: 'https',
hostname: '**',
},
],
formats: ['image/avif', 'image/webp'],
},
};

const bundleAnalyzerConfig = withBundleAnalyzer({
...nextConfig,
compress: true,
});

module.exports = bundleAnalyzerConfig;
73 changes: 73 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"name": "hj-devlog",
"version": "0.1.0",
"private": true,
"homepage": "https://github.com/khj0426/HJ_Devlog",
"scripts": {
"lhci": "next build && lhci autorun",
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"lint:fix": "next lint --fix",
"deploy": "next build && npx gh-pages -d out",
"analyze": "cross-env ANALYZE=true next build",
"analyze:server": "cross-env BUNDLE_ANALYZE=server next build",
"analyze:browser": "cross-env BUNDLE_ANALYZE=browser next build"
},
"dependencies": {
"@giscus/react": "^2.2.8",
"@next/bundle-analyzer": "^13.4.7",
"@sentry/nextjs": "^7.64.0",
"@tanstack/react-query": "^4.33.0",
"@types/node": "20.2.5",
"@types/react": "18.2.8",
"@types/react-dom": "18.2.4",
"@types/react-syntax-highlighter": "^15.5.7",
"@types/recoil": "^0.0.9",
"@types/styled-components": "^5.1.26",
"@types/uuid": "^9.0.1",
Comment on lines +23 to +29
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

패키지들의 Type들은 devDependency에 속해도 좋지 않을까요?
프로덕션 환경에서는 타입이 필요하지 않으니까요!

"autoprefixer": "10.4.14",
"axios": "^1.6.2",
"cross-env": "^7.0.3",
"date-fns": "^2.30.0",
"eslint": "8.42.0",
"eslint-config-next": "13.4.4",
"firebase": "^10.7.1",
"github-label-sync": "^2.3.1",
"gray-matter": "^4.0.3",
"js-cookie": "^3.0.5",
"next": "^13.5.0",
"notion-client": "^6.16.0",
"postcss": "8.4.24",
"prism-react-renderer": "^2.0.5",
"react": "18.2.0",
"react-cookie": "^6.1.1",
"react-dom": "18.2.0",
"react-markdown": "^8.0.7",
"react-notion-x": "^6.16.0",
"react-secure-storage": "^1.3.0",
"react-syntax-highlighter": "^15.5.0",
"recoil": "^0.7.7",
"rehype-raw": "^6.1.1",
"remark": "^14.0.3",
"remark-html": "^15.0.2",
"styled-components": "^6.0.0-rc.3",
"tailwindcss": "3.3.2",
"typescript": "5.1.3",
"uuid": "^9.0.0"
},
"devDependencies": {
"@commitlint/cli": "^17.7.2",
"@commitlint/config-conventional": "^17.7.0",
"@lhci/cli": "^0.12.0",
"@sentry/utils": "^7.64.0",
"@types/glob": "^8.1.0",
"@typescript-eslint/parser": "^6.7.5",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"gh-pages": "^5.0.0",
"glob": "^10.2.7",
"husky": "^8.0.3"
}
}
6 changes: 6 additions & 0 deletions src/@types/AboutProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type AboutProps = {
title: string;
imgurl: string;
content: string | string[];
};
export default AboutProps;
Comment on lines +1 to +6
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 type들은 바로 export를 하신 것 같은데, AboutProps만 export default로 하신 이유가 있으실까요??

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

따로 이유는 없습니다.!! 다른 type 들과의 통일성을 위해 바로 export하도록 수정했어요!!!

10 changes: 10 additions & 0 deletions src/@types/ButtonType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { CSSProperties } from 'react';

export type ButtonProps = {
style?: CSSProperties;
disabled?: boolean;
variant?: 'default' | 'outlined';
label?: string;
icon?: React.ReactNode;
onClick?: () => void;
};
Loading