https://www.inflearn.com/course/프런트엔드-웹팩
https://joshua1988.github.io/webpack-guide/
- 프런트엔드 빌드 시스템 - NPM, Webpack
- 자바스크립트 모듈화 (AMD, Common.js, ES6 Modules)
- 웹팩 개요 (등장 배경, 철학 등)
- 웹팩 주요 속성 4가지
- 배포 환경에서 알고 있어야 할 웹팩 특징과 설정 등
NPM이 해결해주는 문제
NPM이 라이브러리 의존성 관리 문제를 해결해준다.
라이브러리 버전을 업그레이드 하거나 할때 알아서 맞춰주는것이 참 좋다.
이 부분은 스프링 부트 스타터 패키지 쓰면서도 느끼는 부분이다.
NPM 지역 설치와 전역 설치의 차이
npm install 할 때 --global 옵션을 추가하면 전역 설치되게 된다.
전역 설치되면 node_modules에서는 안보이는데 사용이 가능하다.
전역 설치되면 어디에 위치하는지 확인을 해보자.
컴퓨터 어딘가에 node_modules 폴더가 또 존재하고 거기서 가져오게 된다.
시스템 레벨에 전역적으로 설치하는 방법이다.
--save-dev 옵션
이 옵션을 붙여서 npm install을 하면 devDependencies에 포함되게 된다.
dependencies에는 애플리케이션을 동작하는데 필요한 의존성
devDependeicies는 개발 단계에서 필요한 라이브러리(webpack, sass 등)
개발 단계에서만 참조가 유지되는 의존성
배포 단계에서는 관련 코드가 포함되지 않는다.
배포 단계에서 필요없는 라이브러리가 dependencies에 포함되면 배포가 느려질 수가 있다.
devDependencies인지 판단하는 기준은?
TODO 정리해보자.
웹팩이란?
쪼개져있는 파일들을 하나로 함쳐주는 것이 모델 번들링이고 웹팩은 모델 번들링 도구이다.
웹팩이 왜 필요한가?
--mode 속성
none, development, production 세가지 옵션이 있다.
웹팩 4버전에서 추가된 속성
TODO 각 속성 별 의미와 동작 방식
웹팩 설정 파일 적용
- webpack.config.js 파일 생성
- mode는 빌드 모드
- entry는 시작 지점
- output은 결과 파일의 생성위치와 이름
module.exports = {
mode: 'none',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
}
}
TODO lodash 라이브러리에 대해 학습 정리하자.
장단점과 사용해야할지 여부를 판단해보자.
웹팩 적용 전후 코드 차이 비교
적용 전 - 다 쪼개진 파일들이 사용된다. request가 여러개 발생한다.
적용 후 - 묶어서 만들어놨기 때문에 request 개수가 줄어든다.
웹팩 빌드 코드를 확인해보면 IIFE(Immediately Invoked Function Expression) 즉시 실행하는 함수 표현으로 감싸져 있다.
TODO 궁금한 점 1
파일 간에 로딩 순서가 어떤 순서로 결정되는지 궁금하다.
예전에 센차 빌드했을때 파일간 로딩 순서가 어긋나서 에러가 나는 경우가 발생한 적이 있음
F12의 No throttling 옵션
네트워크의 지연시간등 설정
네트워크의 가상환경을 설정하는 것.
로컬에서는 너무 빠르기 때문에 실제 환경과는 다르게 되는데 그런것들을 한번 속도가 느려지게 해서 테스트해볼 수 있게 하는 기능이다.
웹팩이란?
웹팩에서는 브라우저를 위한 사전 컴파일러
자바스크립트 뿐만 아니라 웹페이지를 구성하는 모든 리소스에 대해서 관리해주는 모듈러다.
이미지 css js html 등 모든 리소스파일을 대상으로 한다는 것
웹팩이 묶어주는 기능들
호환성 처리(Babel), 코드 압축(minifiers), 난독화(uglify)
Grunt와 Gulp와의 차이점은 하나의 js 진입점을 통해 모든 리소스들을 알아서 번들링 한다는 것
Grunt, Gulp는 파일 종류별로 묶어서 번들링을 진행하는 것으로 보임
자바스크립트의 문제는 변수 스코프가 전역적으로 선언된다는 것이다.
파일 명이 겹치면서 덮어씌워지는 문제
웹팩이 파일 별로 값들을 유니크하게 유지하도록 변수명을 바꿔주나??
ES Modules 개념이 들어오면서 해결됐다고 한다.
TODO 좀더 조사해보자. 웹팩이 해결해주는 것인지 언어 레벨에서 해결이 된건지
실습을 보니까 그렇게 해결되는건 아닌거 같고 import, export를 통해 해결하는 것 같다.
브라우저에서 한번에 요청할 수 있는 요청 개수가 제한돼있다고 한다.
크롬은 6개
웹팩 빌드 결과물 분석 source map?
production으로 빌드하면 난독화가 된다.
sourcemap은 난독화된 파일 말고 실제 파일을 연결해주는 기능이다.
devtool: 'source-map' 옵션을 webpack.config.js에 넣어주면 된다고 함.
웹팩 주요 속성
entry
빌드할 대상 파일 위치 지정. 최초 진입점이자 자바스크립트 파일 경로
output
빌드 후 결과물을 저장할 위치 지정
filename, path 지정
var path = require('path');
module.exports = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
}
}
설명중에 파일명에 [chunkhash]를 붙이는 예제가 있는데
이렇게 해시값을 파일명에 추가하면 웹브라우저가 파일 변경을 알아채지 못해서 캐시 초기화를 해야되는 상황을 회피할 수 있다고 한다. 파일명이 변경됐으니 항상 변경을 감지함.
filename: '[chunkhash].bundle.js'
loader
로더는 웹팩이 웹 애플리케이션을 해석할 때 자바스크립트 파일이 아닌 웹 지원(HTML, CSS, Images, 폰트 등)들을 변환할 수 있도록 도와주는 속성입니다.
엔트리나 아웃풋 속성과는 다르게 module 라는 이름을 사용합니다.
rules 배열에 규칙들을 지정하는것
test에는 파일 규칙, use에는 로더 배열을 등록한다.
아래는 css 확장자 파일에 로더를 적용하겠다 라는 의미
css-loader는 css를 웹팩안으로 들어갈 수 있게 하는 로더
style-loader는 웹팩안에 들어간 css를 head 안에 style 태그를 만들어서 박아주는 로더
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.js$/,
use: ['babel-loader']
}
}
}
웹팩 로더의 순서
와우ㅡㅡ 이 use 배열에 명시하는 순서가 영향을 끼친다고 한다.
밑에서 ['css-loader', 'style-loader'] 라고 하면 에러가 발생한다고 한다.
css를 불러오고 style로 등록해야되기 때문
로더는 오른쪽에서 왼쪽 순서로 적용된다고 한다.
예를 들어 sass 파일을 변환하고자 하는 경우
sass 처리를 먼저 해야되기 때문에 (sass를 컴파일해서 css로 바꿔야되기 때문)
sass-loader를 마지막에 추가해줘야 한다.
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
MiniCssExtractPlugin
css 파일을 style-loader의 인라인 스타일이 아니라 별도 파일로 웹팩 결과물에 포함되도록 하는 플러그인
아래 문장으로 플러그인을 불러오고 style-loader 대신에 추가해주면 된다.
MiniCssExtractPlugin = require("mini-css-extract-plugin")
var MiniCssExtractPlugin = require("mini-css-extract-plugin")
{
test: /\.css$/,
use: [
{ loader: MiniCssExtractPlugin.loader },
"css-loader"
]
}
플러그인
웹팩의 플러그인이라고 하는것은 웹팩 빌드 결과물을 바꿔준다.
로더랑 비교하면 로더는 파일을 해석하고 변환하는 과정에 관여하는 반면
플러그인은 웹팩의 빌드 결과물의 형태를 바꾸는 역할을 한다고 보면 됩니다.
플러그인의 배열에는 생성자 함수로 생성한 객체 인스턴스만 추가될 수 있습니다.
var webpack = require('webpack');
var HtmlWebpackPlugin = requre('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin(),
new webpack.ProgressPlugin()
]
}
HtmlWebpackPlugin: 웹팩으로 빌드한 결과물로 HTML 파일을 생성해주는 플러그인
ProgressPlugin: 웹팩의 빌드 진행율을 표시해주는 플러그인
자주 사용하는 플러그인
- split-chunks-plugin
- clean-webpack-plugin
- image-webpack-loader
- webpack-bundle-analyzer-plugin
자바스크립트를 번들링할떄는 로더가 필요없고 자바스크립트 외의 파일을 번들링 할때 필요한게 로더다.
강좌 이후에 웹팩 설정 파일 설정 및 변경할 떄 참고할 자료
https://webpack.js.org/loaders/
https://webpack.js.org/plugins/
웹팩 데브 서버가 필요한 이유
개발 단계에서 변경 사항을 바로바로 실행중에 반영되도록 하기 위해서. 핫 리로드 기능이다.
파일을 저장했을때 웹팩 빌드 후 브라우저를 새로고침 한다.
웹팩 데브 서버가 만드는 빌드 결과물은 디스크가 아니라 메모리에 생성되기 때문에(성능때문) 파일을 개발자가 직접 확인할 수는 없다. 빌드 결과물이 필요한 경우 직접 빌드 명령어를 실행해야 한다.
https://joshua1988.github.io/webpack-guide/devtools/webpack-dev-server.html
근데 웹팩 데브서버는 요즘 프론트 프레임워크들이 다 품고있기 때문에 직접 써주는건 아니라고 함
리액트도 CRA에 웹팩 데브서버가 포함돼있다.
TODO 나중에 webpack.config.js를 만들어주면 오버라이딩이 되는건지 아예 처음부터 다 지정해줘야하는지 알아보자. 스프링부트는 깁노 설정을 제공하고 오버라이딩 할 수 있도록 설정을 제공하는데 이것도 그렇지 않을까?
devserver를 설정할때는 아래처럼.
관련 속성은 필요할때 찾아서 쓰세요.
module.exports = {
devServer: {
port: 9000,
overlay: false,
}
}
HtmlWebpackPlugin
역할은 HTML 파일을 만들어주는 역할
번들링된 HTML 파일이나 CSS 파일등을 알아서 import, script 문장들을 추가해준다.
번들 결과물에 해시값이 들어가기도 하고 이 index.html 파일을 직접 생성할 수가 없기 때문
template을 지정해서 해당 파일을 기반으로 index.html 파일을 생성할 수 있다.
https://webpack.js.org/plugins/html-webpack-plugin/
퀴즈 파일
TODO 모르는 부분 정리하기
var path = require('path')
var webpack = require('webpack')
module.exports = {
mode: 'production',
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
module: {
rules: [
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
],
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']
},
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
// if (process.env.NODE_ENV === 'production') {
// module.exports.devtool = '#source-map'
// // http://vue-loader.vuejs.org/en/workflow/production.html
// module.exports.plugins = (module.exports.plugins || []).concat([
// new webpack.DefinePlugin({
// 'process.env': {
// NODE_ENV: '"production"'
// }
// }),
// new webpack.optimize.UglifyJsPlugin({
// sourceMap: true,
// compress: {
// warnings: false
// }
// }),
// new webpack.LoaderOptionsPlugin({
// minimize: true
// })
// ])
// }
웹팩 4에서 추가된 mode 속성
mode 속성이 추가되기 전에는 이렇게 구현했다.
빌드 환경이 production이면 Uglify나 압축 등 작업을 수행하도록 직접 적어줘야 했음
지금은 mode에 'production'이라고만 적어주면 된다.
parcel 등 경쟁자가 등장하면서 webpack 설정도 알아서 해주는 방향으로 변화하는 중
module.exports = {
mode: 'production',
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
'기록 및 문서화 > 강의' 카테고리의 다른 글
처음 만난 리액트 (0) | 2023.05.13 |
---|---|
스프링 핵심 원리 - 기본편 (0) | 2022.03.14 |
댓글