webpack > vite 마이그레이션
Goal : webpack
이점
- 개발 환경 개선
- 빌드 속도 개선
- 서버 - client의 독립적인 분리
사전지식
Webpack 번들링 과정
Webpack의 번들링 과정은 크게 4단계로 나눌 수 있습니다: Entry, Output, Loaders, Plugins.
- Entry: Webpack은 번들링을 시작하는 지점인 'entry point'를 찾습니다. 이는 기본적으로
./src/index.js
입니다. 이 파일은 애플리케이션의 시작점이며, 여기서부터 모든 의존성을 추적하게 됩니다. - Output: 'output' 설정은 Webpack이 생성하는 번들 파일의 이름과 이 파일이 저장될 위치를 지정합니다. 기본적으로 이는
./dist/main.js
로 설정되어 있습니다. - Loaders: Webpack은 기본적으로 JavaScript와 JSON 파일만 이해할 수 있습니다. 그러나 'loaders'를 사용하면 Webpack이 다른 유형의 파일들 (예: CSS, 이미지, TypeScript 등)을 처리하고, 이를 적절한 형식의 모듈로 변환할 수 있게 해줍니다.
- Plugins: 'plugins'는 번들 최적화, 애셋 관리, 환경 변수 주입 등과 같은 광범위한 작업을 수행하는 데 사용됩니다. 예를 들어,
HtmlWebpackPlugin
은 HTML 파일을 생성하고,MiniCssExtractPlugin
은 CSS를 별도의 파일로 추출합니다.
Webpack의 번들링 과정은 다음과 같습니다:
- Webpack은 entry point에서 시작하여, import 문을 통해 연결된 모든 모듈을 찾습니다.
- 각 모듈에 대해 설정된 loader를 사용하여 해당 파일을 처리하고, 이를 JavaScript로 변환합니다.
- 이렇게 변환된 모든 모듈을 하나의 파일 (또는 여러 파일, 코드 분할이 설정된 경우)로 결합하여 번들을 생성합니다.
- 설정된 plugin들이 이 번들에 대해 추가적인 처리를 수행합니다.
- Output 설정에 따라 번들 파일을 디스크에 쓰고, 번들링 과정이 완료됩니다.
PostCSS
PostCSS는 CSS를 변환하는 도구로, JavaScript 플러그인을 사용하여 CSS를 분석하고 변환합니다.
- 이는 CSS 전처리기 (예: Sass, Less)와 비슷하지만, PostCSS는 플러그인 시스템을 통해 더욱 유연하고 확장 가능합니다.
PostCSS의 주요 기능은 다음과 같습니다:
- Autoprefixer: 브라우저 벤더 접두사를 자동으로 추가합니다. 이는 CSS를 작성할 때 크로스 브라우저 호환성을 유지하는 데 도움이 됩니다.
- CSSNext: CSS의 최신 기능을 사용할 수 있게 해주며, 이를 브라우저가 이해할 수 있는 CSS로 컴파일합니다.
- CSS Modules: CSS를 모듈로 사용할 수 있게 해주며, 이는 CSS의 범위를 제한하고 네임스페이스 충돌을 방지하는 데 도움이 됩니다.
- CSSnano: CSS를 최적화하고 축소화하여, 최종 번들의 크기를 줄입니다.
Vite에서는
- PostCSS 설정 파일이 있다면, 이를 사용하여 모든 CSS 파일에 해당 설정을 적용
- CSS의 축소화는 PostCSS 이후에 진행되며, build.cssTarget 옵션을 이용해 설정
설정 예시)
module.exports = {
parser: 'sugarss',
map: false,
plugins: {
'postcss-import': {},
'postcss-preset-env': {},
'postcss-flexbugs-fixes': {},
'cssnano': {}
}
};
1. **parser: 'sugarss'**: 이 설정은 PostCSS가 CSS를 파싱하는 방식을 정의합니다. 여기서는 'sugarss'라는 파서를 사용하도록 설정되어 있습니다. SugarSS는 CSS의 대안 문법으로, 중괄호와 세미콜론 없이 CSS를 작성할 수 있게 해줍니다.
2. **map: false**: 이 설정은 소스 맵을 생성할지 여부를 정의합니다. 소스 맵은 변환된 CSS 파일이 원본 CSS 파일의 어느 부분에 해당하는지를 매핑해주는 파일입니다. 여기서는 소스 맵을 생성하지 않도록 설정되어 있습니다.
3. **plugins**: 이 설정은 PostCSS가 CSS를 변환하는 데 사용할 플러그인들을 정의합니다. 각 플러그인은 다음과 같은 기능을 가지고 있습니다:
- **'postcss-import'**: 이 플러그인은 `@import` 규칙을 해석하여, CSS 파일을 다른 CSS 파일로 가져올 수 있게 해줍니다.
- **'postcss-preset-env'**: 이 플러그인은 최신 CSS 문법을 사용할 수 있게 해주며, 이를 브라우저가 이해할 수 있는 CSS로 컴파일합니다.
- **'postcss-flexbugs-fixes'**: 이 플러그인은 Flexbox 관련 버그를 해결하는 데 도움이 됩니다.
- **'cssnano'**: 이 플러그인은 CSS를 최적화하고 축소화하여, 최종 번들의 크기를 줄입니다.
이 설정 파일을 통해, PostCSS는 CSS를 파싱하고, 여러 플러그인을 통해 CSS를 변환하며, 최종적으로 최적화된 CSS를 생성합니다.
OAuth, OIDC
OAuth 2.0과 OpenID Connect (OIDC)는 모두 인증 및 권한 부여 프로토콜입니다.
- OAuth 2.0은 권한 부여 프로토콜로
- 사용자가 서비스 제공자에게 특정 리소스에 대한 접근 권한을 부여할 수 있게 해줍니다.
- 예를 들어, 사용자가 어떤 앱에게 자신의 Google 계정 내의 데이터에 접근할 권한을 부여할 수 있습니다.
- OAuth 2.0은 이러한 권한 부여를 안전하게 처리하며, 사용자의 비밀번호를 직접 공유하지 않아도 됩니다.
OpenID Connect (OIDC)는 OAuth 2.0 위에 구축된 인증 프로토콜입니다.
- OIDC는 사용자가 누구인지 확인하는 '인증'에 초점을 맞춥니다.
- OIDC는 'ID 토큰'이라는 것을 도입하며, 이 토큰은 사용자의 신원 정보를 포함합니다.
- 이를 통해 애플리케이션은 사용자가 누구인지 확인할 수 있습니다.
요약하면, OAuth 2.0은 '권한 부여'에 중점을 두고 있으며, OIDC는 '인증'에 중점을 두고 있습니다.
- OIDC는 OAuth 2.0 위에 추가적인 기능을 제공하여, 사용자 인증을 가능하게 합니다.
ReactDOM.render
와 ReactDOM.createRoot
(React16 vs React18)
ReactDOM.render
와 ReactDOM.createRoot
는 React 애플리케이션을 DOM에 렌더링하는 두 가지 방법입니다.
- 이 두 방법의 주요 차이점은 React의 버전과 사용하는 동시성 모드(Concurrent Mode)에 있다.
- 계속해서 DOM에 접근하는 방식에서, 그렇지 않은 방식으로 바뀌었다.
ReactDOM.render: 이 방법은 React 16 이하에서 사용되며, 애플리케이션의 루트 컴포넌트를 DOM에 렌더링합니다. 이 방법은 동기적으로 작동하며, 렌더링 프로세스는 중단할 수 없습니다.
ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.createRoot: 이 방법은 React 18 이상에서 사용되며, 애플리케이션의 루트 컴포넌트를 DOM에 렌더링합니다. 이 방법은 React의 새로운 동시성 모드를 활용하며, 렌더링 프로세스는 필요에 따라 중단하고 다시 시작할 수 있습니다. 이는 애플리케이션의 반응성을 향상시키는 데 도움이 됩니다.
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
요약하면, ReactDOM.render
는 React 16 이하의 동기적 렌더링을 위한 방법이며, ReactDOM.createRoot
는 React 18 이상의 동시성 모드를 활용한 비동기적 렌더링을 위한 방법입니다.
ASIS
node 14
webpack-devserver v2
wepback v3
- entry
- main, main-mobile
- loader
- ** 로더 적용 순서는 마지막 요소 부터
- url-loader : [/.bmp$/, /.gif$/, /.jpe?g$/, /.png$/]
- babel-loader : /.(js|jsx|ts|tsx|mjs)$/,
- sass-loader : /.scss$/
- fallback : style-loader
- text-loader : html
- ExtractTextPlugin.extract : css
- fallback : style-loader
- babel-loader : /.svg(\?v=\d+.\d+.\d+)?$/,
- @svgr/webpack : /.svg(\?v=\d+.\d+.\d+)?$/,
- file-loader
- plugin
- ** 플러그인 적용 순서는 0번 요소 부터
- InterpolateHtmlPlugin
- DefinePlugin
- ExtractTextPlugin
- ManifestPlugin
- IgnorePlugin
- output
- dist
note
- 기존의 client 라이브러리, 서버 라이브러리 분리
- 서버 개발 환경, 클라이언트 개발 환경 분리하기
- 개발 : dev server + express server
- 프로덕션 : dev static files + express server
마이그레이션 목표
- 환경변수
- 번들러 환경설정
- 개발서버와, BFF의 분리 및 통합
- 프로덕션 S3 업로드 과정 매칭
- 개발서버 프록시 설정
마이그레이션 프로세스
1.vite 프로젝트 셋업
- 원본 client, client-vite 두개의 소스가 운영
- ( PostCSS.config 설정이 글로벌리 적용되므로 이를 주석처리한다. )
2.패키지 옮기기
1.미사용 라이브러리 구분
//특정 폴더 내에서 사용 중인 npm 패키지를 찾으려면, `depcheck`라는 도구를
npm install -g depcheck
// 그런 다음, `depcheck`를 실행하고 검사하려는 디렉토리를 지정합니다:
depcheck /path/to/your/directory
>depcheck /path/to/your/directory --ignore-patterns=server
안쓰는 모듈 130개
- 보안 이슈 차단 > 라이브러리 버전 업
- 리액트 호환성 이슈 > 라이브러리 버전 업
- 최신버전 리액트 지원 종료된 라이브러리 > 직접 수작업 업데이트
2.의존성 트리 관리하기
- 패키지를 다운받으면 peerDependencies 필드가 있다.
- 이 항목에서 요구하는 라이브러리 버전
3.private npm repository issue
일부 패키지들에서 권한 오류가 나온다. 어떠한 이유에서 블락이 되었다. 원인이 무엇인가?
3.소스 코드 옮기기
- 2138개
4.vite 환경설정
- 설정 파일에서 ES 모듈 구문을 사용 가능 (예: package.json의 type: "module")
vite --config my-config.js
0.공통설정
- JS allow >tsconfig.json
1.절대경로설정
// vite.config.ts :
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
resolve: {
alias: [
{ find: "@components", replacement: "/src/components" },
{ find: "@", replacement: "/src" },
],
},
});
---
// tsconfig.json:
{
"compilerOptions": {
...{options},
"baseUrl": ".",
"paths": {
"@components/*": ["src/components/*"],
"@/*": ["src/*"]
}
},
"include": ["src", "**/*.ts", "**/*.tsx"],
"references": [{ "path": "./tsconfig.node.json" }]
}
Need to consider
- mobile?은 어떤 페이지 인가 ?
- S3 upload process
개발서버 프록시 설정
1.OAuth, OIDC 등 callback url
- appBaseUrl - 을 로컬환경에서는 개발서버로 redirect되도록 분기 설정
2.webpack dev server
- 개발서버의 proxy를 태우면 서버로의 요청 경로는 다른 포트로 우회 가능하다.
devServer: {
disableHostCheck: true,
port: 3030,
historyApiFallback: true,
proxy: {
'/api': 'http://127.0.0.1:10001'
}
},