코드스쿼드 과정에서 분명 만들었었는데 난 이해를 못했어서 정리!
보일러플레이트 다시 만들어보며 메모
일반 (Normal : No webpack-dev-server)
폴더 생성 및 기본 설정
mkdir webpack-react-typescript-boilerplate
cd webpack-react-typescript-boilerplate
npm init -y
npm i react react-dom
<Typography variant="h3" backgroundColor="gray">
<span>설치목록: typescript, ts-loader, webpack, webpack-cli, @types/react, @types/react-dom, @types/webpack</span>
</Typography>
npm i --save-dev typescript ts-loader webpack webpack-cli @types/react @types/react-dom @types/webpack
1) 생성된 package.json
{
"name": "webpack-react-typescript-boilerplate",
"version": "0.1.0",
"scripts": {
"build": "webpack",
"production": "NODE_ENV=production webpack --progress"
},
"repository": {
"type": "git",
"url": "git+https://github.com/17-sss/webpack-react-typescript-boilerplate.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/17-sss/webpack-react-typescript-boilerplate/issues"
},
"homepage": "https://github.com/17-sss/webpack-react-typescript-boilerplate#readme",
"description": "",
"devDependencies": {
"@types/react": "^17.0.14",
"@types/react-dom": "^17.0.9",
"@types/webpack": "^5.28.0",
"ts-loader": "^9.2.3",
"typescript": "^4.3.5",
"webpack": "^5.44.0",
"webpack-cli": "^4.7.2"
},
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
}
tsconfig.json 파일 생성
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"jsx": "react",
"sourceMap": true,
"outDir": "./dist/",
"noImplicitAny": true,
"lib": ["dom", "DOM.Iterable", "ESNext"],
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"isolatedModules": true,
"resolveJsonModule": true,
"noEmit": true,
"allowJs": true
},
"include": ["src/**/*"],
"exclude": ["node_modules/"]
}
- 여기서
compilerOptions에 쓰인 옵션들 설명
target
CMA Script 버전을 'ES3'(기본값),
'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2019', 'ES2021' 또는 'ESNEXT'로 지정.
module
모듈을 위한 코드 생성 설정:
'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'.
jsx: JSX 코드 생성 설정: 'preserve', 'react-native', 혹은 'react'.
sourceMap: '.map' 파일 생성 여부.
outDir: 해당 디렉토리로 결과 구조를 보냅니다.
noImplicitAny: 'any' 타입으로 구현된 표현식 혹은 정의 에러처리 여부
lib: 컴파일에 포함될 라이브러리 파일 목록
skipLibCheck: 정의 파일의 타입 확인을 건너 뛸 지 여부
esModuleInterop
모든 imports에 대한 namespace 생성을 통해
CommonJS와 ES Modules 간의 상호 운용성이 생기게할 지 여부,
'allowSyntheticDefaultImports'를 암시적으로 승인.
allowSyntheticDefaultImports
default export이 아닌 모듈에서도 default import가 가능하게 할 지 여부,
해당 설정은 코드 추출에 영향은 주지 않고, 타입확인에만 영향을 줌.
strict: 모든 엄격한 타입-체킹 옵션 활성화 여부
forceConsistentCasingInFileNames: 같은 파일에 대한 일관되지 않은 참조를 허용하지 않을 지 여부
noFallthroughCasesInSwitch: switch문에서 fallthrough 케이스에 대한 에러보고 여부
moduleResolution: 모듈 해석 방법 설정: 'node' (Node.js) 혹은 'classic' (TypeScript pre-1.6).
isolatedModules: 각 파일을 분리된 모듈로 트랜스파일 ('ts.transpileModule'과 비슷합니다).
resolveJsonModule
node 프로젝트에서 일반적으로 사용되는 확장자가 '.json'인 모듈을 가져올 수 있음.
여기에는 import정적 JSON 모양을 기반으로 하는 유형 생성이 포함됨.
(TypeScript는 기본적으로 JSON 파일 확인을 지원하지 않음)
noEmit: 결과 파일 내보낼지 여부
allowJs: 자바스크립트 파일 컴파일 허용 여부
- 더 많은 옵션: tsconfig.json의 컴파일 옵션 정리
webpack.config.js 파일 생성
1) 초기
const path = require('path');
const mode = process.env.NODE_ENV || 'development';
module.exports = {
mode,
devtool: mode === 'development' ? 'source-map' : 'hidden-source-map',
entry: {
app: path.join(__dirname, 'src', 'index.tsx'),
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
};
-
여기서 쓰인 옵션들 일부 정리
mode
mode 속성을 development, production 또는 none으로 설정하면
webpack에 내장된 환경별 최적화를 활성화 할 수 있음
entry: 엔트리 포인트 설정
output
생성된 번들을 내보낼 위치와 이 파일의 이름을 지정하는 방법을 webpack에 알려주는 역할.
기본 출력 파일의 경우에는 ./dist/main.js로 생성된 기타 파일의 경우에는 ./dist 폴더로 설정
resolve
module이 resolve 되는 방식을 변경시킨다.
예) import 'lodash' 호출시, resolve 옵션은 웹팩이 lodash를 찾는 방법을 변경
module.rules: 모듈이 생성 될 때 요청과 일치하는 Rule의 배열
-
resolve..?
2) 테스트를 위해 미리 파일 생성
src/App.tsx
import React from 'react';
const App = () => <div>Test</div>;
export default App;
src/index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root'),
);
src/public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document <%= env %></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
3) webpack: html-webpack-plugin 설치
index.html을 처리하기 위해 html-webpack-plugin 설치
npm i --save-dev html-webpack-plugin
webpack.config.js 파일에 html-webpack-plugin을 추가
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = {
mode,
plugins: [
new HtmlWebpackPlugin({
template: './src/public/index.html',
templateParameters: {
env: process.env.NODE_ENV === 'production' ? '' : '[DEV]',
},
minify:
process.env.NODE_ENV === 'production'
? {
collapseWhitespace: true,
removeComments: true,
}
: false,
hash: true,
}),
],
};
3-1) webpack: clean-webpack-plugin 설치
webpack을 실행할 때 마다 dist 폴더의 모든 항목을 삭제하려면 설치
npm i --save-dev clean-webpack-plugin
webpack.config.js 파일에 clean-webpack-plugin을 추가
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = {
mode,
plugins: [
new HtmlWebpackPlugin({
}),
new CleanWebpackPlugin(),
],
};
webpack dev server
로컬에서 webpack 실행결과를 확인하기 위해 사용.
- 결과물이 실제 파일로 보이지 않음
webpack을 커맨드라인에 입력하여 수정할 때 마다 번들링한 파일을 생성해줄 필요가 없음
npm i --save-dev webpack-dev-server
package.json 수정 (scripts에 추가 및 수정)
"scripts": {
"start": "NODE_ENV=development webpack serve --progress",
"production": "NODE_ENV=production webpack --progress"
}
- weback dev server 실행 시,
webpack-dev-server가 아닌 webpack serve로!!
(예전에는 webpack-dev-server로 실행했었는데 webpack serve로 바뀜!)
1) webpack.config.js에 devServer 옵션 설정
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = {
mode,
plugins: [
],
devServer: {
contentBase: path.resolve('./public'),
hot: true,
host: 'localhost',
port: 3000,
historyApiFallback: true,
writeToDisk: true,
},
};
-
여기서 쓰인 옵션들 정리
contentBase
서버에 콘텐츠를 제공할 위치를 알려줌 (정적 파일들)
hot
hot reload 기능 활성
(전체 Reload 없이 애플리케이션 실행되는 동안 모듈을 교환, 추가 또는 제거)
host: 개발환경에서 도메인을 맞추어야 하는 상황에서 사용
port: 개발 서버 포트 번호 설정
historyApiFallback
히스토리 API를 사용하는 SPA 개발시 설정. 404가 발생하면 index.html로 리다이렉트
writeToDisk
true시 devServer로 생성되는 컴파일된 파일을 저장함.
저장은 설정한 output.path 디렉토리에 기록 (기본값 false)
전부는 아니지만 추가 옵션 끄적끄적 👀
-
추가 옵션 1
publicPath: 브라우저를 통해 접근하는 경로 (기본값 '/')
overlay: 빌드시 에러나 경고를 브라우져 화면에 표시
stats
메시지 수준을 정할수 있다.
'none', 'errors-only', 'minimal', 'normal', 'verbose'로 메세지 수준을 조절
-
추가 옵션 2 (lazy & filename)
lazy
lazy모드가 활성화가 되면 dev-server는 요청될 때만 번들을 컴파일.
이는 웹 팩이 파일 변경 사항을 감시하지 않음을 의미.
게으른 모드라고도 불러짐
filename
devServer 설정하는 부분에서의 filename 옵션은 lazy 모드에서 사용하면 컴파일을 줄일수 있음.
lazy 모드에서 없이 사용하면 효과 없음
devServer: {
lazy: true,
filename: '[name].js',
}
webpack에 loader 추가
1-1) css-loader
webpack에서 .css 파일을 읽어들이기위해 사용하는 로더
npm i --save-dev css-loader
1-2) style-loader
<style> 태그를 삽입하여 CSS에 DOM을 추가
npm i --save-dev style-loader
1-3) css-loader & style-loader를 webpack.config.js에 추가
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = {
mode,
devtool: mode === 'development' ? 'source-map' : 'hidden-source-map',
entry: {
},
resolve: {
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
],
},
output: {
},
plugins: [
],
devServer: {
},
};
1-4) css-loader & style-loader 추가 설명 및 동작 원리
2-1) file-loader
이름 그대로 파일을 로딩하는 loader
- 웹팩은 모든 것을 모듈로 처리하는데 CSS 파일도 모듈로 다룸.
CSS에서 url() 함수에 파일명을 지정할수 있는데
이를 모듈에서 발견하면 웹팩은 file-loader를 통해 파일을 복사함.
npm i --save-dev file-loader
2-2) file-loader를 webpack.config.js에 추가
module.exports = {
mode,
devtool: ,
entry: { },
resolve: { },
module: {
rules: [
{
test: /\.(webp|jpg|png|jpeg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]',
},
},
],
},
output: { },
plugins: [ ],
devServer: { },
};
- 여기서는 확장자
webp, jpg, png, jpeg를 가진 파일들을 file-loader로 처리해줌
options에서name의 placeholder들
[name]은 entry에 있는 app의 키 이름을 가져옴 ("app")
[ext]는 파일/리소스의 파일 확장자
[hash]는 특정 빌드에 해당하는 해쉬 값
- file-loader의 속성들
options: 옵션을 설정.
options.name: 조건에 해당하는 파일이 저장될 경로(이름 포함)를 설정.
output: 번들된 결과물이 저장되는 출력 디렉토리에 대한 정보를 담은 객체.
path: 파일이 저장될 경로를 의미.
3) loader 설정 할 때의 webpack.config.js의 module.rules의 아이템 (rule) 하나마다 속성들.
test: 정규식 또는 문자열을 통해 조건에 해당하는 파일을 찾음.
use: 조건에 해당하는 파일을 처리할 로더. 복수의 로더가 있는 경우 역순으로 실행.
include: 검사를 포함할 경로이며, test와 함께 사용시 대상인 파일은 두 조건을 모두 일치해야 함.
exclude: 검사를 제외할 경로이며, test 및 include 보다 우선시 함.
참고자료
[+] 공통
[1] 일반 (Normal : No webpack-dev-server)
[2] webpack dev server
[3] webpack에 loader 추가
코드스쿼드 과정에서 분명 만들었었는데 난 이해를 못했어서 정리!
보일러플레이트 다시 만들어보며 메모
일반 (Normal : No webpack-dev-server)
폴더 생성 및 기본 설정
1) 생성된
package.jsontsconfig.json파일 생성compilerOptions에 쓰인 옵션들 설명targetCMA Script 버전을 'ES3'(기본값),
'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2019', 'ES2021' 또는 'ESNEXT'로 지정.
module모듈을 위한 코드 생성 설정:
'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'.
jsx: JSX 코드 생성 설정: 'preserve', 'react-native', 혹은 'react'.sourceMap: '.map' 파일 생성 여부.outDir: 해당 디렉토리로 결과 구조를 보냅니다.noImplicitAny: 'any' 타입으로 구현된 표현식 혹은 정의 에러처리 여부lib: 컴파일에 포함될 라이브러리 파일 목록skipLibCheck: 정의 파일의 타입 확인을 건너 뛸 지 여부esModuleInterop모든 imports에 대한 namespace 생성을 통해
CommonJS와 ES Modules 간의 상호 운용성이 생기게할 지 여부,
'allowSyntheticDefaultImports'를 암시적으로 승인.
allowSyntheticDefaultImportsdefault export이 아닌 모듈에서도 default import가 가능하게 할 지 여부,
해당 설정은 코드 추출에 영향은 주지 않고, 타입확인에만 영향을 줌.
strict: 모든 엄격한 타입-체킹 옵션 활성화 여부forceConsistentCasingInFileNames: 같은 파일에 대한 일관되지 않은 참조를 허용하지 않을 지 여부noFallthroughCasesInSwitch: switch문에서 fallthrough 케이스에 대한 에러보고 여부moduleResolution: 모듈 해석 방법 설정: 'node' (Node.js) 혹은 'classic' (TypeScript pre-1.6).isolatedModules: 각 파일을 분리된 모듈로 트랜스파일 ('ts.transpileModule'과 비슷합니다).resolveJsonModulenode 프로젝트에서 일반적으로 사용되는 확장자가 '.json'인 모듈을 가져올 수 있음.
여기에는 import정적 JSON 모양을 기반으로 하는 유형 생성이 포함됨.
(TypeScript는 기본적으로 JSON 파일 확인을 지원하지 않음)
noEmit: 결과 파일 내보낼지 여부allowJs: 자바스크립트 파일 컴파일 허용 여부webpack.config.js파일 생성1) 초기
여기서 쓰인 옵션들 일부 정리
modemode 속성을 development, production 또는 none으로 설정하면
webpack에 내장된 환경별 최적화를 활성화 할 수 있음
entry: 엔트리 포인트 설정output생성된 번들을 내보낼 위치와 이 파일의 이름을 지정하는 방법을 webpack에 알려주는 역할.
기본 출력 파일의 경우에는 ./dist/main.js로 생성된 기타 파일의 경우에는 ./dist 폴더로 설정
resolvemodule이 resolve 되는 방식을 변경시킨다.
예) import 'lodash' 호출시, resolve 옵션은 웹팩이 lodash를 찾는 방법을 변경
module.rules: 모듈이 생성 될 때 요청과 일치하는 Rule의 배열resolve..?2) 테스트를 위해 미리 파일 생성
src/App.tsxsrc/index.tsxsrc/public/index.html3) webpack:
html-webpack-plugin설치index.html을 처리하기 위해html-webpack-plugin설치webpack.config.js 파일에 html-webpack-plugin을 추가
HTMLWebpackPlugin..?package.json수정 (scripts추가)--progress는 빌드 진척률을 보여줌npm run [이름]예)
npm run production3-1) webpack:
clean-webpack-plugin설치webpack을 실행할 때 마다 dist 폴더의 모든 항목을 삭제하려면 설치
webpack.config.js 파일에 clean-webpack-plugin을 추가
webpack dev server
로컬에서 webpack 실행결과를 확인하기 위해 사용.
webpack을 커맨드라인에 입력하여 수정할 때 마다 번들링한 파일을 생성해줄 필요가 없음package.json수정 (scripts에 추가 및 수정)webpack-dev-server가 아닌webpack serve로!!(예전에는
webpack-dev-server로 실행했었는데webpack serve로 바뀜!)1)
webpack.config.js에 devServer 옵션 설정여기서 쓰인 옵션들 정리
contentBase서버에 콘텐츠를 제공할 위치를 알려줌 (정적 파일들)
hothot reload 기능 활성
(전체 Reload 없이 애플리케이션 실행되는 동안 모듈을 교환, 추가 또는 제거)
host: 개발환경에서 도메인을 맞추어야 하는 상황에서 사용port: 개발 서버 포트 번호 설정historyApiFallback히스토리 API를 사용하는 SPA 개발시 설정. 404가 발생하면 index.html로 리다이렉트
writeToDisktrue시 devServer로 생성되는 컴파일된 파일을 저장함.
저장은 설정한 output.path 디렉토리에 기록 (기본값 false)
전부는 아니지만 추가 옵션 끄적끄적 👀
추가 옵션 1
publicPath: 브라우저를 통해 접근하는 경로 (기본값 '/')overlay: 빌드시 에러나 경고를 브라우져 화면에 표시stats메시지 수준을 정할수 있다.
'none', 'errors-only', 'minimal', 'normal', 'verbose'로 메세지 수준을 조절
추가 옵션 2 (lazy & filename)
lazylazy모드가 활성화가 되면 dev-server는 요청될 때만 번들을 컴파일.
이는 웹 팩이 파일 변경 사항을 감시하지 않음을 의미.
게으른 모드라고도 불러짐
filenamedevServer 설정하는 부분에서의 filename 옵션은 lazy 모드에서 사용하면 컴파일을 줄일수 있음.
lazy 모드에서 없이 사용하면 효과 없음
webpack에 loader 추가
1-1)
css-loaderwebpack에서 .css 파일을 읽어들이기위해 사용하는 로더
1-2)
style-loader<style>태그를 삽입하여 CSS에 DOM을 추가1-3)
css-loader&style-loader를webpack.config.js에 추가1-4)
css-loader&style-loader추가 설명 및 동작 원리use: ['style-loader', 'css-loader']처럼여러 loader 를 위와 같이 중복해서 쓰면 오른쪽의 loader 부터 읽게 됨.
이러한 것을 ChainingLoaders 라고 한다.
2-1)
file-loader이름 그대로 파일을 로딩하는 loader
CSS에서 url() 함수에 파일명을 지정할수 있는데
이를 모듈에서 발견하면 웹팩은 file-loader를 통해 파일을 복사함.
2-2)
file-loader를webpack.config.js에 추가webp,jpg,png,jpeg를 가진 파일들을file-loader로 처리해줌options에서name의 placeholder들[name]은 entry에 있는 app의 키 이름을 가져옴 ("app")[ext]는 파일/리소스의 파일 확장자[hash]는 특정 빌드에 해당하는 해쉬 값options: 옵션을 설정.options.name: 조건에 해당하는 파일이 저장될 경로(이름 포함)를 설정.output: 번들된 결과물이 저장되는 출력 디렉토리에 대한 정보를 담은 객체.path: 파일이 저장될 경로를 의미.3) loader 설정 할 때의
webpack.config.js의module.rules의 아이템 (rule) 하나마다 속성들.test: 정규식 또는 문자열을 통해 조건에 해당하는 파일을 찾음.use: 조건에 해당하는 파일을 처리할 로더. 복수의 로더가 있는 경우 역순으로 실행.include: 검사를 포함할 경로이며, test와 함께 사용시 대상인 파일은 두 조건을 모두 일치해야 함.exclude: 검사를 제외할 경로이며, test 및 include 보다 우선시 함.참고자료
[+] 공통
[1] 일반 (Normal : No webpack-dev-server)
[2] webpack dev server
[3] webpack에 loader 추가