From 118fefeb76fa242d85866a39f9234376b37dbc13 Mon Sep 17 00:00:00 2001 From: IMHOJEONG <39ghwjd@naver.com> Date: Thu, 28 Dec 2023 00:34:10 +0900 Subject: [PATCH] [revise]: revise link & hot-reload & content for search page --- apps/pwrcode-backend/package.json | 7 +- apps/pwrcode-backend/src/main.ts | 7 ++ .../controllers/documents/React/hooks.ts | 100 +++++++++++++++++- apps/pwrcode-backend/webpack-hmr.config.js | 22 ++++ .../app/design/atoms/Link/Link.tsx | 7 +- .../app/design/atoms/TextArea/TextArea.tsx | 1 + .../design/molecules/Card/Card.stories.tsx | 8 +- yarn.lock | 17 +++ 8 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 apps/pwrcode-backend/webpack-hmr.config.js diff --git a/apps/pwrcode-backend/package.json b/apps/pwrcode-backend/package.json index 739f8a6..a927898 100755 --- a/apps/pwrcode-backend/package.json +++ b/apps/pwrcode-backend/package.json @@ -9,7 +9,7 @@ "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", "start": "nest start", - "start:dev": "nest start --watch", + "start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/main", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", @@ -30,8 +30,11 @@ "meilisearch": "^0.36.0", "mysql2": "^3.6.3", "reflect-metadata": "^0.1.13", + "run-script-webpack-plugin": "^0.2.0", "rxjs": "^7.8.1", - "typeorm": "^0.3.17" + "typeorm": "^0.3.17", + "webpack": "^5.89.0", + "webpack-pnp-externals": "^1.1.0" }, "devDependencies": { "@nestjs/cli": "^10.0.0", diff --git a/apps/pwrcode-backend/src/main.ts b/apps/pwrcode-backend/src/main.ts index b55bd90..9e52ca5 100755 --- a/apps/pwrcode-backend/src/main.ts +++ b/apps/pwrcode-backend/src/main.ts @@ -2,6 +2,8 @@ import { NestFactory } from '@nestjs/core'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { AppModule } from './app.module'; +declare const module: any; + async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors(); @@ -16,5 +18,10 @@ async function bootstrap() { SwaggerModule.setup('api', app, document); await app.listen(4000); + + if (module.hot) { + module.hot.accept(); + module.hot.dispose(() => app.close()); + } } bootstrap(); diff --git a/apps/pwrcode-backend/src/modules/search/controllers/documents/React/hooks.ts b/apps/pwrcode-backend/src/modules/search/controllers/documents/React/hooks.ts index a04aa82..38a9371 100755 --- a/apps/pwrcode-backend/src/modules/search/controllers/documents/React/hooks.ts +++ b/apps/pwrcode-backend/src/modules/search/controllers/documents/React/hooks.ts @@ -12,14 +12,110 @@ export const hooks: DataProps = { \`\`\`javascript const div = 'test' +const div2 = 'test2' \`\`\` -1. State Hooks tt +1. State Hooks - 상태를 통해 컴포넌트는 사용자 입력과 같은 정보를 "기억"할 수 있습니다. - "useState" : 직접 업데이트할 수 있는 상태 변수를 선언 - "useReducer" : 리듀서 함수 내부의 업데이트 논리를 사용해 상태 변수를 선언 - `, + +2. 컨텍스트 훅 + +- 컨텍스트를 사용하면 컴포넌트가 정보를 props로 전달하지 않고, 멀리 있는 부모로부터 정보를 받을 수 있습니다. + +- "useContext" : 컨텍스트를 읽고 구독 + +3. Ref 훅 + +- Refs를 사용하면 컴포넌트가 DOM 노드나 시간 초과 ID와 같이 렌더링에 사용되지 않는 일부 정보를 보유할 수 있음 + +- 상태와 달리 참조를 업데이트해도 컴포넌트가 다시 렌더링되지 않음. Refs는 React 패러다임의 "탈출구"입니다. 내장된 브라우저 API와 같이 React가 아닌 시스템으로 작업해야 할 때 유용함 + +- useRef는 참조를 선언함, 여기에는 어떤 값이라도 담을 수 있지만, 대부분 DOM 노드를 담는 데 사용됨 + +- useImperativeHandle을 사용하면 컴포넌트에 의해 노출되는 참조를 사용자 정의할 수 있습니다. + + - 거의 사용되지 않습니다. + +4. Effect 훅 + +- 효과를 사용하면 컴포넌트를 외부 시스템에 연결하고 동기화할 수 있음 + +- 네트워크, 브라우저 DOM, 애니메이션, 다른 UI 라이브러리를 사용하여 작성된 위젯 및 기타 React가 아닌 코드 처리가 포함됨 + +- "useEffect" : 컴포넌트를 외부 시스템에 연결 + + +- Effect는 React 패러다임의 "탈출 해치"입니다. 애플리케이션의 데이터 흐름을 조정하기 위해 Effects를 사용하지 마세요. + +- 외부 시스템과 상호작용하지 않는다면 Effect가 필요하지 않을 수도 있음 + +- useEffect에는 타이밍 차이가 있지만, 거의 사용되지 않는 두 가지 변형이 존재 + +- "useLayoutEffect" : 브라우저가 화면을 다시 그리지 전에 실행됨 + + - 여기에서 레이아웃을 측정할 수 있음 + +- "useInsertionEffect" : React가 DOM을 변경하기 전에 실행됨 + + - 라이브러리는 여기에 동적 CSS를 삽입할 수 있음 + +5. Performance 훅 + +- 리렌더링 성능을 최적화하는 일반적인 방법은 불필요한 작업을 건너뛰는 것 + + - 예) 이전 렌더링 이후 데이터가 변경되지 않은 경우 + + - 캐시된 계산을 재사용하거나 재렌더링을 건너뛰도록 React에 지시할 수 있음 + +- 계산과 불필요한 재렌더링을 건너뛰려면.. + + 1. "useMemo" : 비용이 많이 드는 계산 결과를 캐시할 수 있음 + + 2. "useCallback" : 함수 정의를 최적화된 컴포넌트에 전달하기 전에 캐시 가능 + + +- 화면을 실제로 업데이트해야 하기 때문에, 다시 렌더링을 건너뛸 수 없는 경우도 있음 + + - 이 경우, 동기식이어야 하는 차단 업데이트와 사용자 인터페이스를 차단할 필요가 없는 비차단 업데이트를 분리하여 성능을 향상시킬 수 있음 + +- 렌더링 우선순위를 지정하려면 + + 1. "useTransition" : 상태 전환을 비차단으로 표시하고, 다른 업데이트가 이를 중단하도록 허용할 수 있음 + + 2. "useDeferredValue" : UI의 중요하지 않은 부분 업데이트를 연기하고 다른 부분이 먼저 업데이트되도록 할 수 있음 + +6. Resource 훅 + +- 리소스를 상태의 일부로 포함하지 않고도 컴포넌트에서 리소스에 접근할 수 있음 + +- 예) 컴포넌트는 Promise에서 메시지를 읽거나 컨텍스트에서 스타일 정보를 읽을 수 있음 + +- 리소스에서 값을 읽으려면 + + 1. "use" : Promise나 Context와 같은 리소스의 값을 읽을 수 있음 + +--- + +7. 기타 훅 + +- 대부분 라이브러리 작성자에게 유용하며, 애플리케이션 코드에서는 일반적으로 사용되지 않음 + +- "useDebugValue" : 사용자 정의 훅에 대해 React DevTools 표시 레이블을 사용자 정의할 수 있음 + +- "useId" : 컴포넌트가 고유 ID를 자신과 연결할 수 있음, 일반적으로 접근성 API와 함께 사용됨 + +- "useSyncExternalStore" : 컴포넌트가 외부 저장소를 구독할 수 있음 + +--- + +8. 나만의 훅 + +- 사용자 정의 훅을 자바스크립트 함수로 정의할 수도 있음 + +`, }; diff --git a/apps/pwrcode-backend/webpack-hmr.config.js b/apps/pwrcode-backend/webpack-hmr.config.js new file mode 100644 index 0000000..80c70eb --- /dev/null +++ b/apps/pwrcode-backend/webpack-hmr.config.js @@ -0,0 +1,22 @@ +/* eslint-disable @typescript-eslint/no-var-requires */ +const { WebpackPnpExternals } = require('webpack-pnp-externals'); +const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin'); + +module.exports = function (options, webpack) { + return { + ...options, + entry: ['webpack/hot/poll?100', options.entry], + externals: [WebpackPnpExternals({ exclude: ['webpack/hot/poll?100'] })], + plugins: [ + ...options.plugins, + new webpack.HotModuleReplacementPlugin(), + new webpack.WatchIgnorePlugin({ + paths: [/\.js$/, /\.d\.ts$/], + }), + new RunScriptWebpackPlugin({ + name: options.output.filename, + autoRestart: false, + }), + ], + }; +}; diff --git a/apps/pwrcode-frontend/app/design/atoms/Link/Link.tsx b/apps/pwrcode-frontend/app/design/atoms/Link/Link.tsx index 158f019..5e5a59f 100755 --- a/apps/pwrcode-frontend/app/design/atoms/Link/Link.tsx +++ b/apps/pwrcode-frontend/app/design/atoms/Link/Link.tsx @@ -3,8 +3,6 @@ import styled from '@emotion/styled'; import React from 'react'; import Link from 'next/link'; -import { Theme } from '@emotion/react'; -import { useRouter } from 'next/navigation'; export interface LinkProps { href?: string; @@ -39,7 +37,7 @@ export function CustomLink(props: LinkProps) { borderRadius={props.borderRadius} border={props.border} > - {props.text} + {props.text} ); } @@ -60,4 +58,7 @@ const Component = styled.div` content: ' ${(props) => props.afterIcon}'; color: black; } + &:hover { + background: #c2d1d9; + } `; diff --git a/apps/pwrcode-frontend/app/design/atoms/TextArea/TextArea.tsx b/apps/pwrcode-frontend/app/design/atoms/TextArea/TextArea.tsx index 55e83d9..b3d5eaa 100755 --- a/apps/pwrcode-frontend/app/design/atoms/TextArea/TextArea.tsx +++ b/apps/pwrcode-frontend/app/design/atoms/TextArea/TextArea.tsx @@ -63,6 +63,7 @@ export function TextArea(props: TextAreaProps) { const language = className?.match(/language-(\w+)/)?.at(1); return (