Широкое морепользование, небо высоко птицы летать. Эй привет! Я помощник Цинь. 😄
В статье представлена базовая конфигурация WebPack ввода (Портал 🚀🚀🚀). Теперь поговорим о том, как повысить производительность сборки нашего проекта за счет оптимизации элементов конфигурации.
Что следует оптимизировать?
С практической точки зрения проекта нас больше волнует развитие проекта до запуска. Таким образом, элементы оптимизации можно рассматривать в следующих измерениях:
- среда разработки
- Оптимизировать производительность выполнения кода
- Оптимизация отладки кода
- Оптимизация производственной среды
- Оптимизируйте упаковку кода и скорость сборки
- Оптимизировать производительность выполнения кода
Оптимизировать производительность выполнения кода (среда разработки)
сервер разработки devServer
В среде разработки код в основном предназначен для удобной работы и облегчения нашей разработки и отладки, поэтому нам нужно использоватьdevServer
чтобы запустить локальную службу, пусть кодrun
Встаньте.
devServer
Используется для автоматизации проекта (автоматическая компиляция, автоматическое открытие браузера, автоматическое обновление браузера и т. д.). Он будет скомпилирован и упакован только в памяти и не будет выводиться наружу.build
Вместо этого пакет существует в памяти и автоматически удаляется при закрытии.
Запустите сервер разработки, devServer должен загрузить пакет
npm i -D webpack-dev-server
Напишите основные элементы конфигурации сервера
devServer: {
// 项目构建后路径
contentBase: resolve(__dirname, 'dist'),
// 端口号
port: 3000,
// 自动打开浏览器
open: true,
},
После завершения настройки можно запускать проект.webpack
Является ли установка размерности проекта, поэтому используйтеnpx
бегать
npx webpack 会输出打包结果在dist文件夹
npx webpack-dev-server 只会在内存中编译打包,没有输出
HMR (горячая замена модуля)
HMR: горячая замена модуля Горячая замена модуля / горячая замена модуля, своевременно реагирует на страницу при изменении файла датчика и освобождает F5 для обновления вручную.
Просто установите для параметра hot значение true в devServer, функция HMR будет автоматически включена.
devServer: {
// 开启HMR功能
hot: true
}
Файлы поддержки HMR:
-
Файлы стилей: можно использовать функции HMR,
style-loader
Внутри функция горячей замены модуля реализована по умолчанию. -
js: функция HMR не может использоваться по умолчанию
Изменение модуля js приведет к обновлению всех модулей js, что, очевидно, приведет к неэффективной горячей замене. нам нужно изменитьвходной файл jsкод, который вносит изменения в модуль, перестраивает только один модуль, а не все.
// print.js 为入口js之外的js
if (module.hot) {
// 一旦 module.hot 为true,说明开启了HMR功能。 --> 让HMR功能代码生效
module.hot.accept('./print.js', function() {
// 方法会监听 print.js 文件的变化,一旦发生变化,只有这个模块会重新打包构建,其他模块不会。
// 会执行后面的回调函数
print();
});
}
- html: функция HMR не может использоваться по умолчанию
Примечание: используйтеHMR
Это приведет к тому, что файл html не будет заменяться в горячем режиме и может быть измененentry
запись, импортируйте файл html
entry: ['./src/index.js', './src/index.html']
Оптимизированная отладка кода (среда разработки)
Извлечь css в отдельный файл
из-заcss-loader
Интеграция файлов css в файлы js вызовет следующие эффекты:
1: Размер файла js будет очень большим
2: вам нужно сначала загрузить js, а затем динамически создать тег стиля, скорость рендеринга стиля низкая.
Решение: использоватьMiniCssExtractPlugin.loader
заменятьstyle-loader
, извлечь css в js в отдельный файл
нужно представитьmini-css-extract-plugin
npm i -D mini-css-extract-plugin
// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
{
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
},
],
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/main.css'
}),
]
}
css обработка совместимости
В разработке, когда мы пишем некоторые продвинутые стили, которые не поддерживаются в старших браузерах, нам нужно представить некоторыеloader
Приходите помочь нам решить эту проблему.
нужно представитьpostcss-loader
postcss-preset-env
npm i -D postcss-loader postcss-preset-env
// webpack.config.js
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')(),
],
},
},
После импорта загрузчика необходимоpackage.json
определено вbrowserslist
// package.json
"browserslist": {
// 开发环境
"development": [ // 这里可根据具体业务场景,匹配不同浏览器
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
// 生产环境
"production": [ // 满足绝大多数浏览器的兼容
">0.2%",
"not dead",
"not op_mini all"
]
},
js обработка совместимости
Чтобы быть совместимым с браузерами предыдущего поколения, js также должен быть совместим.
нужно представитьbabel-loader
@babel/preset-env
core-js
@babel/core
{
test: /\.js$/,
exclude: /node_modules/,
use:[
{
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
//按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs:{
version: 3
},
// 指定兼容到什么版本的浏览器
targets:{
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
],
cacheDirectory:true
}
}
],
},
source-map
source-map
: метод, который обеспечивает сопоставление исходного кода с кодом после сборки (если код после сборки идет не так, ошибки исходного кода можно отследить с помощью сопоставления).
параметр:[inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map
devtool: 'eval-source-map'
Перечисленные выше параметры можно комбинировать произвольно, и каждая комбинация различна. Существует 7 распространенных комбинаций.
С таким количеством режимов, какая комбинация более разумна?
В итоге два лучших решения
1: eval-source-map (высокая целостность, высокая скорость)
2: eval-cheap-module-souce-map (подсказка об ошибке игнорирует столбцы, но содержит другую информацию, быстро)
Настроить проверку стиля кода eslint
Разработка команды, спецификации естественным образом важно. Личноeslint
Это слишком строго, и рекомендуется, чтобы команда написала подходящий наборeslint
правило.
Здесь представлен набор стилей js, популярных в настоящее время.airbnb
Портал 🚀🚀🚀
нужно представитьeslint-loader
eslint
// webpack.config.js
{
test: /\.js$/,
exclude: /node_modules/, // 忽略node_modules
loader: 'eslint-loader',
options: {
fix: true, // 自动修复
},
}
После введения загрузчика также необходимоpackage.json
изeslintConfig
напишите конфигурацию в
// package.json
"eslintConfig": {
"extends": "airbnb-base", // 继承airbnb的风格规范
"env": {
"browser": true // 可以使用浏览器中的全局变量(使用window不会报错)
}
}
Оптимизация упаковки кода и скорости сборки (производственная среда)
oneOf
oneOf
: соответствуетloader
После этого обратное сопоставление не выполняется, а скорость упаковки и сборки рабочей среды оптимизируется.
вавилонский кеш
babel 缓存
:Будуbabel
Обработанные ресурсы кэшируются, так что во время второй упаковки и сборки обновляется только измененный контент, а другой неизмененный контент кэшируется. тем самым увеличивая скорость сборки
// 开启babel缓存
cacheDirectory:true
Здесь есть проблема: когда имя файла не изменилось, все файлы с таким именем кэшируются. Это приведет к тому, что измененное содержимое будет несовместимо с фактически отображаемым содержимым.
Обходной путь: используйтеhash
Имя, изменив имя файла, чтобы определить, какие файлы необходимо обновить.
Хэш-значение можно разделить на (hash
,chunkhash
,contenthash
)contenthash
более разумный
hash:каждый разwepack
При упаковке создается уникальное хеш-значение.
chunkhash:согласно смодульСгенерированоhash
стоимость.隶属于同一个модульизhash
то же значение
contenthash: Генерируется из содержимого файлаhash
значение, может гарантировать разные файлыhash
ценить уникальность
Мультипроцессная упаковка
thread-loader
будет за этимloader
Включить многопроцессную упаковку.
нужно представитьthread-loader
Накладные расходы на запуск загрузчика потоков относительно дороги, и его не рекомендуется использовать для общих проектов.
npm i -D thread-loader
{
loader: 'thread-loader',
options: {
workers: 2 // 开启2个进程
}
},
externals
externals
Пусть некоторые сторонние библиотеки не будут упакованы
externals: {
jquery: 'jQuery'
}
Оптимизация производительности выполнения кода (производственная среда)
Сжатый файл
-
Файл стиля Zip
нужно представить
optimize-css-assets-webpack-plugin
npm i -D optimize-css-assets-webpack-plugin
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') plugins: [ new OptimizeCssAssetsWebpackPlugin(), ]
-
Сжатый HTML
нужно представить
html-webpack-plugin
html-webpack-plugin
Автоматически импортирует отдельно упакованные файлы стилей через тег ссылки.npm i -D html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin') plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', minify: { // 移除空格 collapseWhitespace: true, // 移除注释 removeComments: true } }), ]
-
js код будет автоматически сжат в рабочей среде
качание дерева
Если мы думаем о программе как о дереве, полезный код или сторонняя библиотека, которую мы используем, представляют собой зеленые листья. Эти ненужные коды, бесполезные коды представляют собой увядшие листья. tree shaking
Подобно невидимой большой руке, энергично трясущей дерево, стряхивающей мертвые листья (бесполезные коды).
помещение для тряски деревьев
1: Должен использовать модульность es6
2: Откройте производственную среду
В обоих приведенных выше предварительных условиях веб-пакет автоматически удалил наш мертвый код.
Могуpackage.json
Записывайте элементы конфигурации, управляйтевстряска дереваОбъем
// 不会对css/less文件tree shaking处理
"sideEffects": ["*.css", "*.less"]
разделение кода
webpack
Упакуйте код js и выведите его вbuild.js
Файл внутри, что для больших проектов несомненно фатально.build.js
Файл слишком большой, это приведет к тому, что время загрузки страницы будет слишком большим, просто измените немного кода для загрузки больших файлов, и так весь ряд вопросов.
разделение кодаупакует большой выходbundle.js
Файл разбивается на несколько файлов меньшего размера, чтобы можно было загружать несколько файлов параллельно, что быстрее, чем загрузка одного файла.
Существует три способа реализации разделения кода:
1: мульти-разделенный вход (запись ввода файла с использованием множества входов)
entry: {
index: './src/js/index.js',
test: './src/js/test.js'
},
output: {
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build')
},
2: настроить оптимизацию
optimization: {
splitChunks: {
chunks: 'all'
}
},
3:import
Синтаксис динамического импорта
import('./test').then(({ a, b }) => {
// 文件加载成功~
}).catch(() => {
// 文件加载失败~
});
ленивая загрузка
Отложенная загрузка: загружайте файл, когда его нужно использовать.
Предварительная загрузка: перед использованием загрузите его заранее
доступныйimport
Способ динамического импорта реализует ленивую загрузку и предварительную загрузку.
// 将import的内容放在异步回调函数中使用,需要用到的时候再进行加载
// webpackPrefetch: true表示开启预加载
import(/* webpackChunkName: 'test', webpackPrefetch: true */'./test').then(() => {
...
});
Пока что это об этом для оптимизации WebPack. Резюме здесь не могут быть всеобъемлющими, но для большинства проектов достаточно. Давайте работать вместе, учиться усердно и добиться прогресса каждый день.
Рассыпать цветы, посыпать цветы 🌸🌸🌸🌸🌸🌸🌸🌸
Ставьте 👍 и смотрите снова, уже вошло в привычку! Эта серия постоянно обновляется. Ваша тройная ссылка в один клик - самая большая мотивация для меня продолжать писать. Если у вас есть какие-либо комментарии и предложения по этому блогу, вы можете оставить сообщение! Добро пожаловать, чтобы беспокоить! 😜😝
Я Цинь Эйдэ, программист, который выживает в Интернете!