Π’Π΅Π³ΠΈ
ΠΏΠΎΠ»Π½ΡΠΉΠΊΠΎΠ½ΡΠΈΠ³ - ΠΏΠΎΠ»Π½Π°Ρ Π²Π΅ΡΡΠΈΡ ΠΊΠΎΠ½ΡΠΈΠ³Π° webpack
ΠΠ°ΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
ΠΡΠΎΡ ΡΠΊΡΠΈΠΏΡ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π» ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ Π² JSON-ΡΠΎΡΠΌΠ°ΡΠ΅
Post.js
export default class Post {
constructor(title, img) {
this.title = title;
this.img = img;
this.date = new Date();
}
toString() {
return JSON.stringify({
title: this.title,
date: this.date.toJSON(),
img: this.img,
});
}
}
ΠΡΠΎΡ ΡΠΊΡΠΈΠΏΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅Ρ Π½ΠΎΠ²ΡΡ ΠΎΡΠΏΡΠ°Π²ΠΊΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ ΠΈ Π²ΡΠ²ΠΎΠ΄ Π² ΠΊΠΎΠ½ΡΠΎΠ»Ρ
index.js
const post = new Post("Webpack Post Title");
console.log("post to string", post.toString);
Π£ΠΆΠ΅ ΡΡΠΎΡ ΡΠΊΡΠΈΠΏΡ Π½Π΅ ΡΠ²ΡΠ·Π°Π½ Ρ ΡΠ°Π±ΠΎΡΠΎΠΉ ΡΠ°ΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΡΠ° - ΠΎΠ½ ΡΡΠΈΡΠ°Π΅Ρ ΠΊΠ»ΠΈΠΊΠΈ Π½Π° ΡΡΡΠ°Π½ΠΈΡΠ΅ ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΠΈΡ Π²ΡΠ²Π΅ΡΡΠΈ Π² Π½ΡΠΆΠ½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ
Analytics.js
function createAnalytics() {
let counter = 0;
let isDestroyed = false;
const listener = () => counter++;
document.addEventListener("click", listener);
return {
destroy() {
document.addEventListener("click", listener);
isDestroyed = true;
},
getClicks() {
if (isDestroyed) {
return "Analytics is destroyed";
}
return counter;
},
};
}
window.analytics = createAnalytics();
Π’ΡΡ ΡΠΆΠ΅ Π² ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠΌ ΠΏΠΎΡΡΠ΄ΠΊΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΡΠΊΡΠΈΠΏΡΡ ΠΈ ΡΠΎΠ·Π΄Π°ΡΠΌ ΠΎΡΠ½ΠΎΠ²Ρ ΡΠ°ΠΉΡΠ°
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
<script src="analytics.js"></script>
</head>
<body>
<div class="container">
<h1>WP Course</h1>
</div>
<script src="Post.js"></script>
<script src="index.js"></script>
</body>
</html>
Π ΡΠ΅ΠΏΠ΅ΡΡ ΠΏΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΠΏΠΎΠ½ΡΡΡ, ΡΡΠΎ Ρ ΡΡΠΈΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π½Π΅ ΡΠ°ΠΊ:
- ΠΠ°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡ ΠΎΡΠ΅Π½Ρ ΠΌΠ½ΠΎΠ³ΠΎ ΡΠΊΡΠΈΠΏΡΠΎΠ² Π² Π½Π°Ρ
index.html
- ΠΠ°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΡΡΠΈΡΡΠ²Π°ΡΡ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½Π½ΡΡ ΡΠΊΡΠΈΠΏΡΠΎΠ² ΠΊ ΡΡΡΠ°Π½ΠΈΡΠ΅ (ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π² Π½Π΅ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠΌ ΠΏΠΎΡΡΠ΄ΠΊΠ΅ Π²ΡΠ»Π΅Π·Π΅Ρ ΠΎΡΠΈΠ±ΠΊΠ°)
ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ node, ΡΠ΅ΡΠ΅Π· ΠΊΠΎΡΠΎΡΡΠΉ ΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΠΌ Π² Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΌ Webpack
npm init
Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Webpack
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ webpack Π΄Π»Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ (-D
)
npm install -D webpack webpack-cli
- webpack - ΡΡΠΎ ΡΠ°ΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π» webpack
- webpack-cli - ΡΡΠΎ Π΅Π³ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π² ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ
ΠΠ°Π·ΠΎΠ²Π°Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠ° Webpack
ΠΡΠΎ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° webpack
ΠΏΠΎΠ»Π½ΡΠΉΠΊΠΎΠ½ΡΠΈΠ³
webpack.config.js
// ΠΡΠΎ ΠΌΠΎΠ΄ΡΠ»Ρ, ΠΊΠΎΡΠΎΡΡΠΉ Ρ
ΡΠ°Π½ΠΈΡ Π² ΡΠ΅Π±Π΅ ΠΏΡΡΡ Π΄ΠΎ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ°
const path = require("path");
// WP ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π² ΡΠ΅Π±Ρ ΡΠ΅ ΠΎΠΏΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΡΡΠ΄Π° Π²ΡΡΠ°Π²ΠΈΠΌ ΠΈ ΠΏΠΎ Π½ΠΈΠΌ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ±ΠΈΡΠ°ΡΡ Π½Π°Ρ ΠΏΡΠΎΠ΅ΠΊΡ
module.exports = {
// Π£ΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ Π½Π°ΡΠ°Π»ΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ°, Π² ΠΊΠΎΡΠΎΡΡΠΉ ΠΈ Π±ΡΠ΄Π΅Ρ Π²ΡΡ ΠΈΠΌΠΏΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡΡΡ
entry: "./src/index.js",
// ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π²ΡΠ²ΠΎΠ΄Π° webpack
output: {
// ΠΠΌΡ Π²ΡΠ²ΠΎΠ΄ΠΈΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°
filename: "bundle.js",
// ΡΡΡ ΡΠΆΠ΅ ΡΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ: ΠΏΡΡΡ Π΄ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΈ ΠΈΠΌΡ ΠΏΠ°ΠΏΠΊΠΈ, Π² ΠΊΠΎΡΠΎΡΡΡ Π±ΡΠ΄ΡΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡΡΡ ΡΠ°ΠΉΠ»Ρ
path: path.resolve(__dirname, "dist"), //__dirname - ΡΠΈΡΡΠ΅ΠΌΠ½Π°Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π½Π° ΡΠ΅ΠΊΡΡΠ΅Π΅ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
},
};
ΠΠΎΠΌΠ°Π½Π΄Π° Π΄Π»Ρ Π΅Π΄ΠΈΠ½ΠΎΡΠ°Π·ΠΎΠ²ΠΎΠ³ΠΎ Π²ΡΠ·ΠΎΠ²Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ webpack
webpack
Π ΡΠ΅ΠΏΠ΅ΡΡ ΠΏΠΎΡΠ»Π΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΡ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΊ index.html
webpack ΡΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΠ΅Ρ ΡΠ°ΠΉΠ» ΡΠΎ Π²ΡΠ΅ΠΌΠΈ ΡΠΊΡΠΏΠΎΡΡΠ°ΠΌΠΈ ΠΈ ΠΈΠΌΠΏΠΎΡΡΠ°ΠΌΠΈ. ΠΠ΅ΡΠ²ΡΠΌΠΈ Π² Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ Π²ΡΠ΅Π³Π΄Π° ΠΈΠ΄ΡΡ ΠΈΠΌΠΌΠΈΡΠ°ΡΠΈΠΈ ΡΠΊΡΠΏΠΎΡΡΠΎΠ² ΠΈ ΠΈΠΌΠΏΠΎΡΡΠΎΠ² ΠΈ ΡΠ°ΠΌΠΈ exports/imports, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ Π΄Π΅Π»Π°Π»ΠΈ. Π£ΠΆΠ΅ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΡΠΎΠΌ ΠΈΠ΄ΡΡ ΡΠ°ΠΌ ΠΊΠΎΠ΄.
index.html
<script src="bundle.js"></script>
ΠΠ°ΡΡΠ΅ΡΠ½Ρ
ΠΠΎ Π² ΠΏΡΠΎΡΠ»ΠΎΠΌ Π²Π°ΡΠΈΠ°Π½ΡΠ΅ Ρ Π½Π°Ρ Π²ΡΠΏΠ°Π΄Π°Π» ΡΠ°ΠΉΠ» Analytics.js
, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ Π½Π΅ Π±ΡΠ» Π½ΠΈΠΊΠ°ΠΊ ΡΠ²ΡΠ·Π°Π½ ΡΠ΅ΡΠ΅Π· ΠΈΠΌΠΏΠΎΡΡΡ Ρ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠΎΡΠΊΠΎΠΉ Π²Ρ
ΠΎΠ΄Π°. Π§ΡΠΎΠ±Ρ ΠΈΡΠΏΡΠ°Π²ΠΈΡΡ ΡΠΈΡΡΠ°ΡΠΈΡ, ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π·Π½Π°ΡΠΈΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠΎΡΠ΅ΠΊ Π²Ρ
ΠΎΠ΄Π° (ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π½ΠΊΠΎΠ²) ΠΈ Π·Π°Π΄Π°ΡΡ ΠΏΠ°ΡΡΠ΅ΡΠ½ Π΄Π»Ρ ΠΈΠΌΠ΅Π½ΠΈ Π²ΡΠ²ΠΎΠ΄ΠΈΠΌΡΡ
ΡΠ°ΠΉΠ»ΠΎΠ²
webpack.config.js
module.exports = {
mode: "development",
entry: {
// ΡΠ°ΠΊ ΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠΎΡΠ΅ΠΊ Π²Ρ
ΠΎΠ΄Π° Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
main: "./src/index.js", // ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠ°Π½ΠΊ
analytics: "./src/analytics.js", // ΠΏΠΎΠ±ΠΎΡΠ½ΡΠΉ ΡΠ°Π½ΠΊ
},
output: {
// Π’ΡΡ ΡΠΆΠ΅ Π·Π°Π΄Π°ΡΡΡΡ ΠΏΠ°ΡΡΠ΅ΡΠ½ [name]
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
},
};
Π ΡΠ°ΠΊ ΠΆΠ΅ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΏΡΠ°Π²ΠΈΡΡ ΠΈΠΌΠΏΠΎΡΡΡ ΡΠΊΡΠΈΠΏΡΠΎΠ² Π² HTML-ΡΠ°ΠΉΠ»
ΠΠ΄Π½Π°ΠΊΠΎ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΠΎΠ»ΠΊΠ½ΡΡΡΡΡ Ρ ΡΠΎΠΉ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, ΡΡΠΎ ΠΌΡ ΠΎΠ±Π½ΠΎΠ²ΠΈΠ»ΠΈ ΡΠΊΡΠΈΠΏΡ, Π° ΠΎΠ½ ΡΠΎ ΡΠ²ΠΎΠΈΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΡΠΆΠ΅ Π·Π°Ρ ΡΡΠΈΡΠΎΠ²Π°Π»ΡΡ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅ ΠΈ ΡΠΆΠ΅ Π½Π΅ ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅ΡΡΡ - ΡΡΠΎ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ²Π΅ΡΡΠΈ ΠΊ Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½ΡΠΌ ΠΏΠΎΠ»ΠΎΠΌΠΊΠ°ΠΌ, ΠΏΠΎΡΡΠΎΠΌΡ ΡΡΠΎΠΈΡ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π΅ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΏΠ°ΡΡΠ΅ΡΠ½, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΠΎΡΠ½ΠΎΠ²ΡΠ²Π°ΡΡΡΡ Π½Π° Π²Π½ΡΡΡΠ΅Π½Π½Π΅ΠΌ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠΌ ΡΠ°ΠΉΠ»Π°
[contenthash]
- Π±ΡΠ΄Π΅Ρ Π΄Π°Π²Π°ΡΡ ΠΈΠΌΡ, ΠΎΡΠ½ΠΎΠ²ΡΠ²Π°ΡΡΡ Π½Π° Π΅Π³ΠΎ Ρ
ΡΡΠ΅
webpack.config.js
output: {
filename: "[name].[contenthash].js",
path: path.resolve(__dirname, "dist"),
},
Π ΡΠ΅ΠΏΠ΅ΡΡ ΠΏΡΠΈ ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΏΠΎΠ»ΡΡΠ°ΡΡ Π½ΠΎΠ²ΡΠΉ ΡΠ°ΠΉΠ»
ΠΠ»Π°Π³ΠΈΠ½Ρ
ΠΠ»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ° ΡΡΡΠ°Π½ΠΎΠ²ΠΈΠΌ ΠΏΠ»Π°Π³ΠΈΠ½, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π²Π΅Π±ΠΏΠ°ΠΊΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ JS-ΡΠ°ΠΉΠ»Ρ, Π½ΠΎ ΠΈ HTML ΡΠΎ Π²ΡΠ΅ΠΌΠΈ Π½ΡΠΆΠ½ΡΠΌΠΈ Π²Ρ ΠΎΠ΄Π½ΡΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ
Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΠΏΠ»Π°Π³ΠΈΠ½Π°:
npm install -D html-webpack-plugin
ΠΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΏΠ»Π°Π³ΠΈΠ½Π°:
webpack.config.js
const path = require("path");
// ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΠΏΠ»Π°Π³ΠΈΠ½Π° Π² Π²Π΅Π±ΠΏΠ°ΠΊ
const HTMLWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: {
// ΡΠ°ΠΊ ΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠΎΡΠ΅ΠΊ Π²Ρ
ΠΎΠ΄Π° Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
main: "./src/index.js", // ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠ°Π½ΠΊ
analytics: "./src/analytics.js", // ΠΏΠΎΠ±ΠΎΡΠ½ΡΠΉ ΡΠ°Π½ΠΊ
},
output: {
filename: "[name].[contenthash].js",
path: path.resolve(__dirname, "dist"),
},
// ΠΠ΄Π΅ΡΡ ΠΌΡ Π·Π°Π΄Π°ΡΠΌ ΡΠΏΠΈΡΠΎΠΊ ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ Π² Π²Π΅Π±ΠΏΠ°ΠΊ
plugins: [
new HTMLWebpackPlugin() // ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½ Π² Π²Π΅Π±ΠΏΠ°ΠΊΠ΅
]
};
ΠΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ²ΠΈΠ΄Π΅ΡΡ, ΡΠ°ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅Ρ Π½ΠΎΠ²ΡΠΉ index.html
ΠΈΠ· ΠΈΠΌΠ΅ΡΡΠ΅Π³ΠΎΡΡ Π² src
ΠΈ ΠΏΠΎΠ΄ΡΡΠ°Π²Π»ΡΠ΅Ρ Π²ΡΠ΅ Π½ΡΠΆΠ½ΡΠ΅ ΠΈΠΌΠΏΠΎΡΡΡ ΡΠΊΡΠΈΠΏΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ Π² ΡΠ²ΠΎΡ ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΡΡΡΡ ΡΠΎ ΡΠ²ΠΎΠΈΠΌ Ρ
Π΅ΡΠ΅ΠΌ
Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°ΡΡ Π²Π½ΡΡΡΠ΅Π½Π½ΠΎΡΡΠΈ ΡΠ΅Π³ΠΎΠ² Π² HTML
webpack.config.js
plugins: [
new HTMLWebpackPlugin({
title: 'webpack valery' // Π΄Π°Π»ΠΈ ΡΠ°ΠΉΡΠ»
})
]
Π Π°Π±ΠΎΡΠ° Ρ HTML
Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠ°Π·Π°ΡΡ ΠΏΠ»Π°Π³ΠΈΠ½Ρ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΡΠ΅Ρ HTML, ΠΊΠ°ΠΊΠΎΠΉ ΡΠ°ΠΉΠ» Π±ΡΠ΄Π΅Ρ ΡΠ²Π»ΡΡΡΡΡ Π΄Π»Ρ Π½Π΅Π³ΠΎ ΡΠ΅ΠΌΠΏΠ»Π΅ΠΉΡΠΎΠΌ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΡΠ²Π»ΡΡΡΡΡ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΡΠ°ΠΉΡΠ°.
Π‘Π²ΠΎΠΉΡΡΠ²ΠΎ template
ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ, Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΊΠ°ΠΊΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ HTML. Π’Π°ΠΊ ΠΆΠ΅ Π² ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ HTML Π±ΡΠ΄ΡΡ Π²Π»ΠΎΠΆΠ΅Π½Ρ Π²ΡΠ΅ Π½ΡΠΆΠ½ΡΠ΅ ΠΈΠΌΠΏΠΎΡΡΡ
webpack.config.js
const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: {
main: "./src/index.js",
analytics: "./src/analytics.js",
},
output: {
filename: "[name].[contenthash].js",
path: path.resolve(__dirname, "dist"),
},
plugins: [
new HTMLWebpackPlugin({
template: "./src/index.html", // ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠ°Π·Π°ΡΡ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ HTML
})
]
};
ΠΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΠΉ HTML Π² src
(Π±Π΅Π· ΠΊΠ°ΠΊΠΈΡ
-Π»ΠΈΠ±ΠΎ ΠΈΠΌΠΏΠΎΡΡΠΎΠ²)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
</head>
<body>
<div class="container">
<h1>WP Course</h1>
</div>
</body>
</html>
Π’ΠΎ , ΡΡΠΎ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π» webpack (Π²Π΅Π±ΠΏΠ°ΠΊ ΡΠ°ΠΌ Π΄ΠΎΠ±Π°Π²ΠΈΠ» ΠΈΠΌΠΏΠΎΡΡΡ Π½Π° Π°ΠΊΡΡΠ°Π»ΡΠ½ΡΠ΅ ΡΠΊΡΠΈΠΏΡΡ)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
<script defer src="main.a4fbcc6c859c6c9cd2a2.js"></script><script defer src="analytics.b0d68796ad2563de4d6c.js"></script></head>
<body>
<div class="container">
<h1>WP Course</h1>
</div>
</body>
</html>
ΠΡΠΈΡΡΠΊΠ° ΠΏΠ°ΠΏΠΊΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ°
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΈΡΡΠΈΡ ΠΏΡΠΎΠ΅ΠΊΡ ΠΎΡ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ ΡΠ°ΠΉΠ»ΠΎΠ²
npm i -D clean-webpack-plugin
ΠΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ Π΅Π³ΠΎ
webpack.config.js
const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
// ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½-ΠΎΡΠΈΡΡΠΈΡΠ΅Π»Ρ
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
module.exports = {
mode: "development",
entry: {
main: "./src/index.js",
analytics: "./src/analytics.js",
},
output: {
filename: "[name].[contenthash].js",
path: path.resolve(__dirname, "dist"),
},
plugins: [
new HTMLWebpackPlugin({
template: "./src/index.html",
}),
// ΠΠΎΠ²ΡΠΉ ΠΏΠ»Π°Π³ΠΈΠ½
new CleanWebpackPlugin(), // ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½
]
};
Π ΡΠ΅ΠΏΠ΅ΡΡ Π² ΠΏΠ°ΠΏΠΊΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠ° ΡΠΈΡΡΡΡΡΡ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ ΡΠ°ΠΉΠ»Ρ
Π‘Π±ΠΎΡΠΊΠ° ΠΏΡΠΎΠ΅ΠΊΡΠ°
Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Π΄Π°ΡΡ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΊΠΎΠ½ΡΠΎΠ»ΡΠ½ΡΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Π±ΠΈΠ½Π΄ΠΈΡΡ ΠΏΠΎΠ΄ ΠΊΠΎΡΠΎΡΠΊΠΈΠ΅ Π°Π»ΠΈΠ°ΡΡ. ΠΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ Π² ΡΠ°ΠΉΠ»Π΅ package.json
ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π² ΡΠ²ΠΎΠΉΡΡΠ²Π΅ "scripts"
Π·Π°Π΄Π°ΡΡ ΡΠ²ΠΎΠΈ Π°Π»ΠΈΡΠ°ΡΡ ΠΈ ΠΈΠΌ ΠΏΡΠΈΡΠ²ΠΎΠΈΡΡ ΠΊΠΎΠ½ΡΠΎΠ»ΡΠ½ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ
package.json
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
},
Π ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠΌΠ°Π½Π΄Ρ npm run
ΠΌΡ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌ Π·Π°ΠΏΡΡΠΊ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠ³ΠΎ ΡΠΊΡΠΈΠΏΡΠ° (ΡΡΡ - ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ Π² development
ΡΠ΅ΠΆΠΈΠΌΠ΅)
npm run dev
Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠ°ΡΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ Π·Π°Π΄Π°ΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΡΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² ΡΠ°ΠΉΠ»Π°Ρ
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production",
// ΡΠΎΠ·Π΄Π°ΡΠΌ ΠΊΠΎΠΌΠ°Π½Π΄Ρ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΡΡΠΎΡΠ½Π½ΠΎ ΡΠΌΠΎΡΡΠ΅ΡΡ ΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°ΠΉΠ»Ρ
"watch": "webpack --mode development --watch"
},
ΠΠΎΠ½ΡΠ΅ΠΊΡΡ
ΠΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ context
ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΡΠΊΠ°Π·Π°ΡΡ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ, ΠΎΡ ΠΊΠ°ΠΊΠΎΠΉ ΡΠΎΡΠΊΠΈ Π±ΡΠ΄Π΅Ρ ΠΈΠ΄ΡΠΈ ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ΅. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π²Π΅Π±ΠΏΠ°ΠΊ ΠΎΡΠΈΠ΅Π½ΡΠΈΡΡΠ΅ΡΡΡ ΠΎΡ Π½Π°ΡΠ°Π»ΡΠ½ΠΎΠΉ ΠΏΠ°ΠΏΠΊΠΈ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ°. ΠΡΠ»ΠΈ ΠΌΡ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ, ΡΠΎ Π²ΡΠ΅ ΠΏΡΡΠΈ, Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΡΠΎΠΏΠΈΡΡΠ²Π°ΡΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ°. ΠΡΠΎ ΡΠ΄ΠΎΠ±Π½ΠΎ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΏΠΎΡΡΠΈ Π²ΡΠ΅ ΠΏΡΡΠΈ Π΄ΠΎ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΌΡ ΠΏΡΠΎΠΏΠΈΡΡΠ²Π°Π΅ΠΌ Π²Π½ΡΡΡΠΈ ΡΠΎΠΉ ΠΆΠ΅ ΠΏΠ°ΠΏΠΊΠΈ src
webpack.config.js
const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
module.exports = {
// Π³ΠΎΠ²ΠΎΡΠΈΡ, Π³Π΄Π΅ Π½Π°Ρ
ΠΎΠ΄ΡΡΡΡ ΠΈΡΡ
ΠΎΠ΄Π½ΠΈΠΊΠΈ
context: path.resolve(__dirname, "src"),
mode: "development",
entry: {
main: "./index.js",
analytics: "./analytics.js",
},
output: {
filename: "[name].[contenthash].js",
path: path.resolve(__dirname, "dist"),
},
plugins: [
new HTMLWebpackPlugin({
template: "./index.html",
}),
new CleanWebpackPlugin(),
]
};
CSS-Π»ΠΎΠ°Π΄Π΅ΡΡ
ΠΠΎΠ°Π΄Π΅ΡΡ - ΡΡΠΎ ΡΡΡΠ½ΠΎΡΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π» Π²Π΅Π±ΠΏΠ°ΠΊΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ Π΄ΡΡΠ³ΠΈΠΌΠΈ Π²ΠΈΠ΄Π°ΠΌΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΠΏΠ΅ΡΠ²ΡΠΌ Π΄Π΅Π»ΠΎΠΌ Π΄Π²Π° Π»ΠΎΠ°Π΄Π΅ΡΠ°
css-loader
ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΈΠΌΠΏΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠΈΠ»ΠΈ Π² JSstyle-loader
Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ ΡΡΠΈΠ»ΠΈ Π² ΡΠ΅ΠΊΡΠΈΡHEAD
Π² HTML
npm i -D style-loader css-loader
webpack.config.js
module.exports = {
context: path.resolve(__dirname, "src"),
mode: "development",
entry: {
main: "./index.js",
analytics: "./analytics.js",
},
output: {
filename: "[name].[contenthash].js",
path: path.resolve(__dirname, "dist"),
},
plugins: [
new HTMLWebpackPlugin({
template: "./index.html",
}),
new CleanWebpackPlugin(),
],
// ΠΠ°Π΄Π°ΡΠΌ Π»ΠΎΠ°Π΄Π΅ΡΡ
module: {
rules: [
{
// Π’ΡΡ Π·Π°Π΄Π°ΡΡΡΡ ΠΏΠ°ΡΡΠ΅ΡΠ½ ΠΏΠΎΠΈΡΠΊΠ° ΡΠ°ΠΉΠ»Π°
// Π΅ΡΠ»ΠΈ Π½Π°ΠΌ ΠΏΠΎΠΏΠ°Π΄Π°ΡΡΡΡ ΡΠ°ΠΉΠ»Ρ Ρ ΡΠ°ΠΊΠΈΠΌ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ΠΌ
test: /\.css$/,
// ΡΠΎ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°ΠΊΠΈΠ΅ Π»ΠΎΠ°Π΄Π΅ΡΡ
// Π»ΠΎΠ°Π΄Π΅ΡΡ ΡΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΡΠΏΡΠ°Π²Π°-Π½Π°Π»Π΅Π²ΠΎ
// ΠΏΠ΅ΡΠ²ΡΠΉ Π»ΠΎΠ°Π΄Π΅Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΈΠΌΠΏΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠΈΠ»ΠΈ, Π²ΡΠΎΡΠΎΠΉ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ ΡΡΠΈΠ»ΠΈ Π² ΡΠ΅ΠΊΡΠΈΡ HEAD Π² HTML
use: ['style-loader', 'css-loader'],
}
],
}
};
index.html
import Post from './Post';
import './styles/style.css'; // ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ ΡΡΠΈΠ»Π΅ΠΉ
const post = new Post("Webpack Post Title");
console.log("post to string", post.toString);
style.css
.container {
padding-top: 2rem;
max-width: 1000px;
margin: 0 auto;
}
h1 {
text-align: center;
color: red;
font-weight: 700;
font-size: 60px;
}
Π Π°Π±ΠΎΡΠ° Ρ JSON
WP ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡ json-ΡΠ°ΠΉΠ»Ρ Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² ΠΎΠ±ΡΡΠ½ΡΠΌ ΠΈΠΌΠΏΠΎΡΡΠΎΠΌ
// ΠΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ JSON-ΡΠ°ΠΉΠ»Π°
import json from './assets/json.json';
console.log('json: ', json);
Π Π°Π±ΠΎΡΠ° Ρ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ
ΠΠΎ-ΠΏΠ΅ΡΠ²ΡΡ , Π½ΡΠΆΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π½ΠΎΠ²ΡΠΉ Π»ΠΎΠ°Π΄Π΅Ρ, ΠΊΠΎΡΠΎΡΡΠΉ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΡΠ°ΠΉΠ»Ρ
npm install file-loader -g
ΠΠΎ-Π²ΡΠΎΡΡΡ , Π½ΡΠΆΠ½ΠΎ ΠΎΠΏΠΈΡΠ°ΡΡ Π΄Π»Ρ Π½Π΅Π³ΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π°. Π ΠΏΡΠ°Π²ΠΈΠ»Π°Ρ ΠΌΡ ΡΠΊΠ°ΠΆΠ΅ΠΌ Π²Π°ΡΠΈΠ°Π½ΡΡ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠΉ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠ³ΡΡ Π²ΡΡΡΠ΅ΡΠ°ΡΡΡΡ Π² Π½Π°ΡΠ΅ΠΌ ΠΏΡΠΎΠ΅ΠΊΡΠ΅
webpack.config.js
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
// ΠΠΏΠΈΡΡΠ²Π°Π΅ΠΌ Π½ΠΎΠ²ΡΠΉ Π»ΠΎΠ°Π΄Π΅Ρ Π΄Π»Ρ WP
{
// ΠΏΡΠΈ ΡΠ°Π±ΠΎΡΠ΅ Ρ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠΉ:
test: /\.(png|svg|jpg|gif)$/,
// ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ:
use: ['file-loader']
}
],
}
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π² JS
import WebpackLogo from './assets/webpack-logo.png';
const post = new Post("Webpack Post Title", WebpackLogo);
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Π² CSS (ΡΠΎΠ·Π΄Π°ΡΡ Π² dist
ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ)
.logo {
background-image: url("../assets/webpack-logo.png");
background-size: cover;
height: 200px;
width: 200px;
margin: 0 auto;
}
<div class="logo"></div>
Π Π°Π±ΠΎΡΠ° ΡΠΎ ΡΡΠΈΡΡΠ°ΠΌΠΈ
ΠΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³Π° Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ ΡΠΎ ΡΡΠΈΡΡΠ°ΠΌΠΈ:
webpack.config.js
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|jpe?g|gif)$/i,
use: ['file-loader'],
},
// Π’ΡΡ Π½ΡΠΆΠ½ΠΎ ΠΏΡΠΎΠΏΠΈΡΠ°ΡΡ ΠΏΡΠ°Π²ΠΈΠ»Π° ΡΠ°Π±ΠΎΡΡ file-loader ΡΠΎ ΡΡΠΈΡΡΠ°ΠΌΠΈ
{
// ΡΠΈΠΏΡ ΡΡΠΈΡΡΠΎΠ²
test: /\.(ttf|eot|woff|woff2)$/,
use: ['file-loader']
}
],
ΠΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΡΡΠΈΠ»ΠΈ Ρ Π½Π°ΡΠ΅Π³ΠΎ ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΠ°
font.css
@font-face {
font-family: 'Roboto';
src: url('../assets/fonts/Roboto-Regular.ttf') format('truetype');
}
ΠΠΌΠΏΠΎΡΡΠΈΠΌ ΡΠ°ΠΉΠ» Π² Π½Π°Ρ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ. ΠΠΌΠΏΠΎΡΡΡ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΏΠΎΡΡΠΈ ΡΠ°ΠΊ ΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ Π² WP
style.css
@import "font.css";
body {
font-family: 'Roboto', sans-serif;
}
ΠΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ CSS-Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ
ΠΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ Π΄Π»Ρ css. ΠΡΠΎ Π½ΠΎΡΠΌΠ°Π»ΠΈΠ·Π°ΡΠΎΡ ΡΡΠΈΠ»Π΅ΠΉ ΠΏΠΎΠ΄ ΡΠ°Π·Π½ΡΠ΅ Π±ΡΠ°ΡΠ·Π΅ΡΡ.
npm install normalize.css
ΠΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΠΌΠΎΠ΄ΡΠ»Ρ ΡΠ°ΠΊ ΠΆΠ΅ ΡΠ΅ΡΠ΅Π· ΠΈΠΌΠΏΠΎΡΡ.
~
Π² Π½Π°ΡΠ°Π»Π΅ ΠΈΠΌΠ΅Π½ΠΈ ΠΌΠΎΠ΄ΡΠ»Ρ Π³ΠΎΠ²ΠΎΡΠΈΡ Π½Π°ΠΌ ΠΎ ΡΠΎΠΌ, ΡΡΠΎ ΠΌΠΎΠ΄ΡΠ»Ρ Π½ΡΠΆΠ½ΠΎ ΠΈΡΠΊΠ°ΡΡ Π² ΠΏΠ°ΠΏΠΊΠ΅: node_modules
@import "~normalize.css";
ΠΠ°ΡΠΈΡΠ° ΠΎΡ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ ΠΏΠ°ΠΊΠ΅ΡΠ°
Π‘ΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎ Π½Π°Ρ ΠΏΠ°ΠΊΠ΅Ρ ΠΈΠΌΠ΅Π΅Ρ ΠΎΡΠ½ΠΎΠ²Π½ΡΡ Π²Ρ
ΠΎΠ΄Π½ΡΡ ΡΠΎΡΠΊΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° Π² package.json
, ΠΎΠ΄Π½Π°ΠΊΠΎ, ΡΡΠΎΠ±Ρ Π·Π°ΡΠΈΡΠΈΡΡΡΡ ΠΎΡ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ΠΎΠ΄Π½Ρ ΡΡΡΠΎΡΠΊΡ
package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "index.js", // ΠΡΠΎ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ Π½ΡΠΆΠ½ΠΎ Π΄Π»Ρ ΠΏΡΠ±Π»ΠΈΡΠ½ΡΡ
ΠΏΠ°ΠΊΠ΅ΡΠΎΠ²
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production",
"watch": "webpack --mode development --watch"
},
Π ΡΠ΅ΠΉΡΠ°Ρ Π½Π°Ρ ΠΏΠ°ΠΊΠ΅Ρ Π±ΡΠ΄Π΅Ρ Π·Π°ΡΠΈΡΡΠ½ ΠΎΡ ΠΏΡΠ±Π»ΠΈΠΊΠ°ΡΠΈΠΈ
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"private": true, // ΠΡΠΎ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ Π΄Π΅Π»Π°Π΅Ρ Π½Π°Ρ ΠΏΠ°ΠΊΠ΅Ρ ΠΏΡΠΈΠ²Π°ΡΠ½ΡΠΌ
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production",
"watch": "webpack --mode development --watch"
},
Π Π°Π±ΠΎΡΠ° Ρ XML-ΡΠ°ΠΉΠ»Π°ΠΌΠΈ
Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π»ΠΎΠ°Π΄Π΅ΡΠ° XML
npm install -D xml-loader
ΠΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΡΠ°Π²ΠΈΠ» Π½Π° XML
webpack.config.js
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|jpe?g|gif)$/i,
use: ['file-loader'],
},
{
test: /\.(ttf|eot|woff|woff2)$/,
use: ['file-loader']
},
// Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π΄Π»Ρ xml-loader
{
test: /\.xml$/,
use: ['xml-loader']
}
],
}
ΠΡΠ²ΠΎΠ΄ Π² ΠΊΠΎΠ½ΡΠΎΠ»Ρ ΠΈ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅
index.js
import json from './assets/json.json';
import xml from './assets/data.xml';
console.log('json: ', json);
console.log('XML: ', xml);
Π Π°Π±ΠΎΡΠ° Ρ CSV-ΡΠ°ΠΉΠ»Π°ΠΌΠΈ
papaparse
Π½ΡΠΆΠ΅Π½ Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΠΏΠ°ΡΡΠΈΠ½Π³ΠΎΠΌ ΡΠ°ΠΉΠ»ΠΎΠ²
csv-loader
Π»ΠΎΠ°Π΄Π΅Ρ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΌΠ΅Π΅Ρ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ csv ΡΠΎΡΠΌΠ°Ρ ΡΠ°ΠΉΠ»ΠΎΠ²
npm i -d papaparse
npm i -D csv-loader
webpack.config.js
{
test: /\.csv$/,
use: ['csv-loader'],
}
ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ
Π‘Π²ΠΎΠΉΡΡΠ²ΠΎ resolve
ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ Π΄Π»Ρ Webpack, ΡΡΠΎ Π΅ΠΌΡ Π½ΡΠΆΠ½ΠΎ ΠΈΡΠΊΠ°ΡΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
Π’ΠΎ Π΅ΡΡΡ, Π΅ΡΠ»ΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ extensions
Π±ΡΠ΄Π΅Ρ ΠΏΡΡΡΠΎΠ΅, ΡΠΎ ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΠ΄Π΅ΠΌ Π²ΡΠ΅Π³Π΄Π° ΠΏΡΠΎΠΏΠΈΡΡΠ²Π°ΡΡ Π² import
ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ². ΠΡΠ»ΠΈ ΠΌΡ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ Π² ΠΌΠ°ΡΡΠΈΠ², ΡΠΎ WP Π±ΡΠ΄Π΅Ρ ΠΈΡΠΊΠ°ΡΡ ΡΠ°ΠΉΠ» Ρ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡΠΈΠΌ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ΠΌ, Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ Π² ΠΈΠΌΠΏΠΎΡΡΠ΅ ΠΌΡ Π΅Π³ΠΎ Π½Π΅ ΡΠΊΠ°ΠΆΠ΅ΠΌ
module.exports = {
context: path.resolve(__dirname, "src"),
mode: "development",
entry: {
main: "./index.js",
analytics: "./analytics.js",
},
output: {
filename: "[name].[contenthash].js",
path: path.resolve(__dirname, "public"),
},
resolve: {
// Π’ΡΡ ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠΊΠ°Π·Π°ΡΡ WP, ΠΊΠ°ΠΊΠΈΠ΅ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°ΡΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ
extensions: ['.js', '.json', '.png'],
},
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 9000,
open: true
},
// ....
Π‘ Π½Π°ΡΡΡΠΎΠΉΠΊΠ°ΠΌΠΈ Π²ΡΡΠ΅ Π½Π°ΡΠΈ ΠΈΠΌΠΏΠΎΡΡΡ Π±ΡΠ΄ΡΡ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π±Π΅Π· ΡΠΊΠ°Π·Π°Π½ΠΈΡ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ
import Post from './Post'; // .js
import json from './assets/json'; // .json
import WebpackLogo from './assets/webpack-logo'; // .png
Π’Π°ΠΊ ΠΆΠ΅ ΠΏΡΠΈΡΡΡΡΡΠ²ΡΠ΅Ρ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ alias
, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π·Π°Π΄Π°ΡΡ ΠΏΡΠ΅Π²Π΄ΠΎΠ½ΠΈΠΌ Π΄Π»Ρ ΠΏΡΡΠ΅ΠΉ Π² Π½Π°ΡΠΈΡ
ΠΈΠΌΠΏΠΎΡΡΠ°Ρ
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, "src"),
'@components': path.resolve(__dirname, 'src/components'),
'@utilities': path.resolve(__dirname, 'src/utilities'),
'@modules': path.resolve(__dirname, 'src/modules')
}
},
// ΠΈ ΡΠ΅ΠΏΠ΅ΡΡ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π΄Π°ΡΡ ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΏΡΡΡ
import sayHi from './models/script';
// ΠΈΠ»ΠΈ ΡΠ΅ΡΠ΅Π· Π°Π»ΠΈΠ°ΡΡ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ Π°Π±ΡΠΎΠ»ΡΡΠ½ΡΠΉ ΠΏΡΡΡ
import sayHic from '@models/script';
// @ Π·Π°ΠΌΠ΅Π½ΠΈΡ src - ΡΠ°ΠΊ ΠΆΠ΅ ΡΠ΄Π΅Π»Π°Π΅Ρ Π°Π±ΡΠΎΠ»ΡΡΠ½ΡΠΉ ΠΏΡΡΡ
import sayHic from '@/models/script';
ΠΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ JS-Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ
npm i -S jquery
index.js
import * as $ from 'jquery';
$('pre').html(post.toString());
export default class Post {
constructor(title, img) {
this.title = title;
this.img = img;
this.date = new Date();
}
toString() {
return JSON.stringify({
title: this.title,
date: this.date.toJSON(),
img: this.img,
}, null, 2); // ΡΠ°ΠΊ ΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΡΡΠ΄Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΡΠΎΡΠΌΠ°ΡΠ°
}
}
ΠΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ
ΠΡΠ΅Π΄ΡΡΠ°Π²ΠΈΠΌ, ΡΡΠΎ Ρ Π½Π°Ρ Π΅ΡΡΡ Π΄Π²Π° ΡΠ°ΠΉΠ»Π°, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΈΠΌΠΏΠΎΡΡΠΈΡΡΡΡ Π² ΡΠ΅Π±Ρ jquery. ΠΡ ΡΡΠΎΠ»ΠΊΠ½ΡΠΌΡΡ Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, ΡΡΠΎ ΠΎΠ±Π° ΡΡΠΈΡ ΡΠ°ΠΉΠ»Π° Π±ΡΠ΄ΡΡ Π² ΡΠ΅Π±Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ ΠΈΠΌΠΏΠΎΡΡΠΈΡΠΎΠ²Π°ΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ. ΠΡΠΎ ΠΏΡΠΈΠ²Π΅Π΄ΡΡ ΠΊ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΌ ΠΏΡΠΈΠ±Π°Π²ΠΊΠ°ΠΌ ΠΊ Π²Π΅ΡΡ ΡΠ°ΠΉΠ»ΠΎΠ²
index.js
import * as $ from 'jquery';
$('pre').html(post.toString());
analytics.js
import * as $ from 'jquery';
function createAnalytics() {
let counter = 0;
let isDestroyed = false;
const listener = () => counter++;
$(document).on("click", listener);
return {
destroy() {
$(document).off("click", listener);
isDestroyed = true;
},
getClicks() {
if (isDestroyed) {
return "Analytics is destroyed";
}
return counter;
},
};
}
window.analytics = createAnalytics();
ΠΠΎΡΡΠΎΠΌΡ Π² WP Π΅ΡΡΡ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΡΡΡΠΎΠΈΡΡ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΎΠ΅ΠΊΡΠ°. Π Π½ΡΠΌ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΡΡΡ ΠΎΠ±ΡΠΈΠ΅ ΠΈΠΌΠΏΠΎΡΡΡ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΡΠ°Π½ΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ ΡΠ»ΡΠΆΠΈΡΡ ΡΠ²ΠΎΠ΅Π³ΠΎ ΠΎΠ±ΡΠ°Π·Π° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΠΌΠΈ (Ρ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ ΠΎΠ΄ΠΈΠ½ js, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Ρ ΡΠ°Π½ΠΈΡΡ jquery)
module.exports = {
context: path.resolve(__dirname, "src"),
mode: "development",
entry: {
main: "./index.js",
analytics: "./analytics.js",
},
// ΠΠ°ΡΠ°ΠΌΠ΅ΡΡ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ
optimization: {
splitChunks: {
chunks: 'all'
}
},
// ....
Webpack-dev-server
devServer
Π²Π΅Π±ΠΏΠ°ΠΊΠ° ΡΠΎΠ±ΠΈΡΠ°Π΅Ρ Π½Π°Ρ ΠΏΡΠΎΠ΅ΠΊΡ ΡΠ°ΠΊ ΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ ΠΏΡΠΈ ΠΎΠ±ΡΡΠ½ΠΎΠΉ ΡΠ±ΠΎΡΠΊΠ΅, Π½ΠΎ ΡΠΊΠ»Π°Π΄ΡΠ²Π°Π΅Ρ Π²ΡΠ΅ ΡΠΎΠ±ΡΠ°Π½Π½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ Π² ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠ²Π½ΡΡ ΠΏΠ°ΠΌΡΡΡ, ΡΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π΅ΠΌΡ Π½Π΅ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ ΡΡΡΠ°Π½ΠΈΡΡ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡΡ Π²ΡΠ΅ ΠΌΠΎΠ΄ΡΠ»ΠΈ ΠΈ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ. ΠΠΎΡΡΠΎΠΌΡ ΡΠ΅ΡΠ²Π΅Ρ WP ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ.
Π§ΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΊΠΎΠ½Π΅ΡΠ½ΡΠΉ Π±ΠΈΠ»Π΄, Π½ΡΠΆΠ½ΠΎ Π·Π°ΠΏΡΡΡΠΈΡΡ production
ΡΠ±ΠΎΡΠΊΡ Π²Π΅Π±ΠΏΠ°ΠΊΠ°.
ΠΡΠ»ΠΈ Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ, ΡΠΎ Π²ΠΌΠ΅ΡΡΠΎ -D
Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠΏΡΠΎΠ±ΠΎΠ²Π°ΡΡ -g
npm i webpack-dev-server -D
Π‘ΠΎΠ·Π΄Π°ΡΠΌ Π½ΠΎΠ²ΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ°
package.json
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production",
"watch": "webpack --mode development --watch",
// ΠΠΎΠΌΠ°Π½Π΄Π° ΡΡΠ°ΡΡΡΠ΅Ρ ΡΠ΅ΡΠ²Π΅Ρ Π²Π΅Π±ΠΏΠ°ΠΊΠ°
"start": "webpack serve"
},
Π’ΡΡ ΡΠΆΠ΅ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π΄Π»Ρ Π·Π°ΠΏΡΡΠΊΠ° Π±ΡΠ΄Π΅Ρ Π²ΠΏΠΈΡΠ°ΡΡ ΡΠ°ΠΊΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Ρ:
npm start
Π§ΡΠΎΠ±Ρ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠ°, Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π½Π°ΠΆΠ°ΡΡ ctrl+c
webpack.config.js
module.exports = {
context: path.resolve(__dirname, "src"),
mode: "development",
entry: {
main: "./index.js",
analytics: "./analytics.js",
},
output: {
filename: "[name].[contenthash].js",
path: path.resolve(__dirname, "public"),
},
// Π‘ΡΠ΄Π° Π²ΡΡΠ°Π²Π»ΡΠ΅ΠΌ Π°ΠΊΡΠΈΠ²Π°ΡΠΈΡ ΡΠ°Π±ΠΎΡΡ ΠΏΠ»Π°Π³ΠΈΠ½Π° devServer
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true, // ΠΡΠ»ΠΈ Π½ΡΠΆΠ½ΠΎ ΠΊΠΎΠΌΠΏΡΠ΅ΡΡΠΈΡ ΡΠ°ΠΉΠ»Π°
port: 9000, // ΠΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠΎΡΡ
open: true // ΠΠ²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ Π·Π°ΠΏΡΡΠΊΠ°Π΅Ρ ΡΡΡΠ°Π½ΠΈΡΡ Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅
},
plugins: [
new HTMLWebpackPlugin({
template: "./index.html",
}),
new CleanWebpackPlugin(),
],
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|jpe?g|gif)$/i,
use: ['file-loader'],
},
{
test: /\.(ttf|eot|woff|woff2)$/,
use: ['file-loader']
},
{
test: /\.xml$/,
use: ['xml-loader']
}
],
}
};
ΠΠΎΠΏΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²
Π’Π°ΠΊ ΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠ°Π·Π°ΡΡ Π½Π°ΡΠ΅ΠΌΡ WP ΠΊΡΠ΄Π° ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ (ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΠ»ΠΈ ΡΠΎΠ»ΡΠΊΠΎ Π² HTML)
npm i -D copy-webpack-plugin
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
<link rel="stylesheet" href="styles/style.css">
<!--Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΡΠ°Π²ΠΈΠΊΠΎΠ½ΠΊΡ-->
<link rel="icon" href="favicon.ico" type="image/icon">
</head>
webpack.config.js
// ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½
const CopyWebpackPlugin = require("copy-webpack-plugin");
// ....
plugins: [
new HTMLWebpackPlugin({
template: "./index.html",
}),
new CleanWebpackPlugin(),
// Π ΡΠ΅ΠΏΠ΅ΡΡ ΡΡΠΎΡ ΠΏΠ»Π°Π³ΠΈΠ½ ΠΏΠ΅ΡΠ΅Π½Π΅ΡΡΡ ΡΠΎΡΠΎΠ³ΡΠ°ΡΠΈΡ Π² Π²ΡΠ²ΠΎΠ΄ΠΈΠΌΡΡ ΠΏΠ°ΠΏΠΊΡ
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src/favicon.ico'),
to: path.resolve(__dirname, 'dist')
}
],
}),
],
// ....
ΠΠ°ΠΊ ΠΈΡΠΎΠ³, ΠΌΠΎΠΆΠ½ΠΎ ΡΠ²ΠΈΠ΄Π΅ΡΡ ΡΠ°Π²ΠΈΠΊΠΎΠ½ΠΊΡ, ΠΊΠΎΡΠΎΡΡΡ ΠΌΡ Π½Π°ΠΏΡΡΠΌΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΠ»ΠΈ Π² HTML
Π‘ΠΆΠ°ΡΠΈΠ΅ CSS, HTML, JS
ΠΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΈΡ CSS ΠΠ°Π½Π½ΡΠΉ ΠΏΠ»Π°Π³ΠΈΠ½ Π±ΡΠ΄Π΅Ρ Π²ΡΠ²ΠΎΠ΄ΠΈΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ CSS ΡΠ°ΠΉΠ»Ρ ΠΈ Π½ΠΎΡΠΌΠ°Π»ΡΠ½ΠΎ ΠΈΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ
npm install --save-dev mini-css-extract-plugin
ΠΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌ Π½Π΅Π±ΠΎΠ»ΡΡΠΈΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΈ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½ Π² ΠΊΠΎΠ½ΡΠΈΠ³
webpack.config.js
const MiniCSSExtractPlugin = require("mini-css-extract-plugin");
// ....
plugins: [
new HTMLWebpackPlugin({
template: "./index.html",
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src/favicon.ico'),
to: path.resolve(__dirname, 'dist')
}
],
}),
// ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΠΌΠΈΠ½ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ CSS
new MiniCSSExtractPlugin({
// ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ ΠΈΠ· output ΠΏΡΡΡ ΠΈ ΠΌΠ΅Π½ΡΠ΅ΠΌ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ Π½Π° '.css'
filename: "[name].[contenthash].css",
}),
],
module: {
rules: [
{
test: /\.css$/,
// ΠΠ΅Π½ΡΠ΅ΠΌ 'style-loader' Π½Π° Π»ΠΎΠ°Π΄Π΅Ρ ΠΌΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ°
use: [MiniCSSExtractPlugin.loader, 'css-loader']
},
{
test: /\.(png|jpe?g|gif)$/i,
use: ['file-loader'],
},
{
test: /\.(ttf|eot|woff|woff2)$/,
use: ['file-loader']
},
{
test: /\.xml$/,
use: ['xml-loader']
},
{
test: /\.csv$/,
use: ['csv-loader'],
}
],
}
Π£Π±ΠΈΡΠ°Π΅ΠΌ ΠΈΠ· ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ CSS, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΠ΅ΠΏΠ΅ΡΡ ΠΎΠ½ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡΡΡ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Webpack</title>
<!--Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΡΠ°Π²ΠΈΠΊΠΎΠ½ΠΊΡ-->
<link rel="icon" href="favicon.ico" type="image/icon">
</head>
ΠΠΎΡ ΡΠ°ΠΊ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ Π²ΡΡ ΠΎΠ΄Π½ΠΎΠΉ HTML-ΡΠ°ΠΉΠ»
Π’ΡΡ ΠΌΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΠ»ΠΈ
- ΠΊΠ°ΠΊ ΡΠ°ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ Π² Π½Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ
- ΡΠ°ΠΊ ΠΈ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π»ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ ΡΠ΅ΠΆΠΈΠΌΠ° Π΄Π»Ρ Π½Π°ΡΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ² ΠΈ Π΅ΡΠ»ΠΈ ΠΌΡ Π½Π°Ρ ΠΎΠ΄ΠΈΠΌΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ, ΡΠΎ Ρ Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Π°ΠΊΡΠΈΠ²Π½Π° ΡΠΌΠ΅Π½Π° ΠΌΠΎΠ΄ΡΠ»Π΅ΠΉ Π±Π΅Π· ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΡΡΡΠ°Π½ΠΈΡΡ
webpack.config.js
// ΠΡΠ° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Ρ
ΡΠ°Π½ΠΈΡΡ Π² ΡΠ΅Π±Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ ΡΠ°ΠΉΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ
const isDev = process.env.NODE_ENV === "development";
// ...
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 9000,
open: true,
// ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠΆΠ°Π΅Ρ ΡΡΡΠ°Π½ΠΈΡΡ Π΅ΡΠ»ΠΈ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°
hot: isDev,
},
module: {
rules: [
{
test: /\.css$/,
// Π’Π°ΠΊ ΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π±ΠΎΠ»Π΅Π΅ Π΄Π΅ΡΠ°Π»ΡΠ½ΠΎ Π½Π°ΡΡΡΠΎΠΈΡΡ ΠΏΠ»Π°Π³ΠΈΠ½, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΏΠ΅ΡΠ²ΡΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠΌ ΠΎΠ½ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π² ΡΠ΅Π±Ρ ΠΏΠΎΠ»ΠΎΠΆΠΈΡΡ ΠΎΠ±ΡΠ΅ΠΊΡ Ρ ΡΠ°ΠΌΠΈΠΌ Π»ΠΎΠ°Π΄Π΅ΡΠΎΠΌ ΠΈ Π΅Π³ΠΎ ΠΎΠΏΡΠΈΡΠΌΠΈ
use: [{
loader: MiniCSSExtractPlugin.loader,
options: {
// hot module reload - ΠΌΠ΅Π½ΡΠ΅Ρ ΡΡΡΠ½ΠΎΡΡΠΈ Π±Π΅Π· ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠ·ΠΊΠΈ
// ΠΡΠ»ΠΈ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°, ΡΠΎ Π±ΡΠ΄Π΅Ρ Π°ΠΊΡΠΈΠ²Π½ΠΎ
hmr: isDev,
reloadAll: true
}
}, 'css-loader']
},
// ....
Π§ΡΠΎΠ±Ρ ΠΏΡΠΎΠ²Π΅ΡΠΈΡΡ ΡΠ°Π±ΠΎΡΡ ΡΠΌΠ΅Π½Ρ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΉ, Π½ΡΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠΌ Π΄Π»Ρ ΠΈΡ ΡΠΌΠ΅Π½Ρ:
npm i -G cross-env
Π‘ΡΡΠΎΡΠΊΠ°ΠΌΠΈ cross-env NODE_ENV=development
ΠΌΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ ΡΡΠ΅Π΄Ρ Π½Π°ΡΠ΅ΠΉ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ (ΠΏΡΠΎΠ΄Π°ΠΊΡΠ΅Π½ ΠΈΠ»ΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ°). ΠΡΠΎΡ ΠΊΠΎΠ΄ Π² ΡΠΊΡΠΈΠΏΡΠ°Ρ
ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ Π½Π°ΠΌ Π²ΡΠ΅Π³Π΄Π° ΠΊΠΎΠ½ΡΡΠΎΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠ΅Π΄Ρ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΡ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌΡΡ ΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΡΠ°Π±ΠΎΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΡΡ
Π½Π°ΡΠΈΡ
ΡΡΠ½ΠΊΡΠΈΠΉ Π²Π΅Π±ΠΏΠ°ΠΊΠ°
package.json
"scripts": {
"dev": "cross-env NODE_ENV=development webpack --mode development",
"build": "cross-env NODE_ENV=production webpack --mode production",
"watch": "cross-env NODE_ENV=development webpack --mode development --watch",
"start": "cross-env NODE_ENV=development webpack serve"
},
Π‘Π°ΠΌ ΠΏΠ»Π°Π³ΠΈΠ½ Π΄Π»Ρ ΠΌΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ CSS:
npm install css-minimizer-webpack-plugin --save-dev
const MiniCSSExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
// ΠΡΠ° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Ρ
ΡΠ°Π½ΠΈΡΡ Π² ΡΠ΅Π±Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ ΡΠ°ΠΉΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ
const isDev = process.env.NODE_ENV === "development";
const isProd = process.env.NODE_ENV === "production";
const optimization = () => {
const config = {
splitChunks: {
chunks: 'all'
} }
// ΠΡΠ»ΠΈ ΡΠ΅ΠΆΠΈΠΌ ΠΏΡΠΎΠ΄Π°ΠΊΡΠ΅Π½Π°
if (isProd) {
// ΡΠΎ Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ minimizer Ρ ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠΌ ΠΌΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ
config.minimizer = [
new CssMinimizerPlugin() // ΡΠ°ΠΌ ΠΌΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΎΡ CSS
]
}
return config;
}
// ....
module.exports = {
context: path.resolve(__dirname, "src"),
mode: "development",
entry: {
main: "./index.js",
analytics: "./analytics.js",
},
// Π’ΡΡ Π½ΡΠΆΠ½ΠΎ Π²Π»ΠΎΠΆΠΈΡΡ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠ³Π΅Π½Π΅ΡΠΈΡΡΠ΅Ρ Π½Π°Ρ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ
optimization: optimization(),
// ....
ΠΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΈΡ JS
npm install terser-webpack-plugin --save-dev
webpack.config.js
// ΠΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΠΌΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΎΡ JS
const TerserPlugin = require("terser-webpack-plugin");
// ΠΡΠ° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Ρ
ΡΠ°Π½ΠΈΡΡ Π² ΡΠ΅Π±Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ ΡΠ°ΠΉΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ
const isDev = process.env.NODE_ENV === "development";
const isProd = process.env.NODE_ENV === "production";
const optimization = () => {
const config = {
splitChunks: {
chunks: 'all'
} }
if (isProd) {
config.minimizer = [
new TerserPlugin(), // ΠΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΠΌΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΎΡ JS
new CssMinimizerPlugin(),
]
}
return config;
}
ΠΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΈΡ HTML Π£ΠΆΠ΅ ΡΡΠΎΡ ΠΊΠΎΠ΄ Π±ΡΠ΄Π΅Ρ ΠΌΠΈΠ½ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ HTML ΠΊΠΎΠ΄ ΠΏΡΠΈ ΡΠ°Π±ΠΎΡΠ΅ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΠΏΡΠΎΠ΄Π°ΠΊΡΠ΅Π½Π°
webpack.config.js
// ΠΡΠ»ΠΈ ΡΠ°Π±ΠΎΡΠ°Π΅ΠΌ Π² ΠΏΡΠΎΠ΄Π°ΠΊΡΠ½ ΡΠ΅ΠΆΠΈΠΌΠ΅...
const isProd = process.env.NODE_ENV === "production";
// ....
plugins: [
new HTMLWebpackPlugin({
template: "./index.html",
// Π’ΡΡ ΡΠΆΠ΅ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ ΠΌΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΈΡ
minify: {
// ...ΡΠΎ ΡΠΆΠΈΠΌΠ°Π΅ΠΌ Π²ΡΠ΅ ΠΏΡΠΎΠ±Π΅Π»Ρ Π² ΠΊΠΎΠ΄Π΅
collapseWhitespace: isProd
}
}),
// ...
ΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ Less ΠΈ Sass
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΡΠ°ΠΌ less, sass ΠΈ ΠΈΡ Π΅Π³ΠΎ Π»ΠΎΠ°Π΄Π΅ΡΡ Π² Π½Π°Ρ ΠΏΡΠΎΠ΅ΠΊΡ
npm install less less-loader --save-dev
npm install sass-loader sass webpack --save-dev
ΠΠ°Π»Π΅Π΅ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΠΏΡΠ°Π²ΠΈΠ»ΠΎ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π±ΡΠ΄Π΅Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ less ΠΈ sass
ΠΏΠΎΠ»Π½ΡΠΉΠΊΠΎΠ½ΡΠΈΠ³
wenpack.config.js
const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const MiniCSSExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
// ΠΡΠ° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Ρ
ΡΠ°Π½ΠΈΡΡ Π² ΡΠ΅Π±Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ ΡΠ°ΠΉΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ
const isDev = process.env.NODE_ENV === "development";
const isProd = process.env.NODE_ENV === "production";
const optimization = () => {
const config = {
splitChunks: {
chunks: 'all'
} }
if (isProd) {
config.minimizer = [
new TerserPlugin(),
new CssMinimizerPlugin(),
]
}
return config;
}
// ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ Π½Π°ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π°
const filename = ext => isDev ? `[name].${ext}` : `[name].[hash].${ext}`;
module.exports = {
context: path.resolve(__dirname, "src"),
mode: "development",
entry: {
main: "./index.js",
analytics: "./analytics.js",
},
optimization: optimization(),
output: {
filename: filename('js'),
path: path.resolve(__dirname, "dist"),
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, "src"),
'@components': path.resolve(__dirname, 'src/components'),
'@utilities': path.resolve(__dirname, 'src/utilities')
}
},
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 9000,
open: true,
hot: isDev, // ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠΆΠ°Π΅Ρ ΡΡΡΠ°Π½ΠΈΡΡ Π΅ΡΠ»ΠΈ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°
},
plugins: [
new HTMLWebpackPlugin({
template: "./index.html",
minify: {
collapseWhitespace: isProd
}
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src/favicon.ico'),
to: path.resolve(__dirname, 'dist')
}
],
}),
new MiniCSSExtractPlugin({
// ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ ΠΈΠ· output
filename: filename('css'),
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [MiniCSSExtractPlugin.loader, 'css-loader']
},
// Π’ΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ SASS/SCSS
{
test: /\.s[ac]ss$/i,
use: [
"style-loader", // ΠΈΠ»ΠΈ MiniCSSExtractPlugin.loader
"css-loader",
"sass-loader",
],
},
// Π ΡΡΡ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ LESS
{
test: /\.less$/i,
use: [
// compiles Less to CSS
"style-loader", // ΠΈΠ»ΠΈ MiniCSSExtractPlugin.loader
"css-loader",
"less-loader",
],
},
{
test: /\.(png|jpe?g|gif)$/i,
use: ['file-loader'],
},
{
test: /\.(ttf|eot|woff|woff2)$/,
use: ['file-loader']
},
{
test: /\.xml$/,
use: ['xml-loader']
},
{
test: /\.csv$/,
use: ['csv-loader'],
}
],
}
};
Π‘ΡΠΈΠ»ΠΈ Less
@border: 1px solid #ccc;
.box {
padding: 1rem;
border-radius: 5px;
margin-top: 1rem;
border: @border;
h2 {
text-align: center;
color: darkblue;
}
}
Π‘ΡΠΈΠ»ΠΈ SCSS
$border: 1px solid #ccc;
.card {
padding: 1rem;
border-radius: 5px;
margin-top: 1rem;
border: $border;
h2 {
text-align: center;
color: darkred;
}
}
ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°Π΅ΠΌ ΡΡΠΈΠ»ΠΈ Π² ΡΠ°ΠΉΠ» ΡΠΊΡΠΈΠΏΡΠ°
index.js
import './styles/style.css';
import './styles/less.less';
import './styles/scss.scss';
ΠΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΡ
Π§ΡΠΎΠ±Ρ ΡΠΎΠΊΡΠ°ΡΠΈΡΡ ΠΏΠΎΠ²ΡΠΎΡΡΡΡΠΈΠΉΡΡ ΠΊΠΎΠ΄, ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ½Π΅ΡΡΠΈ Π΅Π³ΠΎ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ, Π² ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄Π΅ΠΌ Π²ΠΊΠ»Π°Π΄ΡΠ²Π°ΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ
ΠΏΠΎΠ»Π½ΡΠΉΠΊΠΎΠ½ΡΠΈΠ³
webpack.config.js
const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const MiniCSSExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
// ΠΡΠ° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Ρ
ΡΠ°Π½ΠΈΡΡ Π² ΡΠ΅Π±Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ ΡΠ°ΠΉΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ
const isDev = process.env.NODE_ENV === "development";
const isProd = process.env.NODE_ENV === "production";
const optimization = () => {
const config = {
splitChunks: {
chunks: 'all'
} }
if (isProd) {
config.minimizer = [
new TerserPlugin(),
new CssMinimizerPlugin(),
]
}
return config;
}
// ΠΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³Π° Π² ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ, ΠΊΠΎΡΠΎΡΠΎΠ΅ Ρ
ΡΠ°Π½ΠΈΡ ΡΠ²Π΅Π΄Π΅Π½ΠΈΡ ΠΎ Π»ΠΎΠ°Π΄Π΅ΡΠ°Ρ
Π΄Π»Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΡ
ΡΠ°ΠΉΠ»Π°Ρ
const cssLoaders = (extra) => {
const loader = [
MiniCSSExtractPlugin.loader,
'css-loader',
];
// Π΅ΡΠ»ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΅ΡΡΡ, ΡΠΎ ΠΏΡΡΠΈΠΌ Π΅Π³ΠΎ Π² ΠΌΠ°ΡΡΠΈΠ²
if(extra) loader.push(extra);
return loader;
}
// ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ Π½Π°ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π°
const filename = ext => isDev ? `[name].${ext}` : `[name].[hash].${ext}`;
module.exports = {
context: path.resolve(__dirname, "src"),
mode: "development",
entry: {
main: "./index.js",
analytics: "./analytics.js",
},
optimization: optimization(),
output: {
filename: filename('js'),
path: path.resolve(__dirname, "dist"),
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, "src"),
'@components': path.resolve(__dirname, 'src/components'),
'@utilities': path.resolve(__dirname, 'src/utilities')
}
},
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 9000,
open: true,
hot: isDev, // ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠΆΠ°Π΅Ρ ΡΡΡΠ°Π½ΠΈΡΡ Π΅ΡΠ»ΠΈ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°
},
plugins: [
new HTMLWebpackPlugin({
template: "./index.html",
minify: {
collapseWhitespace: isProd
}
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src/favicon.ico'),
to: path.resolve(__dirname, 'dist')
}
],
}),
new MiniCSSExtractPlugin({
// ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ ΠΈΠ· output
filename: filename('css'),
}),
],
module: {
rules: [
{
test: /\.css$/,
// ΡΡΡ ΡΠΆΠ΅ ΠΌΡ ΠΏΡΠΎΡΡΠΎ Π²ΡΠ·Π²Π°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ Π²ΡΡΠ°Π²Π»ΡΡΡ Π½ΡΠΆΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠΈΠ³
use: cssLoaders(),
},
{
test: /\.s[ac]ss$/i,
// ΡΡΡ ΡΠΆΠ΅ ΠΌΡ ΠΏΡΠΎΡΡΠΎ Π²ΡΠ·Π²Π°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ Π²ΡΡΠ°Π²Π»ΡΡΡ Π½ΡΠΆΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ
use: cssLoaders('sass-loader'),
},
{
test: /\.less$/i,
// ΡΡΡ ΡΠΆΠ΅ ΠΌΡ ΠΏΡΠΎΡΡΠΎ Π²ΡΠ·Π²Π°Π΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ Π²ΡΡΠ°Π²Π»ΡΡΡ Π½ΡΠΆΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ
use: cssLoaders('less-loader'),
},
{
test: /\.(png|jpe?g|gif)$/i,
use: ['file-loader'],
},
{
test: /\.(ttf|eot|woff|woff2)$/,
use: ['file-loader']
},
{
test: /\.xml$/,
use: ['xml-loader']
},
{
test: /\.csv$/,
use: ['csv-loader'],
}
],
}
};
Babel
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ Π½ΡΠΆΠ½ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ babel
npm install -D babel-loader @babel/core @babel/preset-env webpack
Π’Π°ΠΊ ΠΆΠ΅ Π½ΡΠΆΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΏΠΎΠ»ΠΈΡΠΈΠ»Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΈΡΡ ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ (async/await, get/set) ΠΏΠΎΠ΄ ΡΡΠ°ΡΡΠ΅ ΡΡΠ°Π½Π΄Π°ΡΡΡ
npm install --save @babel/polyfill
ΠΡ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π½ΠΎΠ²ΡΠ΅ ΠΏΡΠ°Π²ΠΈΠ»Π° Π΄Π»Ρ Π°ΠΊΡΠΈΠ²Π°ΡΠΈΠΈ ΡΠ°Π±ΠΎΡΡ babel Π²Π½ΡΡΡΠΈ webpack
webpack.config.js
// ....
module.exports = {
context: path.resolve(__dirname, 'src'),
mode: 'development',
entry: {
// ΡΡΡ ΠΊΠ°ΠΊ ΡΠΎΡΠΊΡ Π²Ρ
ΠΎΠ΄Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ ΠΌΠ°ΡΡΠΈΠ², ΠΏΠ΅ΡΠ²ΡΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π±ΡΠ΄ΡΡ ΡΠ²Π»ΡΡΡΡΡ ΠΏΠΎΠ»ΠΈΡΠΈΠ»Ρ babel
main: ['@babel/polyfill', './index.js'],
analytics: './analytics.js',
},
// ....
{
// ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°Π΅ΠΌ js-ΡΠ°ΠΉΠ»Ρ
test: /\.m?js$/,
// ΠΈΡΠΊΠ»ΡΡΠ°Π΅ΠΌ Π½ΠΎΠ΄-ΠΌΠΎΠ΄ΡΠ»ΠΈ ΠΈΠ· ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ
exclude: /node_modules/,
use: {
// ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π»ΠΎΠ°Π΄Π΅Ρ babel
loader: "babel-loader",
options: {
// Π² ΠΎΠΏΡΠΈΡΡ
ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ ΠΏΡΠ΅ΡΠ΅ΡΡ
presets: ['@babel/preset-env']
}
}
}
package.json
{
"name": "webpack",
// ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΡΠ°ΠΊ, ΡΡΠΎΠ±Ρ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π»ΠΈ ΡΠΎΠ»ΡΠΊΠΎ 0,25% Π±ΡΠ°ΡΠ·Π΅ΡΠΎΠ², Π° Π²ΡΠ΅ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ - ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π»ΠΈΡΡ
"browserList": ">0.25%, not dead",
"version": "1.0.0",
"description": "",
// ...
ΠΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ² Π΄Π»Ρ Babel
npm install --save-dev @babel/plugin-proposal-class-properties
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: [
'@babel/plugin-proposal-class-properties',
]
},
},
},
class Util {
static id = Date.now();
}
console.log(Util.id); // Π²ΡΠ²Π΅Π΄Π΅Ρ Π΄Π°ΡΡ
ΠΡΠΈΠ²Π΅Π΄ΡΠ½Π½ΡΠΉ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΏΠ»Π°Π³ΠΈΠ½ ΡΠΆΠ΅ Π²Ρ ΠΎΠ΄ΠΈΡ Π²
preset-env
ΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ TypeScript
ΠΠ»Ρ Π½Π°ΡΠ°Π»Π° ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ Π½ΡΠΆΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΏΡΠ΅ΡΠ΅Ρ Π½Π° Π’Π‘
npm install --save-dev @babel/preset-typescript
ΠΠ°Π»ΡΡΠ΅ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΏΡΠ°Π²ΠΈΡΡ ΠΊΠΎΠ½ΡΠΈΠ³
// ...
module.exports = {
context: path.resolve(__dirname, 'src'),
mode: 'development',
entry: {
main: ['@babel/polyfill', './index.js'],
// ΡΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π²ΡΠΎΡΠΎΠΉ ΡΠΎΡΠΊΠΈ Π²Ρ
ΠΎΠ΄Π° ΠΏΠΎΡΡΠ°Π²ΠΈΡΡ ts (ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΠΎΡ ΡΠ°ΠΉΠ» ΠΌΡ ΠΏΠ΅ΡΠ΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π»ΠΈ Π² ts ΠΈΠ· js)
analytics: './analytics.ts',
},
// ...
// ΠΡΠΎ ΡΠΆΠ΅ ΠΏΡΠ°Π²ΠΈΠ»Π° Π΄Π»Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ ts
{
test: /\.ts$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
// Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΏΡΠ΅ΡΠ΅Ρ Π½Π° ts
'@babel/preset-typescript',
],
},
},
},
// ...
ΠΡΠΎ ΡΠ°ΠΌΠ° Π°Π½Π°Π»ΠΈΡΠΈΠΊΠ°, ΠΏΠ΅ΡΠ΅Π΄Π΅Π»Π°Π½Π½Π°Ρ Π² TS
import * as $ from 'jquery';
function createAnalytics(): Object {
let counter = 0;
let isDestroyed: boolean = false;
const listener = (): number => counter++;
$(document).on('click', listener);
return {
destroy() {
$(document).off('click', listener);
isDestroyed = true;
},
getClicks() {
if (isDestroyed) {
return 'Analytics is destroyed';
}
return counter;
},
};
}
window['analytics'] = createAnalytics();
Π’Π°ΠΊ ΠΆΠ΅ ΠΊΠ°ΠΊ ΠΈ Π² ΠΏΡΠΎΡΠ»ΡΡ ΡΠ»ΡΡΠ°ΡΡ , ΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΡΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠΎΠ½ΡΠΈΠ³
// ΠΡΠΎ ΠΎΠΏΡΠΈΠΈ ΠΏΠΎΠ΄ ΡΠΈΠΏΡ ΠΏΡΠ΅ΡΠ΅ΡΠΎΠ² babel
const babelOptions = (ext) => {
const options = {
presets: [
'@babel/preset-env',
],
}
if (ext) options.presets.push(ext);
return options;
}
// ...
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: babelOptions(),
},
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: babelOptions('@babel/preset-typescript'),
},
},
ΠΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ React JSX
npm install --save-dev @babel/preset-react
npm i react react-dom
webpack.config.js
entry: {
// ΡΠΎΡΠΊΡ Π²Ρ
ΠΎΠ΄Π° Π² Π²Π΅Π±ΠΏΠ°ΠΊΠ΅ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅Π½ΡΡΡ Π½Π° '.jsx'
main: ['@babel/polyfill', './index.jsx'],
analytics: './analytics.ts',
},
// ....
// ΠΡΠΎ ΠΏΡΠ°Π²ΠΈΠ»Π° Π΄Π»Ρ ΡΠ°Π±ΠΎΡΡ ΠΈ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ JSX
{
test: /\.jsx$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
// Π£ΡΡΠ°Π½Π°Π²Π»Π²ΠΈΠ°Π΅ΠΌ ΠΏΡΠ΅ΡΠ΅Ρ
options: babelOptions('@babel/preset-react'),
},
},
index.jsx
import './babel';
import './styles/style.css';
import './styles/less.less';
import './styles/scss.scss';
import React, { Component } from 'react';
import ReactDOM from 'react-dom/client';
class App extends Component {
render() {
return (
<div className='container'>
<h1>WP Course</h1>
<hr />
<div className='logo' />
<hr />
<hr />
<pre />
<hr />
<div className='box'>
<h2>Less</h2>
</div>
<hr />
<div className='card'>
<h2>SCSS</h2>
</div>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
Devtool
Π’Π°ΠΊ ΠΆΠ΅ Π² WP ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΡΡΠΎΠΈΡΡ ΡΠ΅ΠΆΠΈΠΌΡ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΠΈ ΠΏΠΎ ΠΎΠ³ΡΠΎΠΌΠ½ΠΎΠΉ ΡΠ°Π±Π»ΠΈΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ
Π ΠΊΠΎΠ½ΡΠΈΠ³ WP Π½ΡΠΆΠ½ΠΎ Π²ΠΏΠΈΡΠ°ΡΡ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ devtool
, ΠΊΠΎΡΠΎΡΠΎΠΌΡ ΠΏΠΎ ΡΡΠ»ΠΎΠ²ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π·Π½Π°ΡΠΈΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΡΠΉ ΡΠΈΠΏ ΠΊΠΎΠΌΠΏΠ°ΠΉΠ»Π° ΠΊΠ°ΡΡ
webpack.config.js
module.exports = {
context: path.resolve(__dirname, 'src'),
mode: 'development',
// ΡΡΡ ΡΠΆΠ΅ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° Π±ΡΠ΄Π΅ΠΌ Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ ΠΊΠ°ΡΡΡ
devtool: isDev ? 'source-map' : 'eval-cheap-source-map',
Π ΡΠ΅ΠΏΠ΅ΡΡ ΠΊΠ°ΡΡΡ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡ, Π² ΠΊΠ°ΠΊΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ Π±ΡΠ»ΠΈ ΡΠΎΠ·Π΄Π°Π½Ρ ΡΡΠΈΠ»ΠΈ ΠΈ Π½Π° ΠΊΠ°ΠΊΠΎΠΉ ΡΡΡΠΎΠΊΠ΅ ΠΎΠ½ΠΈ ΡΠ°ΡΠΏΠΎΠ»Π°Π³Π°ΡΡΡΡ (ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΡ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠΉ ΠΈΠ· Π±ΡΠ°ΡΠ·Π΅ΡΠ°)
Π ΡΠ°ΠΊ ΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅Ρ ΠΈΡΡ ΠΎΠ΄Π½ΠΈΠΊ Π² ΡΠ°ΠΌΠΎΠΌ Π±ΡΠ°ΡΠ·Π΅ΡΠ΅
ESLint
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΡΠ°ΠΌ eslint
ΠΈ babel
-ΠΏΠ°ΡΡΠ΅Ρ Π΄Π»Ρ Π΅ΡΠ»ΠΈΠ½ΡΠ°
npm i -D eslint-loader
npm i -D babel-eslint
ΠΠΎΠ±Π°Π²ΠΈΠΌ ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π»ΠΎΠ°Π΄Π΅ΡΡ Π΄Π»Ρ JS ΠΈ Π·Π°ΠΊΠΈΠ½Π΅ΠΌ eslint-loader
Π² ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ JS
webpack.config.js
// Π±ΡΠ΄Π΅Ρ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ Π»ΠΎΠ°Π΄Π΅ΡΡ
const jsLoaders = ext => {
const loaders = [
{
loader: ['babel-loader'],
options: babelOptions(),
},
];
if (ext) loaders.push(ext);
return loaders;
};
// ....
{
test: /\.js$/,
exclude: /node_modules/,
use: jsLoaders('eslint-loader'),
},
babel.js
- ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π΄Π»Ρ ΠΏΡΠΈΠΌΠ΅ΡΠ° ΠΎΠ΄Π½Ρ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ
const unused = 10;
.eslintrc
- ΡΠΎΠ·Π΄Π°ΡΠΌ Π² ΠΊΠΎΡΠ½Π΅ ΠΏΡΠΎΠ΅ΠΊΡΠ°
{
// ΠΠ°Π·Π½Π°ΡΠΈΠΌ ΠΏΠ°ΡΡΠ΅Ρ ΠΏΠΎΠ΄ Π±ΡΠΉΠ±Π΅Π»Ρ
"parser": "babel-eslint",
// Π‘ΠΊΠ°ΠΆΠ΅ΠΌ, ΡΡΠΎΠ±Ρ Π²ΡΠΏΠ°Π΄Π°Π»ΠΈ Π²Π°ΡΠ½ΠΈΠ½Π³ΠΈ, Π΅ΡΠ»ΠΈ Π±ΡΠ΄ΡΡ ΠΎΠ±Π½Π°ΡΡΠΆΠ΅Π½Ρ Π½Π΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅
"rules": {
"no-unused-vars": "warn"
},
// Π°ΠΊΡΠΈΠ²ΠΈΡΡΠ΅ΠΌ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΡ ES6
"env": {
"es6": true,
"browser": true
},
"extends": [
"eslint:recommended"
]
}
ΠΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΈΠΌΠΏΠΎΡΡΡ
ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° ΠΏΡΠΎΡΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΉ
npm i -D lodash
ΠΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΠΈΠΌΠΏΠΎΡΡΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ Π½Π°ΠΌ Π²ΡΡΠ°Π²ΠΈΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ Π² Π»ΡΠ±ΠΎΠΌ ΡΡΠ°ΡΡΠΊΠ΅ ΠΊΠΎΠ΄Π° ΠΈ ΡΡΠ°Π·Ρ ΠΆΠ΅ Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
babel.js
import('lodash').then(_ => {
console.log('Lodash: ', _.random(10, 11, true));
});
ΠΠ½Π°Π»ΠΈΠ· ΡΠΈΠ½Π°Π»ΡΠ½ΠΎΠΉ ΡΠ±ΠΎΡΠΊΠΈ
npm iΒ webpack-bundle-analyzer -D
// ....
// ΠΈΠΌΠΏΠΎΡΡΠΈΡΡΠ΅ΠΌ ΡΡΠ½ΠΊΡΠΈΡ Π°Π½Π°Π»ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΊΠΎΠ½ΡΠΈΠ³Π°
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
// ΠΡΠΎ ΡΠΏΠΈΡΠΎΠΊ Π½Π°ΡΠΈΡ
ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ², ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Π·Π°Π²ΠΈΡΠ΅ΡΡ ΠΎΡ
const plugins = () => {
const base = [
new HTMLWebpackPlugin({
template: './index.html',
minify: {
collapseWhitespace: isProd,
},
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src/favicon.ico'),
to: path.resolve(__dirname, 'dist'),
},
],
}),
new MiniCSSExtractPlugin({
// ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ ΠΈΠ· output
filename: filename('css'),
}),
];
if (isProd) base.push(new BundleAnalyzerPlugin());
return base;
};
// ....
module.exports = {
plugins: plugins(),
// ....
Π ΡΠ΅ΠΏΠ΅ΡΡ ΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ²ΠΈΠ΄Π΅ΡΡ, ΡΠΊΠΎΠ»ΡΠΊΠΎ Π·Π°Π½ΠΈΠΌΠ°ΡΡ ΠΌΠ΅ΡΡΠ° ΡΠ°Π·Π½ΡΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π² Π½Π°ΡΠ΅ΠΌ ΠΏΡΠΎΠ΅ΠΊΡΠ΅
ΠΠΈΠ±ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΠΈΡΠ°ΡΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΡΡΠΎΠ³ΠΎ ΠΏΠ»Π°Π³ΠΈΠ½Π° ΡΠ΅ΡΠ΅Π· ΡΠΊΡΠΈΠΏΡ
package.json
"scripts": {
"stats": "webpack --json > stats.json && webpack-bundle-analyzer stats.json"
ΠΠΎΠ»Π½ΡΠΉ ΠΊΠΎΠ½ΡΠΈΠ³ ΡΠ±ΠΎΡΠΊΠΈ
ΠΠ°ΠΏΠΊΠ° ΠΏΡΠΎΠ΅ΠΊΡΠ°:
ΠΠΎΠ½ΡΠΈΠ³:
const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
// ΠΡΠ° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ Π±ΡΠ΄Π΅Ρ Ρ
ΡΠ°Π½ΠΈΡΡ Π² ΡΠ΅Π±Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π½Π°Ρ
ΠΎΠ΄ΠΈΡΡΡ ΡΠ°ΠΉΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ
const isDev = process.env.NODE_ENV === 'development';
const isProd = process.env.NODE_ENV === 'production';
// ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΏΠΎΠ΄ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠΈΠΏ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠ²ΠΎΡ ΠΌΠΈΠ½ΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²
const optimization = () => {
const config = {
splitChunks: {
chunks: 'all',
},
};
if (isProd) {
config.minimizer = [new TerserPlugin(), new CssMinimizerPlugin()];
}
return config;
};
// ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅Ρ ΠΎΠΏΡΠΈΠΈ Π»ΠΎΠ°Π΄Π΅ΡΠΎΠ²
const cssLoaders = extra => {
const loader = [MiniCSSExtractPlugin.loader, 'css-loader'];
if (extra) loader.push(extra);
return loader;
};
// ΠΡΠΎ ΠΎΠΏΡΠΈΠΈ ΠΏΠΎΠ΄ ΡΠΈΠΏΡ ΠΏΡΠ΅ΡΠ΅ΡΠΎΠ² babel
const babelOptions = ext => {
const options = {
presets: ['@babel/preset-env'],
};
if (ext) options.presets.push(ext);
return options;
};
// Π±ΡΠ΄Π΅Ρ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ Π»ΠΎΠ°Π΄Π΅ΡΡ
// const jsLoaders = ext => {
// const loaders = [
// {
// loader: ['babel-loader'],
// options: babelOptions(),
// },
// ];
//
// if (isDev) loaders.push(ext);
//
// return loaders;
// };
// ΡΡΠ° ΡΡΠ½ΠΊΡΠΈΡ Π±ΡΠ΄Π΅Ρ Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ Π½Π°ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π°
const filename = ext => (isDev ? `[name].${ext}` : `[name].[hash].${ext}`);
const plugins = () => {
const base = [
new HTMLWebpackPlugin({
template: './index.html',
minify: {
collapseWhitespace: isProd,
},
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{
from: path.resolve(__dirname, 'src/favicon.ico'),
to: path.resolve(__dirname, 'dist'),
},
],
}),
new MiniCSSExtractPlugin({
// ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ ΠΈΠ· output
filename: filename('css'),
}),
];
if (isProd) base.push(new BundleAnalyzerPlugin());
return base;
};
module.exports = {
context: path.resolve(__dirname, 'src'),
mode: 'development',
devtool: isDev ? 'source-map' : 'eval-cheap-source-map',
entry: {
main: ['@babel/polyfill', './index.jsx'],
analytics: './analytics.ts',
},
optimization: optimization(),
output: {
filename: filename('js'),
path: path.resolve(__dirname, 'dist'),
},
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@': path.resolve(__dirname, 'src'),
'@components': path.resolve(__dirname, 'src/components'),
'@utilities': path.resolve(__dirname, 'src/utilities'),
},
},
devServer: {
static: {
directory: path.join(__dirname, 'dist'),
},
compress: true,
port: 9000,
open: true,
hot: isDev, // ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠΆΠ°Π΅Ρ ΡΡΡΠ°Π½ΠΈΡΡ Π΅ΡΠ»ΠΈ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌΡΡ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°
},
plugins: plugins(),
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: babelOptions(),
},
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: babelOptions('@babel/preset-typescript'),
},
},
{
test: /\.jsx$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: babelOptions('@babel/preset-react'),
},
},
{
test: /\.css$/,
use: cssLoaders(),
},
{
test: /\.s[ac]ss$/i,
use: cssLoaders('sass-loader'),
},
{
test: /\.less$/i,
use: cssLoaders('less-loader'),
},
{
test: /\.(png|jpe?g|gif)$/i,
use: ['file-loader'],
},
{
test: /\.(ttf|eot|woff|woff2)$/,
use: ['file-loader'],
},
{
test: /\.xml$/,
use: ['xml-loader'],
},
{
test: /\.csv$/,
use: ['csv-loader'],
},
],
},
};