왜 웹팩인가?
본문
프론트 엔드 개발 분야는 오늘날 우리가 하는 일에 따라 급속히 변화하고 있습니다. 인생이 너무 단순 해졌고 프론트 엔드 라이브러리와 프레임 워크가 나타나기 전에 HTML 파일에 포함 시켜야 하는 간단한 자바 스크립트 파일이 있었습니다.
CSS에는 요즘 사용할 라이브러리와 프레임 워크가 몇 개 있습니다. 이것은 프론트 엔드 개발을 점점 더 어렵게 만듭니다. JavaScript 생태계에서도 마찬가지입니다. 사용할 라이브러리와 프레임 워크가 변경되었을 뿐만 아니라 오늘날 ES6와 같은 표준도 변경되었습니다. Angular, React, Vue와 같은 큰 세 가지 프레임 워크는 지난 몇 년 동안 작동했습니다.
그런 다음 소위 "모듈 번 들러"또는 빌드 도구 (웹팩, browserify 및 gulp)가 제공되었습니다.
웹팩과 같은 빌드 도구를 사용해야 하는 툴링이 점점 더 복잡해 졌다는 사실이 궁금하다면 웹 개발이 매우 간단했던 시대로 돌아가서 간단한 스크립트를 포함하는 것으로 충분합니다.
https://blog.bitsrc.io/why-learning-webpack-is-important-as-front-end-developer-247bc0ca40bd
팁
구성 요소를 모든 종속성 및 설정으로 캡슐화 하려면 비트를 사용하십시오. Bit의 클라우드에서 공유하고 팀과 협력하여 어디서나 사용할 수 있습니다.
비트가 있는 구성 요소 : 한 팀으로 프로젝트 전체에서 쉽게 공유
Webpack이란 무엇입니까?
먼저 Webpack이 무엇인지 정의 해 봅시다. 공식 사이트에 따르면 Webpack은 최신 JavaScript 응용 프로그램을 위한 정적 모듈 번들러입니다. 하나의 javascript 파일이 서로 의존 할 때 위치에 관계없이 모든 javascript 모듈을 하나로 묶는 종속성 그래프를 작성합니다.
간단히 말해서, Webpack은 모든 자바 스크립트 파일을 묶어서 작동 시키는 번들러입니다.
웹팩과 같은 라이브러리, 프레임 워크 및 빌드 도구 이전의 시간
그 당시의 삶은 훨씬 간단 해 졌기 때문에 HTML에 단일 스크립트를 포함 시키면 다음과 같은 문제를 즉시 해결할 수 있습니다.
<head>
<script src="main.js" type="text/javascript"></script>
</head>
그러나 라이브러리는 상호 의존적으로 작동하도록 라이브러리를 하나씩 포함하고 올바른 순서로 포함시켜야 합니다.
<head>
<script src="library1.js" type="text/javascript"></script>
<script src="library2.js" type="text/javascript"></script>
<script src="script.js" type="text/javascript"></script>
</head>
그런 다음 이 생태계는 Ember, Backbone, Meteor, React, Vue, Angular와 같은 프레임 워크를 추가했으며 거기에서 상황이 복잡해졌습니다. ES6, ES7 이상과 같이 변화하는 자바 스크립트 표준을 추가하십시오.
그런 다음 마지막으로 browserify, grunt, webpack과 같은 빌드 도구가 제공되었으며 프런트 엔드 생태계의 미지의 바다에서 완전히 길을 잃었습니다.
var webpack = require("webpack"); | |
var path = require("path"); | |
var HtmlWebpackPlugin = require("html-webpack-plugin"); | |
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; | |
module.exports = { | |
entry: { | |
bundle: './src/index.js' | |
}, | |
output: { | |
path: path.join(__dirname, "../dist"), | |
//note: we changed `bundle` name into a variable `[name]` to get the key values in `entry` property instead of declaring the name statically. | |
//[chunkhash] - this is a large string of characters that uses hash. If vendor or javascript files were updated, webpack will automatically bundle the contents of the file then generate a different hash. | |
filename: "[name].[chunkhash].js" | |
}, | |
mode: "development", | |
devtool: "inline-source-map", | |
devServer: { | |
proxy: { | |
'/api': { | |
target: "http://localhost:3000", | |
secure: false, | |
changeOrigin: true | |
} | |
} | |
}, | |
module: { | |
rules: [ | |
{ | |
use: { | |
loader: "babel-loader" | |
}, | |
test: /\.js$/, | |
exclude: /node_modules/ //excludes node_modules folder from being transpiled by babel. We do this because it's a waste of resources to do so. | |
}, | |
{ | |
use: ['style-loader', 'css-loader'], | |
test: /\.css$/ | |
} | |
] | |
}, | |
plugins: [ | |
//`manifest` - Gives the browser a better understanding that tells whether the vendor file has actually got changed. | |
// new webpack.optimize.CommonsChunkPlugin({ | |
// names: ['vendor', 'manifest'] | |
// }), //We need to include this plugin so that it never duplicates the libraries that were included in `vendor.js` within `bundle.js` as well | |
new HtmlWebpackPlugin({ | |
template: 'src/index.html' | |
}), //this plugin is responsible for injecting the entry scripts of webpack (such as `bundle.js` and `vendor.js`) inside the html file without specifying them manually. | |
new webpack.DefinePlugin({ | |
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) //we will set the correct variable for `process.env.NODE_ENV` variable inside the `scripts` property in `package.json` | |
}), //This adds windows-scoped variables that will be defined in bundle.js | |
// new BundleAnalyzerPlugin() | |
], | |
optimization: { | |
splitChunks: { | |
chunks: 'async', | |
minSize: 30000, | |
maxSize: 0, | |
minChunks: 1, | |
maxAsyncRequests: 5, | |
maxInitialRequests: 3, | |
automaticNameDelimiter: '~', | |
name: true, | |
cacheGroups: { | |
commons: { | |
test: /[\\/]node_modules[\\/]/, | |
name: 'vendors', | |
chunks: 'all' | |
}, | |
default: { | |
minChunks: 2, | |
priority: -20, | |
reuseExistingChunk: true | |
} | |
} | |
} | |
} | |
}; |
var webpack = require("webpack"); | |
var path = require("path"); | |
var HtmlWebpackPlugin = require("html-webpack-plugin"); | |
const CompressionPlugin = require("compression-webpack-plugin"); | |
module.exports = { | |
entry: { | |
bundle: './src/index.js' | |
}, | |
output: { | |
path: path.join(__dirname, "../dist"), | |
//note: we changed `bundle` name into a variable `[name]` to get the key values in `entry` property instead of declaring the name statically. | |
//[chunkhash] - this is a large string of characters that uses hash. If vendor or javascript files were updated, webpack will automatically bundle the contents of the file then generate a different hash. | |
filename: "[name].[chunkhash].js" | |
}, | |
mode: "development", | |
devServer: { | |
proxy: { | |
'/api': { | |
target: "http://localhost:3000", | |
secure: false, | |
changeOrigin: true | |
} | |
} | |
}, | |
module: { | |
rules: [ | |
{ | |
use: { | |
loader: "babel-loader" | |
}, | |
test: /\.js$/, | |
exclude: /node_modules/ //excludes node_modules folder from being transpiled by babel. We do this because it's a waste of resources to do so. | |
}, | |
{ | |
use: ['style-loader', 'css-loader'], | |
test: /\.css$/ | |
} | |
] | |
}, | |
plugins: [ | |
new HtmlWebpackPlugin({ | |
template: 'src/index.html' | |
}), //this plugin is responsible for injecting the entry scripts of webpack (such as `bundle.js` and `vendor.js`) inside the html file without specifying them manually. | |
new webpack.DefinePlugin({ | |
'process.env.NODE_ENV': JSON.stringify('production') //we will set the correct variable for `process.env.NODE_ENV` variable inside the `scripts` property in `package.json` | |
}) //This adds windows-scoped variables that will be defined in bundle.js | |
], | |
optimization: { | |
minimize: true, | |
splitChunks: { | |
chunks: 'async', | |
minSize: 30000, | |
maxSize: 0, | |
minChunks: 1, | |
maxAsyncRequests: 5, | |
maxInitialRequests: 3, | |
automaticNameDelimiter: '~', | |
name: true, | |
cacheGroups: { | |
commons: { | |
test: /[\\/]node_modules[\\/]/, | |
name: 'vendors', | |
chunks: 'all' | |
}, | |
default: { | |
minChunks: 2, | |
priority: -20, | |
reuseExistingChunk: true | |
} | |
} | |
} | |
} | |
}; |
개발자 커뮤니티에서 배우기 위해 이 스택을 듣고 읽었을 때 나는 프론트 엔드 생태계를 등반하고 휴식을 취한 다음 다시 촬영하기 시작할 때까지 협박 한 개발자 중 한 명이라는 것을 인정해야 합니다.
우리는 어떻게 이 혼란에 빠졌습니까?
먼저, 실제로 어떻게 이 혼란에 빠졌는지, 웹팩과 같은 도구를 빌드 할 때 어떤 문제가 해결되는지 물어 보자.
다음은 웹팩에서 해결하려는 문제입니다.
자동조작
HTML 헤더에 모든 자바 스크립트 라이브러리를 포함하는 데 열중하지는 않지만 기능에 사용하려는 라이브러리를 포함하기 위해 npm을 사용하는 것을 선호합니다.
Webpack은 당신을 위해 그것을 합니다. npm에서 원하는 라이브러리를 설치하기 만하면 모듈에서 해당 라이브러리를 사용하는 경우 webpack이 해당 라이브러리를 번들에 자동으로 포함 시킬 수 있습니다.
로드 속도
최신 웹 앱을 만들려면 웹 페이지 내에 개별 스크립트를 로드 하는 데 많은 비용이 듭니다.
Webpack은 웹 서버에서 스크립트를 가져올 때 한 번만 요청하므로 모든 Javascript 모듈을 하나로 묶어 로딩 속도를 향상 시킵니다. 자바 스크립트 파일을 하나씩 가져 오는 경우 웹 서버에서 요청하는 하나의 큰 파일과 대조적으로 해당 파일을 두 번 가져 와서 웹 서버에 스트레스를 가하는 것이 합리적입니다.
이것은 HTTP/2가 등장하기 전에는 사실 일 수 있지만 그 이후로 상황이 변경되었을 수 있습니다.
필요한 경우에만 필요한 스크립트를 로드 하십시오.
정상적인 상황에서 앱은 이러한 기능이 필요한지 여부에 관계없이 모든 자바 스크립트 모듈 및 라이브러리를로드합니다. 그러나 특정 시점에서 사용자가 현재 사용 중인 특정 기능이나 모듈에 라이브러리가 필요하지 않은 경우 어떻게 해야 합니까?
개발자 콘솔에서 이 그래프를 살펴보십시오.
그래프의 빨간색은 앱에서 사용되지 않은 스크립트의 백분율을 나타내고 녹색 스크립트는 스크립트가 사용되고 있음을 나타냅니다. 당신이 그것에 대해 생각할 때, 우리는 로딩 시간 동안 불필요하게 로드 되는 더 많은 사용되지 않는 스크립트를 가지고 있습니다.
이를 통해 웹팩은 이 문제를 해결하기 위해 "코드 분할"이라는 기능을 제공합니다. 이 기능은 앱에서 필요할 때만 개별 스크립트를 "주문형"또는 "비동기식"으로 로드 하도록 선택할 수 있습니다. 이를 통해 놀라운 속도로 앱을 로드 하는 데 필요한 성능을 향상 시킬 수 있습니다.
이 기능으로 인해 사용자가 특정 모듈이나 기능을 사용하지 않을 때 성능을 저해하는 불필요한 스크립트를 로드 할 필요가 없습니다.
코드 분할에 대한 자세한 내용은 다음 웹팩 공식 문서를 참조하십시오.
종속성 문제
웹팩 이 자바 스크립트 앱을 빌드 할 때 발생하는 일반적인 문제인 종속성 문제를 해결하기 때문에 웹팩이 인기를 얻는 또 다른 이유.
앞에서 언급했듯이 웹팩이 시작되기 전에 종속성을 올바르게 연결하기 위해 스크립트와 라이브러리를 적절한 순서로 배열했습니다.
<script src="moment.min.js"></script>
<script src="typeahead.min.js"></script>
<script src="jquery.min.js"></script>
<script src="otherplugins.min.js"></script>
<script src="main.js"></script>
이건 괜찮아요. 그러나 의존하는 라이브러리 목록이 넓어 질수록 스크립트를 올바른 순서로 가져 오지 않았기 때문에 일부 종속성 문제가 발생합니다. 내가 의존하는 라이브러리 목록이 점점 넓어지면 이 문제가 많이 발생합니다.
그러나 웹 팩을 사용하면 ECMAScript 모듈 (ESM)을 사용하여 빌드 시간 동안 누락 된 종속성을 미리 알 수 있기 때문에 이전의 모든 종속성 문제를 해결합니다.
//helper.js
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//main.js
import { square, diag } from 'helper';console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
이 import/export 모듈은 웹팩에서 자동으로 감지되며 번들 중에 포함 할 자바 스크립트 모듈의 표시기 역할을 합니다. 이것은 모든 것이 작동하도록 라이브러리를 적절한 순서로 배열하는 고통을 효과적으로 제거합니다.
얼마나 많은 문제가 해결 되더라도 여전히 웹팩 학습에 신경을 써야 합니까?
왜 웹팩을 배우나요?
이 도구에 대해 간략히 설명하기 위해 웹팩을 배우는 것이 프론트 엔드 개발자로서 큰 이점을 얻는 이유를 열거했습니다. 그 이유는 다음과 같습니다.
당신은 현대 프론트 엔드 생태계를 더 잘 이해할 것입니다
최근에 알 수 있듯이 Angular, React 및 Vue는 이미 웹 패키지를 사용하여 보일러 플레이트 또는 개발자가 이러한 주요 프레임 워크를 사용하여 프로토 타입 코딩을 시작할 수 있는 기성품 앱을 빌드 하는 데 이미 의존하고있었습니다.
상용구가 웹팩에 의존하는 이유는 Angular의 경우와 같이 많은 모듈 / 라이브러리가 관련되어 있기 때문입니다. Webpack은 위에서 언급 한대로 모듈 다운로드 / 포함 프로세스를 자동화하므로 프레임 워크 / 라이브러리에서 자주 사용됩니다.
웹팩을 배우면 앞서 언급 한 이점을 얻을 수 있을 뿐만 아니라 프론트 엔드 상용구가 어떻게 작동하는지 이해하여 현대 프론트 엔드 생태계를 이해하게 됩니다.
개발 속도를 높일 수 있습니다
"핫 모듈 교체"라는 웹팩 기능 덕분에 개발 시간도 단축되었습니다. 자바 스크립트 코드의 변경 사항을 반영하기 위해 페이지를 완전히 다시 로드 하지 않아도 되므로 생산성이 향상되는 것으로 입증되었습니다.
이것은 자바 스크립트에만 적용되는 것이 아니라 CSS 코드는 webpack 설정에 CSS 로더를 추가하여 이 기능을 활용할 수도 있습니다. 따라서 개발 시간이 엄청나게 빨라지고 디버깅 하는 동안 페이지가 완전히 로드 되는 데 걸리는 시간이 줄어 듭니다.
단일 페이지 응용 프로그램을 더 잘 설정할 수 있습니다
특히 단일 페이지 응용 프로그램을 개발하는 경우 웹팩 사용의 이점을 실제로 볼 수 있습니다.
웹팩을 배우면 단일 페이지 응용 프로그램을 쉽게 설정할 수 있습니다. 웹팩은 Babel과 같은 변환기를 사용하여 JSX 구문을 읽을 수 있는 자바 스크립트 코드로 변환 할 수 있기 때문에 React를 사용할 때 특히 그렇습니다.
빌드 시스템에 대한 완벽한 제어
자바 스크립트 코드를 이전 브라우저와 호환되도록 이전 버전에서 ES6 + 코드를 변환 해야 하는 경우 웹팩 로더를 통해 babel 또는 traceur를 사용하는 등 웹팩에 필요한 다양한 빌드 시스템을 선택할 수 있습니다.
어느 쪽이든 항상 제어 할 수 있습니다.
결론
웹팩이 일상적인 프론트 엔드 개발 작업에 추가 할 수 있는 훌륭한 도구 인 이유에 대해 간략히 설명하겠습니다. 모든 프론트 엔드 개발 프로젝트에서 이 도구가 항상 필요한 것은 아닙니다.
개인적인 경험으로 React를 사용한다면 웹팩에 의존 할 가능성이 더 높습니다. 그러나 웹팩에서 제공하는 솔루션이 귀하에게 도움이 되지 않거나 사용 사례에 맞지 않으면 괜찮습니다.
웹팩 학습에 어려움을 겪고 있다면 먼저 기존 상용구를 사용하여 웹 앱을 빠르게 설정 한 다음 천천히 웹팩을 배우는 것이 좋습니다.
- 이전글TensorFlow.js를 통한 클라이언트 측 NSFW 탐지 19.08.20
- 다음글JavaScript Sets 소개 19.08.20