새로운 도구를 배울 때마다 먼저 두 가지 질문을 해야 합니다.
이 두 가지 질문에 모두 답할 수 없는 경우 먼저 도구가 필요하지 않을 수 있습니다. 그 질문들을 웹팩에 적용 해 봅시다.
Webpack이 존재하는 이유는 무엇입니까?
핵심적으로 webpack은 모듈 번들러입니다. 응용 프로그램의 모든 모듈을 검사하고 종속성 그래프를 만든 다음 index.html 파일이 참조 할 수 있는 하나 이상의 번들에 지능적으로 모든 모듈을 통합합니다.
App.js ---> | |
Dashboard.js -> | Bundler | -> bundle.js
About.js ---> | |
웹팩은 어떤 문제를 해결합니까?
역사적으로 JavaScript 응용 프로그램을 작성할 때 JavaScript 코드는 파일로 구분됩니다 (이러한 파일은 실제 모듈 일 수도 있고 아닐 수도 있습니다). 그런 다음 index.html 파일에서 모든 JavaScript 파일에 <script> 태그를 포함시켜야 합니다.
<body>
...
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="libs/react.min.js"></script>
<script src='src/admin.js'></script>
<script src='src/dashboard.js'></script>
<script src='src/api.js'></script>
<script src='src/auth.js'></script>
<script src='src/rickastley.js'></script>
</body>
이것은 지루할 뿐만 아니라 오류가 발생하기 쉽습니다. 오타 나 파일 포함을 잊는 것과 같은 명백한 문제가 있었지만 그보다 <script> 태그의 순서가 중요했습니다. React 스크립트를 로드 하기 전에 React에 의존하는 스크립트를 로드하면 문제가 발생합니다.
webpack은 (지능적으로) 당신을 위해 번들을 생성하기 때문에,이 두 가지 문제는 사라집니다.
<script>를 잊어 버릴 염려가 없으며 주문에 대해 걱정할 필요가 없습니다.
<body>
...
<script src='dist/bundle.js'></script>
</body>
곧 알 수 있듯이 "모듈 번들링"측면은 웹팩의 일부일 뿐입니다. 필요한 경우, 모듈을 번들에 추가하기 전에 모듈에서 특정 변환을 수행하도록 웹팩에 지시 할 수도 있습니다. 예를 들어 브라우저에서 이해할 수 있는 SASS / LESS를 일반 CSS로 변환하거나 "현대 JavaScript"를 ES5로 변환 할 수 있습니다.
웹팩 설치
npm으로 새 프로젝트를 초기화했다고 가정하면 webpack, webpack 및 webpack-cli를 사용하려면 두 가지 패키지를 설치해야 합니다.
npm install webpack webpack-cli --save-dev
webpack.config.js
webpack 및 webpack-cli를 설치했으면 이제 webpack 구성을 시작해야 합니다. 이를 위해 객체를 내보내는 webpack.config.js 파일을 만듭니다. 당연히 이 객체는 웹팩에 대한 모든 구성 설정으로 이동합니다.
// webpack.config.js
module.exports = {}
웹팩의 핵심은 "모든 모듈을 검사하고, 선택적으로 변환 한 다음 지능적으로 하나 이상의 번들로 묶어 두는 것"입니다. 프로세스에 대해 생각한다면, 웹팩은 세 가지를 알아야 합니다.
The entry point
애플리케이션이 모듈로 구성 될 때마다 항상 애플리케이션의 진입 점 인 단일 모듈이 있습니다. 모든 것을 시작하는 모듈입니다. 일반적으로 index.js 파일입니다.
index.js
imports about.js
imports dashboard.js
imports graph.js
imports auth.js
imports api.js
우리가 webpack에 이 엔트리 파일의 경로를 주면,이를 사용하여 애플리케이션의 의존성 그래프를 생성 할 것입니다 (위에서 했던 것처럼 ... 더 나은 것을 제외하고). 그렇게 하려면 항목 파일을 가리키는 항목 속성을 webpack 구성에 추가합니다.
// webpack.config.js
module.exports = {
entry: './app/index.js'
}
로더를 사용한 변환
이제 웹팩은 엔트리 파일을 알고 있으므로 다음으로 코드에서 실행할 변환이 무엇인지 알려야 합니다. 이를 위해 우리는 "로더"를 사용합니다.
기본적으로 webpack은 모든 import / require () 문을 검사하여 종속성 그래프를 작성하면 JavaScript 및 JSON 파일 만 처리 할 수 있습니다.
import auth from './api/auth' // ?
import config from './utils/config.json' // ?
import './styles.css' // ⁉️
import logo from './assets/logo.svg' // ⁉️
종속성 트리가 JS 및 JSON 파일 이상으로 구성되기를 원할 가능성이 매우 높습니다. 즉, .css 파일, .svg 파일, 이미지를 가져올 수 있습니다. 우리가 위에서 하고 있는 것처럼. 여기에서 "로더"가 도움이 될 수 있습니다. 로더의 주요 목적은 이름에서 알 수 있듯이 웹팩에 JavaScript 및 JSON 파일 이상을 처리 할 수 있는 기능을 제공하는 것입니다.
로더를 추가하는 첫 단계는 다운로드하는 것입니다. 앱에서 .svg 파일을 가져 오는 기능을 추가하기 위해 npm에서 svg-inline-loader를 다운로드합니다.
npm install svg-inline-loader --save-dev
다음으로 웹팩 설정에 추가해야 합니다. 로더에 대한 모든 정보는 module.rules 아래의 객체 배열로 이동합니다.
// webpack.config.js
module.exports = {
entry: './app/index.js',
module: {
rules: []
}
}
이제 각 로더에 대해 웹팩에 제공해야 하는 두 가지 정보가 있습니다. 먼저 로더를 실행할 파일 유형 (이 경우 모든 .svg 파일) 둘째, 해당 파일 형식에 사용할 로더 (이 경우 svg-inline-loader)입니다.
이를 위해 테스트와 사용이라는 두 가지 속성이 있는 객체가 있습니다. test는 파일 경로와 일치하는 정규 표현식이며 use는 우리가 사용하려는 로더의 이름입니다.
// webpack.config.js
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' }
]
}
}
이제 앱 어디에서나 .svg 파일을 가져올 수 있습니다. .css 파일은 어떻습니까? 로더도 추가해 보겠습니다. css-loader를 사용하겠습니다.
npm install css-loader --save-dev
// webpack.config.js
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: 'css-loader' }
]
}
}
이제 앱 어디에서나 .svg 및 .css 파일을 가져올 수 있습니다. 그러나 스타일이 제대로 작동하려면 로더를 하나 더 추가해야 합니다. 현재 CSS 로더로 인해 .css 파일을 가져올 수 있습니다. 그러나 이것이 해당 스타일이 DOM에 주입되고 있다는 의미는 아닙니다.
우리가 정말로 원하는 것은 CSS 파일을 가져온 다음 웹팩이 모든 CSS를 DOM의 <style> 태그에 넣어 페이지에서 활성화 되도록 하는 것입니다. 이를 위해 스타일 로더를 사용합니다.
npm install style-loader --save-dev
// webpack.config.js
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] }
]
}
}
이제 .css 규칙에 대해 두 개의 로더가 있으므로 use를 배열로 변경합니다. 또한 css-loader 이전에 스타일 로더가 있습니다. 이건 중요하다. 웹팩은 그것들을 역순으로 처리합니다. 따라서 css-loader는 가져 오기 './styles.css'줄을 해석 한 다음 style-loader는 해당 CSS를 DOM에 삽입합니다.
방금 스타일 로더로 보았듯이 로더는 특정 파일 형식을 가져 오는 것 이상의 기능을 수행 할 수 있습니다. 최종 출력 번들에 추가되기 전에 파일에서 변환을 실행할 수도 있습니다. 가장 인기 있는 것은 "차세대 JavaScript"를 오늘날의 JavaScript로 변환하여 브라우저가 Babel을 사용하여 이해할 수 있도록 하는 것입니다. 이를 위해 모든 .js 파일에서 babel-loader를 사용할 수 있습니다.
npm install babel-loader --save-dev
// webpack.config.js
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
}
}
당신이 해야 할 일에 대한 로더가 있습니다. 여기에서 전체 목록을 확인할 수 있습니다.
출력
이제 웹팩은 엔트리 파일과 사용할 로더를 알고 있으므로 다음으로 생성해야 할 번들을 어디에 두어야 하는지 알아야 합니다. 이를 위해 webpack 설정에 출력 속성을 추가합니다.
// webpack.config.js
const path = require('path')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
}
}
전체 프로세스는 다음과 같습니다.
Plugins
번들을 생성하기 전이나 생성하는 동안 로더를 사용하여 개별 파일을 처리하는 방법을 살펴 보았습니다. 로더와 달리 플러그인을 사용하면 번들을 만든 후 특정 작업을 실행할 수 있습니다. 이 때문에 이러한 작업은 번들 자체 또는 코드베이스에 있을 수 있습니다. 플러그인은 더 강력하고 덜 제한적인 로더 버전으로 생각할 수 있습니다.
몇 가지 예를 살펴 보겠습니다.
HtmlWebpackPlugin
앞에서 우리는 webpack의 주요 이점은 우리가 하나의 번들을 생성하여 기본 index.html 페이지 내부를 참조하는 데 사용할 수 있다는 것입니다.
HtmlWebpackPlugin은 우리를 위해 이 index.html 페이지를 생성하고 번들을 넣은 디렉토리와 같은 디렉토리 안에 넣고 새로 생성 된 번들을 참조하는 <script> 태그를 자동으로 포함합니다.
이 예제에서 우리는 webpack에게 최종 번들의 이름을 index_bundle.js로 지정하고 dist라는 폴더에 넣도록 지시했습니다. HtmlWebpackPlugin이 실행될 때 새로운 index.html 파일을 생성하여 dist에 넣고 번들을 참조하는 스크립트 인 <script src = 'index_bundle.js'> </ script> 꽤 좋아요? 이 파일은 HtmlWebpackPlugin에 의해 생성되었으므로 번들의 출력 경로 또는 파일 이름을 변경하더라도 HtmlWebpackPlugin에 해당 정보가 있으며 그에 따라 조정됩니다.
이제 HtmlWebpackPlugin을 활용하기 위해 웹팩 구성을 어떻게 조정합니까? 항상 그렇듯이 먼저 다운로드 해야 합니다.
npm install html-webpack-plugin --save-dev
다음으로 webpack 설정에 배열 인 plugins 속성을 추가합니다.
// webpack.config.js
const path = require('path')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: []
}
그런 다음 HtmlWebpackPlugin을 사용하기 위해 plugins 배열 내에 새 인스턴스를 만듭니다.
// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin()
]
}
EnvironmentPlugin
React를 사용하는 경우 코드를 배포하기 전에 process.env.NODE_ENV를 프로덕션으로 설정해야 합니다. 이것은 React에게 경고와 같은 개발자 기능을 제거하는 프로덕션 모드로 빌드 하도록 지시합니다. Webpack은 EnvironmentPlugin이라는 플러그인을 제공하여 이를 간단하게 만듭니다. 웹팩 네임 스페이스의 일부로 제공되므로 다운로드 할 필요가 없습니다.
// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin(),
new webpack.EnvironmentPlugin({
'NODE_ENV': 'production'
})
]
}
이제 응용 프로그램의 어느 곳에서나 process.env.NODE_ENV를 사용하여 프로덕션 모드에서 실행 중인지 알 수 있습니다.
HtmlWebpackPlugin 및 EnvironmentPlugin은 웹팩의 플러그인 시스템으로 할 수 있는 작업 중 일부에 지나지 않습니다. 공식적으로 지원되는 플러그인의 전체 목록은 다음과 같습니다.
Mode
프로덕션 용 앱을 빌드 할 때마다 몇 가지 단계를 수행해야 합니다. 방금 process.env.NODE_ENV를 프로덕션으로 설정하는 것에 대해 배웠습니다. 다른 하나는 코드를 축소하고 주석을 제거하여 번들 크기를 줄이는 것입니다.
이러한 프로덕션 작업 각각에 플러그인을 사용하면 효과가 있지만 훨씬 쉬운 방법이 있습니다. 웹팩 구성에서 사용 중인 환경에 따라 mode 속성을 개발 또는 프로덕션으로 설정할 수 있습니다.
// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './app/index.js',
module: {
rules: [
{ test: /\.svg$/, use: 'svg-inline-loader' },
{ test: /\.css$/, use: [ 'style-loader', 'css-loader' ] },
{ test: /\.(js)$/, use: 'babel-loader' }
]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin()
],
mode: 'production'
}
EnvironmentPlugin을 제거 할 수 있었습니다. 그 이유는 mode를 production으로 설정하면 webpack은 process.env.NODE_ENV를 프로덕션으로 자동 설정합니다. 또한 코드를 축소하고 경고를 제거합니다.
웹팩 실행
이 시점에서, 우리는 웹팩의 작동 방식과 구성 방법에 대해 아주 잘 알고 있습니다. 이제 우리가 해야 할 유일한 것은 실제로 실행하는 것입니다.
npm을 사용하고 package.json 파일이 있다고 가정하면 webpack을 실행하는 스크립트를 작성할 수 있습니다.
// package.json
"scripts": {
"build": "webpack"
}
이제 명령 행에서 npm run build를 실행할 때마다 webpack은 index_bundle.js라는 최적화 된 번들을 실행하고 생성하여 dist 디렉토리 안에 넣습니다.
Production vs Development Modes
이 시점에서 우리가 다룰 웹팩 자체는 더 이상 없습니다. 그러나 개발 모드에서 실행과 프로덕션 모드에서 실행을 쉽게 전환하는 방법을 이해하는 것이 중요합니다.
우리가 이야기 한 것처럼 생산을 위해 구축 할 때는 모든 것이 최대한 최적화되기를 원합니다. 우리가 개발을 위해 구축 할 때 그 반대가 사실입니다.
프로덕션 빌드와 개발 빌드를 쉽게 전환 할 수 있도록 npm 스크립트를 통해 실행할 수 있는 두 가지 명령이 있습니다.
npm run build는 프로덕션 용 앱을 빌드합니다.
npm run start는 코드를 변경할 때마다 번들을 자동으로 재생성 하는 개발 서버를 시작합니다.
기억하신다면, 우리는 웹팩 설정 내부에서 모드를 하드 코딩했습니다. 그러나 npm run build를 실행할 때만 프로덕션 모드로 실행하려고 합니다. npm run start를 실행하면 모드를 개발로 설정하려고 합니다. 이 문제를 해결하기 위해 package.json 파일의 scripts.build 속성을 조정하여 환경 변수를 전달합니다.
"scripts": {
"build": "NODE_ENV='production' webpack",
}
Windows를 사용하는 경우 명령이 약간 다릅니다. "SET NODE_ENV = 'production'&& webpack"
이제 웹팩 설정에서 process.env.NODE_ENV를 기반으로 모드를 전환 할 수 있습니다.
// webpack.config.js
...
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development'
}
이제 프로덕션 용 앱을 빌드 할 때마다 명령 행에서 npm run build를 실행하면 됩니다. 그러면 index.html 파일과 index_bundle.js 파일이 생성되어 dist 디렉토리에 저장됩니다.
webpack DevServer
프로덕션을 위한 건물과 달리 개발할 때는 속도가 중요합니다. 코드를 변경할 때마다 웹팩을 다시 실행하고 dist 디렉토리를 다시 빌드 할 때까지 기다릴 필요가 없습니다. 여기서 webpack-dev-server 패키지가 도움이 될 수 있습니다.
이름에서 알 수 있듯이 webpack-dev-server는 webpack 용 개발 서버입니다. dist 디렉토리를 생성하는 대신 메모리에 있는 파일을 추적하고 로컬 서버를 통해 파일을 제공합니다. 또한 라이브 리로딩을 지원합니다. 즉, 코드를 변경할 때마다 webpack-dev-server는 코드를 빠르게 재 컴파일하고 해당 변경 사항으로 브라우저를 다시 로드 합니다.
항상 그렇듯이 사용하려면 먼저 설치해야 합니다.
npm install webpack-dev-server --save-dev
그런 다음 webpack-dev-server를 실행하기 위해 시작 스크립트를 업데이트하기 만하면 됩니다.
"scripts": {
"build": "NODE_ENV='production' webpack",
"start": "webpack-dev-server"
}
마찬가지로 개발 서버를 만들기 위한 명령과 프로덕션을 위한 앱을 빌드하기 위한 명령이 있습니다.
등록된 댓글이 없습니다.