Автор: Валентино Гальярди.
Переводчик: Front-end Xiaozhi
Источник: Валентиног
Ставь лайк и смотри, поиск в WeChat【Переезд в мир】Обратите внимание на этого человека, который не имеет большого фабричного прошлого, но имеет восходящий и позитивный настрой. эта статья
GitHub
GitHub.com/QQ449245884…Он был включен, статьи были классифицированы, и многие мои документы и учебные материалы были систематизированы.
Должны ли мы изучать веб-пакет?
сейчас,инструменты командной строки(Такие какcreate-react-app
илиVue -cli
) уже абстрагирует для нас большую часть конфигурации и предоставляет разумные значения по умолчанию.
Даже в этом случае хорошо знать, как все работает за кулисами, потому что рано или поздно нам нужно будет внести некоторые изменения в настройки по умолчанию.
В этой статье мы увидим, на что способен веб-пакет и как его настроить для наших повседневных нужд.
Что такое вебпак?
Как фронтенд-разработчики, мы должны быть знакомы сmoduleконцепция. вы, возможно, слышалимодуль AMD,UMD,Common JSа такжемодуль ЕС.
webpack — это модуль связывания, который имеет более широкое определение модуля, которое для веб-пакета:
- Common JS modules
- AMD modules
- CSS import
- Images url
- ES modules
webpack также может получить из этих модулейзависимости.
Конечная цель webpack — объединить все эти разрозненные типы исходников и модулей., тем самым импортируя все в код JavaScript и создавая наиболее работоспособный код.
entry
Webpack**entry(точка входа)** — это отправная точка для сбора всех зависимостей внешнего проекта. На самом деле это простой файл JavaScript.
Эти зависимости образуютграфик зависимости.
Точка входа по умолчанию для Webpack (начиная с версии 4):src/index.js
, это настраивается. webpack может иметь несколько точек входа.
Output
outputэто место, куда помещаются сгенерированные файлы JavaScript и статические файлы.
Loaders
Loaders— это стороннее расширение, которое помогает веб-пакету обрабатывать различные расширения файлов. Например, CSS, изображения или текстовые файлы.
LoadersЦель состоит в том, чтобы преобразовать файлы модулей (файлы, кроме JavaScript). После того, как файл стал модулем, WebPack можно использовать в качестве зависимостей в проекте.
Plugins
Плагины — это сторонние расширения, которые изменяют способ работы веб-пакета. Например, есть плагины для извлечения HTML, CSS или установки переменных среды.
Mode
webpack имеет два режима работы:开发(development)
а также生产(production)
. Основное различие между ними заключается в том, что рабочий режим автоматически генерирует некоторый оптимизированный код.
Code splitting
разделение кодаилиленивая загрузка— это метод оптимизации, позволяющий избежать создания пакетов большего размера.
С помощью разделения кода разработчики могут решить загружать целые блоки JavaScript только в ответ на определенные действия пользователя, такие как клики или изменения маршрута (или другие условия).
Разделенный фрагмент кода называетсяchunk.
Начало работы с вебпаком
Когда вы начнете использовать webpack, сначала создайте новую папку, затем зайдите в этот файл и инициализируйте проект NPM следующим образом:
mkdir webpack-tutorial && cd $_
npm init -y
Затем установитеwebpack,webpack-cliа такжеwebpack-dev-server:
npm i webpack webpack-cli webpack-dev-server --save-dev
Чтобы запустить веб-пакет, просто запуститеpackage.json
Настройте следующую команду:
"scripts": {
"dev": "webpack --mode development"
},
С помощью этого сценария мы указываем веб-пакету работать в режиме разработки, что упрощает работу локально.
Первые шаги с Webpack
Запустите webpack в режиме разработки:
npm run dev
После запуска вы увидите следующую ошибку:
ERROR in Entry module not found: Error: Can't resolve './src'
webpack ищет здесь точку входа по умолчаниюsrc/index.js
, поэтому нам нужно создать его вручную и ввести некоторый контент:
mkdir src
echo 'console.log("Hello webpack!")' > src/index.js
теперь беги сноваnpm run dev
, ошибка ушла. Результат прогона даетdist/
, который содержит новую папку с именемmain.js
JS-файл:
dist
└── main.js
Это наш первый пакет веб-пакетов, также известный какoutput
.
Настроить веб-пакет
Для простых задач вебпак будет работать без настройки, но вскоре мы столкнемся с проблемами, когда некоторые файлы невозможно запаковать без указанного загрузчика. Поэтому нам нужно настроить вебпак, а конфигурация для вебпака находится вwebpack.config.js
поэтому нам нужно создать этот файл:
touch webpack.config.js
Webpack написан на JavaScript и работает в безголовой среде JS, такой как Node.js. В этом файле хотя бы одинmodule.exports
, вот как Common JS экспортирует:
module.exports = {
//
};
существуетwebpack.config.js
, мы можем изменить поведение веб-пакета, добавив или изменив
- entry point
- output
- loaders
- plugins
- code splitting
Например, чтобы изменить путь входа, мы можем сделать
const path = require("path");
module.exports = {
entry: { index: path.resolve(__dirname, "source", "index.js") }
};
Теперь веб-пакет будетsource/index.js
Найдите первый файл для загрузки. Чтобы изменить выходной путь пакета, мы можем сделать это:
const path = require("path");
module.exports = {
output: {
path: path.resolve(__dirname, "build")
}
}
Таким образом, webpack поместит окончательный сгенерированный пакет вbuild
вместоdist
(Для простоты в этой статье мы используем конфигурацию по умолчанию).
Упаковка HTML
Веб-приложение без HTML-страниц практически бесполезно. быть вwebpack
чтобы использовать HTML, нам нужно установить плагинhtml-webpack-plugin
:
npm i html-webpack-plugin --save-dev
После того, как плагин установлен, мы можем настроить его:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
};
Смысл здесь в том, чтобы позволить webpack, изsrc/index.html
Загрузите HTML-шаблон.
html-webpack-plugin
Есть две конечные цели:
-
загрузить html-файл
-
Так и будет
bundle
вставить в тот же файл
Далее нам нужноsrc/index.html
Создайте простой файл HTML в:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack tutorial</title>
</head>
<body>
</body>
</html>
Позже мы запустим эту программу.
webpack development server
В первой части этой статьи мы установилиwebpack-dev-server
. Если вы забыли установить его, вы можете установить его сейчас, выполнив следующую команду:
npm i webpack-dev-server --save-dev
webpack-dev-server
Это может сделать разработку более удобной и вручную обновить файл, не изменяя его. После завершения настройки мы можем запустить локальный сервер для обслуживания файлов.
Чтобы настроитьwebpack-dev-server
, откройте package.json и добавьте "start
" Заказ:
"scripts": {
"dev": "webpack --mode development",
"start": "webpack-dev-server --mode development --open",
},
Имея в руках команду запуска, давайте запустим:
npm start
После запуска должен открыться браузер по умолчанию. В консоли вашего браузера вы также должны увидетьscript
лейбл, введение нашеmain.js
.
Используйте загрузчик веб-пакетов
Loader
это стороннее расширение, которое помогаетwebpack
Обрабатывает различные расширения файлов. Например, есть загрузчики для CSS, изображений или текстовых файлов.
Вот некоторые сведения о конфигурации загрузчика:
module.exports = {
module: {
rules: [
{
test: /\.filename$/,
use: ["loader-b", "loader-a"]
}
]
},
//
};
соответствующая конфигурация дляmodule
ключевое слово начинается. существуетmodule
внутри мыrules
Настройте каждую группу загрузчиков или отдельный загрузчик внутри.
Для каждого файла, который мы хотим обработать как модуль, мы используемtest
а такжеuse
настроить объект
{
test: /\.filename$/,
use: ["loader-b", "loader-a"]
}
test
Скажите веб-пакету: «Эй, считай это имя файла модулем».use
Определяет, какие загрузчики применяются к упакованным файлам.
CSS для упаковки
Чтобы связать CSS в webpack, нам нужно установить как минимум дваloader
. Загрузчик, помогающий веб-пакету понять, как обращаться с.css
Документация необходима.
Чтобы протестировать CSS в webpack, нам нужноsrc
создать следующийstyle.css
документ:
h1 {
color: orange;
}
Также вsrc/index.html
Добавить кh1
Этикетка
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack tutorial</title>
</head>
<body>
<h1>Hello webpack!</h1>
</body>
</html>
Наконец, вsrc/index.js
Загрузите CSS в:
Перед тестированием нам нужно установить два загрузчика:
-
css-loader: Разобрать URL-адрес в коде CSS,
@import
синтаксис какimport
а такжеrequire
Точно так же поступают с модулями, представленными в css -
style-loader: помогите нам напрямую
css-loader
Разобранный контент монтируется на html-странице
Устанавливаем загрузчик:
npm i css-loader style-loader --save-dev
затем вwebpack.config.js
настроить их в
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
};
Теперь, если вы запуститеnpm start
, вы увидите, что таблица стилей загружается в начале HTML:
Когда загрузчик CSS установлен, мы также можем использоватьMiniCssExtractPluginИзвлечь файлы CSS
Порядок загрузчика Webpack имеет значение!
В вебпаке,Loader
Порядок, в котором они появляются в конфигурации, важен. Следующая конфигурация недействительна:
//
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ["css-loader", "style-loader"]
}
]
},
//
};
Здесь, "style-loader
"Появляться в "css-loader
"раньше. Ноstyle-loader
Используется для внедрения стилей на страницу, а не для загрузки фактического файла CSS.
Вместо этого работает следующая конфигурация:
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
//
};
загрузчики webpack выполняются справа налево.
пакет
Для тестирования в веб-пакетеsass
, нам снова нужноsrc
создать каталогstyle.scss
документ:
@import url("https://fonts.googleapis.com/css?family=Karla:weight@400;700&display=swap");
$font: "Karla", sans-serif;
$primary-color: #3e6f9e;
body {
font-family: $font;
color: $primary-color;
}
Кроме того, вsrc/index.html
Добавьте некоторые элементы Dom:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack tutorial</title>
</head>
<body>
<h1>Hello webpack!</h1>
<p>Hello sass!</p>
</body>
</html>
Наконец, загрузите файл sass вsrc/index.js
середина:
import "./style.scss";
console.log("Hello webpack!");
Перед тестированием нам нужно установить несколько загрузчиков:
-
sass-loader: загрузить файлы SASS/SCSS и скомпилировать их в CSS.
-
css-loader: Разобрать URL-адрес в коде CSS,
@import
синтаксис какimport
а такжеrequire
Точно так же поступают с модулями, представленными в css -
style-loader: помогите нам напрямую
css-loader
Разобранный контент монтируется на html-странице
Устанавливаем загрузчик:
npm i css-loader style-loader sass-loader sass --save-dev
затем вwebpack.config.js
настроить их в:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
};
Уведомлениеloader
порядок появления: первыйsass-loader
,Послеcss-loader
,Ну наконец тоstyle-loader
.
Теперь бегиnpm start
, вы должны увидеть таблицу стилей, загруженную в заголовок HTML:
Упаковка современного JavaScript
сам webpack не знает, как преобразовывать код JavaScript.Эта задача отдана на аутсорсингbabel
сторонние загрузчики, особенноbabel-loader.
babelявляется компилятором JavaScript и «компилятором». babel может конвертировать современный JS (es6, es7...) в совместимый код, который может работать (почти) в любом браузере.
Опять же, чтобы использовать его, нам нужно установить несколько загрузчиков:
-
babel-core: Анализировать код js в ast, что удобно каждому плагину для анализа синтаксиса соответствующей обработки
-
babel-preset-env: Скомпилируйте современный JS в ES5.
-
**babel-loader**: для веб-пакета
импортировать зависимости
npm i @babel/core babel-loader @babel/preset-env --save-dev
Далее создайте новый файлbabel.config.json
настроитьbabel
, содержание следующее:
{
"presets": [
"@babel/preset-env"
]
}
Наконец, настройте веб-пакет:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
};
Чтобы проверить преобразование, вы можетеsrc/index.js
Напишите современный синтаксис в:
import "./style.scss";
console.log("Hello webpack!");
const fancyFunc = () => {
return [1, 2];
};
const [a, b] = fancyFunc();
Доставка сейчас行npm run dev
смотретьdist
Преобразованный код в . Открытьdist/main.js
и ищите "fancyFunc
":
\n\nvar fancyFunc = function fancyFunc() {\n return [1, 2];\n};\n\nvar _fancyFunc = fancyFunc(),\n _fancyFunc2 = _slicedToArray(_fancyFunc, 2),\n a = _fancyFunc2[0],\n b = _fancyFunc2[1];\n\n//# sourceURL=webpack:///./src/index.js?"
Без Babel код не будет транспилирован:
\n\nconsole.log(\"Hello webpack!\");\n\nconst fancyFunc = () => {\n return [1, 2];\n};\n\nconst [a, b] = fancyFunc();\n\n\n//# sourceURL=webpack:///./src/index.js?");
**Примечание:** webpack отлично работает даже без babel. Процесс транскодирования требуется только при выполнении кода ES5.
Использование модулей JS с Webpack
webpack рассматривает весь файл как модуль. Однако не забывайте о его основном назначении:Загрузить модуль ES.
Модули ECMAScript (сокращенно ES-модули) — это механизм повторного использования кода JavaScript, который был запущен в 2015 году и с момента запуска полюбился фронтенд-разработчикам. В 2015 году в JavaScript не было стандартного механизма повторного использования кода. За прошедшие годы было предпринято много попыток спецификации этого, что привело к множеству способов модульности.
Возможно, вы слышали о модулях AMD, UMD или CommonJS, ни один из которых не лучше и не хуже. Наконец, в ECMAScript 2015 появились модули ES.
Теперь у нас есть «официальная» модульная система.
Чтобы использовать модуль ES с веб-пакетом, сначала создайтеsrc/common/usersAPI.js
документ:
const ENDPOINT = "https://jsonplaceholder.typicode.com/users/";
export function getUsers() {
return fetch(ENDPOINT)
.then(response => {
if (!response.ok) throw Error(response.statusText);
return response.json();
})
.then(json => json);
}
существуетsrc/index.js
, импортируйте указанный выше модуль:
import { getUsers } from "./common/usersAPI";
import "./style.scss";
console.log("Hello webpack!");
getUsers().then(json => console.log(json));
методы производства
Как упоминалось ранее, у webpack есть два режима работы:Разработка и (производство). Пока мы работаем только в режиме разработки.
В режиме разработки, чтобы облегчить отладку кода и помочь нам быстро найти ошибки, запутанный исходный код не будет сжат. Вместо этого впроизводственный режимПод капотом webpack делает ряд оптимизаций:
- использовать
TerserWebpackPlugin
Минимизировать, чтобы уменьшить размер пакета - использовать
ModuleConcatenationPlugin
поднимите объем
Чтобы настроить веб-пакет в рабочем режиме, включитеpackage.json
и добавьте команду «строить»:
беги сейчасnpm run build
, webpack создаст мини-пакет.
Code splitting
**Разделение кода** относится к методам оптимизации для:
- Избегайте большого пакета
- Избегайте дублирующих зависимостей
Сообщество веб-пакетов имеет ограничение на максимальный размер исходного пакета приложения с учетом:200KB
.
Есть три основных способа активировать разделение кода в webpack:
-
иметь несколько точек входа
-
использовать
optimization.splitChunks
Опции -
динамический импорт
Первая техника, основанная на нескольких точках входа, работает для более мелких проектов, но в долгосрочной перспективе не масштабируется. Здесь мы сосредоточены только на втором и третьего способах.
Разделение кода и оптимизация.splitChunks
Рассмотрим использованиеMoment.jsJS-приложение,Moment.js
— популярная JS-библиотека времени и даты.
Устанавливаем библиотеку в папку проекта:
npm i moment
Сейчас ясноsrc/index.js
и импортируйте библиотеку моментов:
import moment from "moment";
бегатьnpm run build
и посмотрите на вывод элемента управления:
main.js 350 KiB 0 [emitted] [big] main
весьmoment
Библиотеки обязаныmain.js
Это не хорошо. с помощьюoptimization.splitChunks
, мы можем перейти из основного пакетаmoment.js
.
Чтобы использовать его, вам нужноwebpack.config.js
Добавить кoptimization
Опции:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
module: {
// ...
},
optimization: {
splitChunks: { chunks: "all" }
},
// ...
};
бегатьnpm run build
и проверьте текущий результат:
main.js 5.05 KiB 0 [emitted] main
vendors~main.js 346 KiB 1 [emitted] [big] vendors~main
Теперь у нас есть moment.js сvendors〜main.js
, в то время как основная точка входа имеет более разумный размер.
Примечание. Даже при разделении кодаmoment.js
Все еще громоздкая библиотека. Есть лучшие варианты, такие как использованиеluxon
илиdate-fns
.
## Разделение кода и динамический импорт
Более мощный метод разделения кода для использованиядинамический импортдля условной загрузки кода. До того, как эта функция была доступна в ECMAScript 2020, веб-пакет обеспечивал динамический импорт.
Этот подход широко используется в современных интерфейсных библиотеках, таких как Vue и React (у React есть свой путь, но концепция та же).
Разделение кода можно использовать для:
- уровень модуля
- уровень маршрутизации
Например, вы можете условно загружать некоторые модули JavaScript в ответ на действия пользователя (например, клики или движения мыши). Кроме того, вы можетемаршрут ответаЗагрузите соответствующую часть кода при изменении.
Чтобы использовать динамический импорт, мы сначала очищаемsrc/index.html
, и напишите следующее:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dynamic imports</title>
</head>
<body>
<button id="btn">Load!</button>
</body>
</html>
существуетsrc/common/usersAPI.js
середина:
const ENDPOINT = "https://jsonplaceholder.typicode.com/users/";
export function getUsers() {
return fetch(ENDPOINT)
.then(response => {
if (!response.ok) throw Error(response.statusText);
return response.json();
})
.then(json => json);
}
существуетsrc/index.js
середина
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
//
});
Если отправлено行npm run start
Смотришь и нажимаешь кнопки в интерфейсе и ничего не происходит.
Теперь представьте, что мы хотим загрузить список пользователей после того, как кто-то нажмет кнопку. "Родные" методы могут использовать статический импорт изsrc/common /usersAPI.js
Функция нагрузки:
import { getUsers } from "./common/usersAPI";
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
getUsers().then(json => console.log(json));
});
Проблема в том, что модули ES являются статическими, что означает, что мы не можем изменить то, что импортируется во время выполнения.
С динамическим импортом мы можем выбирать, когда загружать код
const getUserModule = () => import("./common/usersAPI");
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
getUserModule().then(({ getUsers }) => {
getUsers().then(json => console.log(json));
});
});
Здесь мы создаем функцию для динамической загрузки модуля
const getUserModule = () => import("./common/usersAPI");
Теперь, когда вы впервые используетеnpm run start
Когда вы загрузите страницу, вы увидите загруженный пакет js в консоли:
Теперь он загружается только при нажатии кнопки/common/usersAPI
:
Соответствующий фрагмент0.js
Добавляя к пути импорта магический комментарий/ * webpackChunkName:“ name_here” * /
, вы можете изменить имя блока:
const getUserModule = () =>
import(/* webpackChunkName: "usersAPI" */ "./common/usersAPI");
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
getUserModule().then(({ getUsers }) => {
getUsers().then(json => console.log(json));
});
});
таланты【Три последовательных】Это самая большая мотивация для Сяочжи продолжать делиться. Если в этом блоге есть какие-либо ошибки и предложения, вы можете оставить сообщение. Наконец, спасибо за просмотр.
Ошибки, которые могут существовать после развертывания кода, не могут быть известны в режиме реального времени.Чтобы решить эти ошибки впоследствии, много времени тратится на отладку журнала.Кстати, я рекомендую всем полезный инструмент мониторинга ошибок.Fundebug.
оригинал:woohoo.site point.com/Web pack-beg…