- PVSM.RU - https://www.pvsm.ru -
Привет!
У webpack'а есть много полезных плагинов, о которых многие не знают и не используют в своих проектах. Под катом я собрал 5 таких, они могут здорово упростить вам жизнь!
В больших фронтенд-проектах всегда много модулей, в которых легко потеряться. Если не проверять проект на неиспользуемые модули, то рано или поздно в нем скопятся мусорные файлы, которые нигде не используются.
Чтобы знать о неиспользуемых файлах в проекте, добавьте в свой конфиг unused-files-webpack-plugin:
npm i unused-files-webpack-plugin
/* webpack.config.js */
const { UnusedFilesWebpackPlugin } = require('unused-files-webpack-plugin');
module.exports = {
/* ... */
plugins: [
/* ... */
new UnusedFilesWebpackPlugin(),
],
};
После установки вы будете получать предупреждения о любых неиспользуемых файлах:
src/
├── index.js
└── someFile.js (не используется)
WARNING in
UnusedFilesWebpackPlugin found some unused files:
src/someFile.js
Ссылки:
Во время разработки на OSX часто можно перепутать строчные и заглавные буквы в пути при импорте модуля. На маке сборка соберется, но на других чувствительных к регистру системах она упадет.
Если хотите избавиться от этой проблемы, нужно поставить case-sensitive-paths-webpack-plugin:
npm i case-sensitive-paths-webpack-plugin
/* webpack.config.js */
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
module.exports = {
/* ... */
plugins: [
/* ... */
new CaseSensitivePathsPlugin(),
],
};
Теперь при импортировании модуля с неправильным регистром вы всегда будете получать ошибку:
/* index.js */
import someFile from './SOMEFILE';
/* someFile.js */
export default () => {
console.log('Hello!');
};
ERROR in index.js
Module not found: Error: [CaseSensitivePathsPlugin] `SOMEFILE.js` does not match the corresponding path on disk `someFile.js`.
Эту проблему так же можно решить с помощью eslint-плагина import/no-unresolved [3].
В typescript есть похожая по работе опция — forceConsistentCasingInFileNames. Но ведет она себя немного иначе: она проверяет, что импортирование модуля из разных мест не отличается по регистру, сама правильность регистра не проверяется.
Ссылки:
В вашем проекте может возникнуть ситуация, что вы и ваши пакеты используют разные версии одной и той же библиотеки. Тогда в бандле появится несколько копий пакета, что легко можно поправить, указав одинаковые версии.
Inspectpack поможет сразу найти такую ситуацию:
npm i inspectpack
/* webpack.config.js */
const { DuplicatesPlugin } = require('inspectpack/plugin');
module.exports = {
/* ... */
plugins: [
/* ... */
new DuplicatesPlugin(),
],
};
Если вы установите плагин, то при появлении копий пакета будет выскакивать предупреждение:
/* package.json */
{
/* ... */
"name": "my-app",
"dependencies": {
"lodash": "4.1.0",
"one": "1.2.3"
}
}
/* node_modules/one/package.json */
{
/* ... */
"name": "one",
"dependencies": {
"lodash": "3.0.0"
}
}
/* index.js */
import _ from 'lodash';
import 'one';
/* ... */
WARNING in Duplicate Sources / Packages - Duplicates found! ️
* Duplicates: Found 2 similar files across 2 code sources (both identical + similar)
accounting for 703 bundled bytes.
* Packages: Found 1 packages with 2 resolved, 2 installed, and 2 depended versions.
## bundle.js
lodash (Found 2 resolved, 2 installed, 2 depended. Latest 4.1.0.)
3.0.0 ~/one/~/lodash
scenario-new-webpack-new-npm-unflattened@* -> one@1.2.3 -> lodash@3.0.0
4.1.0 ~/lodash
scenario-new-webpack-new-npm-unflattened@* -> lodash@4.1.0
В одном из проектов по ошибке в dependencies был объявлен tslib@1.9.0, из-за чего tslib одной версии устанавливался локально для каждого пакета. Пакеты sentry выглядели вот так:
Бордовым выделены копии tslib
Parsed size: 121.03 KB
Gzipped size: 27.16 KB
Благодаря inspectpack проблема нашлась: я удалил из dependencies в package.json tslib@1.9.0, зависимость tslib@^1.9.3 от sentry установилась один раз на верхнем уровне, и пакеты стали весить меньше на 26 КБайт:
Parsed size: 94.5 KB
Gzipped size: 26.5 KB
Аналогичный функционал предоставляет duplicate-package-checker-webpack-plugin [8]. Но с ним есть одна проблема — он не показывает [9] несколько вхождений одной версии библиотеки, т.е. проблему в примере под спойдером, где несколько одинаковых версий tslib, он найти не сможет.
Ссылки:
При разработке иногда возникают проблемы с разрешением зависимостей — два модуля импортируют друг-друга и получается круговая зависимость. Такое может происходить неявно, через цепочку других модулей. В редких случаях циклические зависимости — это нормально, но скорее всего это говорит о том, что в архитектуре проекта есть проблема.
Чтобы сразу увидеть круговую зависимость и убрать ее, добавьте circular-dependency-plugin:
npm i circular-dependency-plugin
/* webpack.config.js */
const CircularDependencyPlugin = require('circular-dependency-plugin');
module.exports = {
/* ... */
plugins: [
/* ... */
new CircularDependencyPlugin(),
],
};
Теперь при появлении циклической зависимости вы получите предупреждение:
/* first.js */
import second from './second'
/* ... */
/* second.js */
import first from './first'
/* ... */
WARNING in Circular dependency detected:
first.js -> second.js -> first.js
WARNING in Circular dependency detected:
second.js -> first.js -> second.js
Похожую проблему решают правила import/no-cycle [12] для eslint и tslint-no-circular-imports [13] для tslint. У последнего, правда, нет возможности игнорировать импорты типов, интерфейсов и классов, которые используются только для типизации — придется часто писать tslint:disable.
Ссылки:
В больших проектах, состоящих из нескольких сотен файлов, сборка может занимать до нескольких минут.
Замерить каждый шаг сборки и найти проблемы поможет speed-measure-webpack-plugin:
npm i speed-measure-webpack-plugin
/* webpack.config.js */
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({
/* ... */
});
В выводе сборки добавится информация об общем времени сборки, времени выполнения каждого плагина и каждой цепочки лоадеров:
SMP
General output time took 48.97 secs
SMP - Plugins
TerserPlugin took 19.6 secs
OptimizeCssAssetsWebpackPlugin took 2.65 secs
MiniCssExtractPlugin took 0.261 secs
VueLoaderPlugin took 0.216 secs
/* ... */
SMP - Loaders
mini-css-extract-plugin, and
css-loader, and
postcss-loader took 21.81 secs
module count = 33
cache-loader, and
babel-loader, and
ts-loader, and
tslint-loader took 21.63 secs
module count = 240
/* ... */
Мне он помог найти проблему со скоростью минификации у TerserPlugin: я убрал несколько настроек, которые почти не влияли на размер итоговых файлов, и ускорил его на пару-тройку секунд.
Ссылки:
Автор: Андрей Аникин
Источник [18]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/326398
Ссылки в тексте:
[1] Github: https://github.com/tomchentw/unused-files-webpack-plugin
[2] NPM: https://www.npmjs.com/package/unused-files-webpack-plugin
[3] import/no-unresolved: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md
[4] Github: https://github.com/Urthen/case-sensitive-paths-webpack-plugin
[5] NPM: https://www.npmjs.com/package/case-sensitive-paths-webpack-plugin
[6] sentry: https://sentry.io/
[7] javascript SDK: https://github.com/getsentry/sentry-javascript
[8] duplicate-package-checker-webpack-plugin: https://github.com/darrenscerri/duplicate-package-checker-webpack-plugin
[9] не показывает: https://github.com/darrenscerri/duplicate-package-checker-webpack-plugin/issues/19
[10] Github: https://github.com/FormidableLabs/inspectpack
[11] NPM: https://www.npmjs.com/package/inspectpack
[12] import/no-cycle: https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-cycle.md
[13] tslint-no-circular-imports: https://www.npmjs.com/package/tslint-no-circular-imports
[14] Github: https://github.com/aackerman/circular-dependency-plugin
[15] NPM: https://www.npmjs.com/package/circular-dependency-plugin
[16] Github: https://github.com/stephencookdev/speed-measure-webpack-plugin
[17] NPM: https://www.npmjs.com/package/speed-measure-webpack-plugin
[18] Источник: https://habr.com/ru/post/461105/?utm_source=habrahabr&utm_medium=rss&utm_campaign=461105
Нажмите здесь для печати.