предисловие
Для игроков начального уровня элементов конфигурации веб-пакета много и они тяжелые, поэтому стоит подумать о том, как быстро настроить веб-пакет, который можно использовать в онлайн-среде. На самом деле, ознакомившись с webpack, вы обнаружите, что это очень просто, базовую настройку можно разделить на следующие аспекты:entry
,output
,mode
,resolve
,module
,optimization
,plugin
,source map
,performance
Подождите, эта статья будет посвящена этим частям.
Прилагается изображение для сравнения нулевой конфигурации веб-пакета, обратите внимание на публичную учетную запись [джентльмен с бутылкой переднего плана] и ответьте [веб-пакет], чтобы получить файл PDF бесплатно.
Сначала настройте запись
1. Однократный и многократный въезд
Добавьте исходные файлы в процесс сборки веб-пакета, который может быть одной записью:
module.exports = {
entry: `./index.js`,
}
имя пакета сборки[name]
дляmain
;
или множественная запись:
module.exports = {
entry: {
"index": `./index.js`,
},
}
key:value
Форма пар ключ-значение:
- ключ: имя пакета сборки, т.е.
[name]
, здесь дляindex
- значение: путь входа
Запись определяет, из какого модуля webapck начинает генерировать граф зависимостей (пакет сборки), и каждый файл записи соответствует графу зависимостей.
2. Файл записи динамической конфигурации
Динамически упаковать все подпроекты
Когда проект сборки содержит несколько подпроектов, каждый раз, когда добавляется подсистема, файл входа должен быть записан в файл конфигурации веб-пакета.Фактически, мы позволяем веб-пакету динамически получать файл входа, например:
// 使用 glob 等工具使用若干通配符,运行时获得 entry 的条目
module.exports = {
entry: glob.sync('./project/**/index.js').reduce((acc, path) => {
const entry = path.replace('/index.js', '')
acc[entry] = path
return acc
}, {}),
}
будет соответствовать всем./project/**/index.js
Файлы упакованы как входные файлы.Если вы хотите добавить подпроект, простоproject
Создайте каталог подпроекта и создайтеindex.js
как входной файл.
Этот метод более подходит для сценариев, где входные файлы не сосредоточены, и много.
Динамически упаковать подпроект
При создании мультисистемного приложения или библиотеки компонентов нам может понадобиться упаковывать только определенный модуль каждый раз, когда мы упаковываем.В это время мы можем запросить печать определенного модуля через командную строку, например:
npm run build --project components
Разобрать аргументы командной строки при упаковке:
// 解析命令行参数
const argv = require('minimist')(process.argv.slice(2))
// 项目
const project = argv['project'] || 'index'
Затем настройте запись:
module.exports = {
entry: {
"index": `./${project}/index.js`,
}
}
эквивалентно:
module.exports = {
entry: {
"index": `./components/index.js`,
}
}
Конечно, вы можете передать другие параметры, которые также можно применять в нескольких местах, напримерresolve.alias
середина.
2. Настройте вывод экспорта
Используется, чтобы сообщить webpack, как создавать скомпилированные файлы, вы можете настроить местоположение и имя выходного файла:
module.exports = {
output: {
// path 必须为绝对路径
// 输出文件路径
path: path.resolve(__dirname, '../../dist/build'),
// 包名称
filename: "[name].bundle.js",
// 或使用函数返回名(不常用)
// filename: (chunkData) => {
// return chunkData.chunk.name === 'main' ? '[name].js': '[name]/[name].js';
// },
// 块名,公共块名(非入口)
chunkFilename: '[name].[chunkhash].bundle.js',
// 打包生成的 index.html 文件里面引用资源的前缀
// 也为发布到线上资源的 URL 前缀
// 使用的是相对路径,默认为 ''
publicPath: '/',
}
}
В режиме разработки webpack4 он запустится по умолчанию.output.pathinfo
, который выводит дополнительную информацию в комментариях, полезную для отладки проекта, особенно при использовании eval devtool.
filename
:[name]
настроен для входаkey
, в дополнение к этому, также может быть[id]
(внутренний идентификатор блока),[hash]
,[contenthash]
Ждать.
1. Кэш браузера и хэш-значение
Для каждого приложения, которое мы разрабатываем, браузер кэширует статические ресурсы.Если мы обновляем статические ресурсы без обновления имени статического ресурса (или пути), браузер может не получить обновленные ресурсы из-за проблем с кэшированием. Когда мы используем webpack для упаковки, webpack предоставляет концепцию хэша, поэтому мы можем использовать хэш для упаковки.
После определения имени пакета (например,chunkFilename
,filename
), мы обычно используем хеш-значения, и в разных сценариях используются разные хеш-значения:
hash
зависит от сборки, хеш-значение соответствует каждой сборке (Compilation
), то есть каждая компиляция отличается, даже если содержимое файла не изменилось, и все ресурсы разделяют это значение хеш-функции, в это время кеш браузера бесполезен,Его можно использовать в среде разработки, но не в производственной среде.
chunkhash
зависит от фрагмента, хеш-значение соответствует каждой точке входа в webpack, и каждая запись имеет свое собственное хэш-значение. Если есть изменение в содержимом файла на графе зависимостей отношений, созданном файлом входа, то соответствующий файл входаchunkhash
изменится,Подходит для производственной среды
contenthash
Content-Specific, в соответствии с хэш-значением, рассчитанным в соответствии с содержимым, если содержимое пакета является постоянным,contenthash
не изменится,Подходит для производственной среды
webpack также позволяет нарезать хэши. если ты напишешь[hash:8]
, то он получает первые 8 бит хеша.
Уведомление:
- Попробуйте использовать хэши в продакшене
- Блоки, загружаемые по требованию, не подлежат
filename
затронутыйchunkFilename
влияние - использовать
hash/chunkhash/contenthash
обычно сотрудничаютhtml-webpack-plugin
(создайте html и свяжите соответствующий файл пакета),clean-webpack-plugin
(чтобы очистить исходный файл пакета) используются вместе.
2. Упакован в виде библиотеки
При использовании webpack для создания библиотеки, на которую могут ссылаться другие модули:
module.exports = {
output: {
// path 必须为绝对路径
// 输出文件路径
path: path.resolve(__dirname, '../../dist/build'),
// 包名称
filename: "[name].bundle.js",
// 块名,公共块名(非入口)
chunkFilename: '[name].[chunkhash].bundle.js',
// 打包生成的 index.html 文件里面引用资源的前缀
// 也为发布到线上资源的 URL 前缀
// 使用的是相对路径,默认为 ''
publicPath: '/',
// 一旦设置后该 bundle 将被处理为 library
library: 'webpackNumbers',
// export 的 library 的规范,有支持 var, this, commonjs,commonjs2,amd,umd
libraryTarget: 'umd',
}
}
Три, режим режима конфигурации (webpack4)
настраиватьmode
, что позволяет веб-пакету автоматически вызывать соответствующие встроенные оптимизации.
module.exports = {
// 可以是 none、development、production
// 默认为 production
mode: 'production'
}
Или настройте его в командной строке:
"build:prod": "webpack --config config/webpack.prod.config.js --mode production"
в обстановкеmode
После этого webpack4 выполнит синхронизацию конфигурацииprocess.env.NODE_ENV
дляdevelopment
илиproduction
.
Наиболее примечательные особенности webpack4:
-
Сокращение времени компиляции
Время упаковки сократилось более чем на 60%
-
Нулевая конфигурация
Мы можем использовать веб-пакет для различных проектов без каких-либо файлов конфигурации.
webpack4 поддерживает нулевую конфигурацию, где нулевая конфигурация означает,mode
так же какentry
(по умолчаниюsrc/index.js
) можно указать через файл ввода, а webpack4 нацелен на разныеmode
Встроенные соответствующие стратегии оптимизации.
1. production
Конфигурация:
// webpack.prod.config.js
module.exports = {
mode: 'production',
}
Эквивалент встроенного по умолчанию:
// webpack.prod.config.js
module.exports = {
performance: {
// 性能设置,文件打包过大时,会报警告
hints: 'warning'
},
output: {
// 打包时,在包中不包含所属模块的信息的注释
pathinfo: false
},
optimization: {
// 不使用可读的模块标识符进行调试
namedModules: false,
// 不使用可读的块标识符进行调试
namedChunks: false,
// 设置 process.env.NODE_ENV 为 production
nodeEnv: 'production',
// 标记块是否是其它块的子集
// 控制加载块的大小(加载较大块时,不加载其子集)
flagIncludedChunks: true,
// 标记模块的加载顺序,使初始包更小
occurrenceOrder: true,
// 启用副作用
sideEffects: true,
// 确定每个模块的使用导出,
// 不会为未使用的导出生成导出
// 最小化的消除死代码
// optimization.usedExports 收集的信息将被其他优化或代码生成所使用
usedExports: true,
// 查找模块图中可以安全的连接到其它模块的片段
concatenateModules: true,
// SplitChunksPlugin 配置项
splitChunks: {
// 默认 webpack4 只会对按需加载的代码做分割
chunks: 'async',
// 表示在压缩前的最小模块大小,默认值是30kb
minSize: 30000,
minRemainingSize: 0,
// 旨在与HTTP/2和长期缓存一起使用
// 它增加了请求数量以实现更好的缓存
// 它还可以用于减小文件大小,以加快重建速度。
maxSize: 0,
// 分割一个模块之前必须共享的最小块数
minChunks: 1,
// 按需加载时的最大并行请求数
maxAsyncRequests: 6,
// 入口的最大并行请求数
maxInitialRequests: 4,
// 界定符
automaticNameDelimiter: '~',
// 块名最大字符数
automaticNameMaxLength: 30,
cacheGroups: { // 缓存组
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
},
// 当打包时,遇到错误编译,将不会把打包文件输出
// 确保 webpack 不会输入任何错误的包
noEmitOnErrors: true,
checkWasmTypes: true,
// 使用 optimization.minimizer || TerserPlugin 来最小化包
minimize: true,
},
plugins: [
// 使用 terser 来优化 JavaScript
new TerserPlugin(/* ... */),
// 定义环境变量
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
// 预编译所有模块到一个闭包中,提升代码在浏览器中的执行速度
new webpack.optimize.ModuleConcatenationPlugin(),
// 在编译出现错误时,使用 NoEmitOnErrorsPlugin 来跳过输出阶段。
// 这样可以确保输出资源不会包含错误
new webpack.NoEmitOnErrorsPlugin()
]
}
2. development
Конфигурация:
// webpack.dev.config.js
module.exports = {
mode: 'development',
}
Эквивалент встроенного по умолчанию:
// webpack.dev.config.js
module.exports = {
devtool: 'eval',
cache: true,
performance: {
// 性能设置,文件打包过大时,不报错和警告,只做提示
hints: false
},
output: {
// 打包时,在包中包含所属模块的信息的注释
pathinfo: true
},
optimization: {
// 使用可读的模块标识符进行调试
namedModules: true,
// 使用可读的块标识符进行调试
namedChunks: true,
// 设置 process.env.NODE_ENV 为 development
nodeEnv: 'development',
// 不标记块是否是其它块的子集
flagIncludedChunks: false,
// 不标记模块的加载顺序
occurrenceOrder: false,
// 不启用副作用
sideEffects: false,
usedExports: false,
concatenateModules: false,
splitChunks: {
hidePathInfo: false,
minSize: 10000,
maxAsyncRequests: Infinity,
maxInitialRequests: Infinity,
},
// 当打包时,遇到错误编译,仍把打包文件输出
noEmitOnErrors: false,
checkWasmTypes: false,
// 不使用 optimization.minimizer || TerserPlugin 来最小化包
minimize: false,
removeAvailableModules: false
},
plugins: [
// 当启用 HMR 时,使用该插件会显示模块的相对路径
// 建议用于开发环境
new webpack.NamedModulesPlugin(),
// webpack 内部维护了一个自增的 id,每个 chunk 都有一个 id。
// 所以当增加 entry 或者其他类型 chunk 的时候,id 就会变化,
// 导致内容没有变化的 chunk 的 id 也发生了变化
// NamedChunksPlugin 将内部 chunk id 映射成一个字符串标识符(模块的相对路径)
// 这样 chunk id 就稳定了下来
new webpack.NamedChunksPlugin(),
// 定义环境变量
new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
]
}
3. none
Никаких опций оптимизации по умолчанию не делается.
Конфигурация:
// webpack.com.config.js
module.exports = {
mode: 'none',
}
Эквивалент встроенного по умолчанию:
// webpack.com.config.js
module.exports = {
performance: {
// 性能设置,文件打包过大时,不报错和警告,只做提示
hints: false
},
optimization: {
// 不标记块是否是其它块的子集
flagIncludedChunks: false,
// 不标记模块的加载顺序
occurrenceOrder: false,
// 不启用副作用
sideEffects: false,
usedExports: false,
concatenateModules: false,
splitChunks: {
hidePathInfo: false,
minSize: 10000,
maxAsyncRequests: Infinity,
maxInitialRequests: Infinity,
},
// 当打包时,遇到错误编译,仍把打包文件输出
noEmitOnErrors: false,
checkWasmTypes: false,
// 不使用 optimization.minimizer || TerserPlugin 来最小化包
minimize: false,
},
plugins: []
}
4. Резюме производства, разработки, нет
Примечание. Обратите внимание на общедоступную учетную запись [Front-end Bottle King] и ответьте на [webpack], чтобы получить исходный pdf-файл бесплатно.Дайте вам лучший пользовательский опыт в производственном режиме:
- Меньший размер выходного пакета
- Более быстрое выполнение кода в браузере
- Игнорировать код в разработке
- Не раскрывайте исходный код или пути к файлам
- Простые в использовании ресурсы вывода
Режим разработки даст вам лучший опыт разработки:
- Инструменты отладки браузера
- Быстрая инкрементная компиляция ускоряет циклы разработки
- Предоставляет полезные сообщения об ошибках во время выполнения
Несмотря на то, что webpack4 делает все возможное с нулевой конфигурацией, все же существуют ограничения, и в большинстве случаев по-прежнему требуется файл конфигурации. Мы можем использовать нулевую конфигурацию в начале проекта и настроить ее позже, когда бизнес усложнится.
5. Переменная окружения process.env.NODE_ENV
Сторонние фреймворки или библиотеки, а также наш бизнес-код будут настроены для разных сред и будут выполнять разные логические коды, такие как:
Мы можем определить переменные среды следующими способами:
Способ 1: режим: «производство» в webpack4 настроено с помощью process.env.NODE_ENV = «производство» по умолчанию, поэтому webapck4 не может быть определен
Хотя определено в webpack4mode
будет автоматически настроенprocess.env.NODE_ENV
, то нам не нужно вручную настраивать переменные окружения?
вообще-то нет,mode
можно определить только какdevelopment
илиproduction
, и в проекте у нас есть не только среда разработки или производства, но во многих случаях нам нужно настроить разные среды (например, тестовую среду), в это время нам нужно вручную настроить другие переменные среды (такие как тестовая среду, нам нужно определитьprocess.env.NODE_ENV
для'test'
), вы можете сделать следующее:
Способ 2: webpack.DefinePlugin
// webpack编译过程中设置全局变量process.env
new webpack.DefinePlugin({
'process.env': require('../config/dev.env.js')
}
config/prod.env.js
:
module.exports ={
// 或 '"production"' ,环境变量的值需要是一个由双引号包裹的字符串
NODE_ENV: JSON.stringify('production')
}
Способ 3: когда команда веб-пакета NODE_ENV=development
Настроить в окнеNODE_ENV=production
Может застрять, поэтому используйте cross-env:
cross-env NODE_ENV=production webpack --config webpack.config.prod.js
Способ 4: Использованиеnew webpack.EnvironmentPlugin(['NODE_ENV'])
EnvironmentPlugin
пропускwebpack.DefinePlugin
устанавливатьprocess.env
Ярлыки для переменных среды.
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
});
Примечание: приведенное выше фактически даетNODE_ENV
Установите значение по умолчанию'production'
, если определено в другом местеprocess.env.NODE_ENV
, значение по умолчанию недопустимо.
В-четвертых, настройте стратегию разрешения
Настройте стратегию поиска зависимых модулей (например,import _ from 'lodash'
):
module.exports = {
resolve: {
// 设置模块导入规则,import/require时会直接在这些目录找文件
// 可以指明存放第三方模块的绝对路径,以减少寻找,
// 默认 node_modules
modules: [path.resolve(`${project}/components`), 'node_modules'],
// import导入时省略后缀
// 注意:尽可能的减少后缀尝试的可能性
extensions: ['.js', '.jsx', '.react.js', '.css', '.json'],
// import导入时别名,减少耗时的递归解析操作
alias: {
'@components': path.resolve(`${project}/components`),
'@style': path.resolve('asset/style'),
},
// 很多第三方库会针对不同的环境提供几份代码
// webpack 会根据 mainFields 的配置去决定优先采用那份代码
// 它会根据 webpack 配置中指定的 target 不同,默认值也会有所不同
mainFields: ['browser', 'module', 'main'],
},
}
В-пятых, настройте модуль стратегии для парсинга и конвертации файлов.
Решите, как обрабатывать различные типы модулей в вашем проекте, обычно путем настройки загрузчиков в module.rules:
module.exports = {
module: {
// 指明 webpack 不去解析某些内容,该方式有助于提升 webpack 的构建性能
noParse: /jquery/,
rules: [
{
// 这里编译 js、jsx
// 注意:如果项目源码中没有 jsx 文件就不要写 /\.jsx?$/,提升正则表达式性能
test: /\.(js|jsx)$/,
// 指定要用什么 loader 及其相关 loader 配置
use: {
loader: "babel-loader",
options: {
// babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启
// 使用 cacheDirectory 选项将 babel-loader 的速度提高2倍
cacheDirectory: true,
// Save disk space when time isn't as important
cacheCompression: true,
compact: true,
}
},
// 排除 node_modules 目录下的文件
// node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换
exclude: /node_modules/
// 也可以配置 include:需要引入的文件
}
]
}
}
1. noParse
Указывает, что WebPack не анализирует определенное содержание, которое может помочь улучшить производительность сборки WebPack.
2. rules
Обычные загрузчики:
-
babel-loader
: разбор.js
а также.jsx
документ// 配置 .babelrc { "presets": [ [ "@babel/preset-env", ], "@babel/preset-react" ], "plugins": [ [ "@babel/plugin-proposal-class-properties", { "loose": true } ], [ "@babel/plugin-transform-runtime", { "absoluteRuntime": false, "corejs": false, "helpers": true, "regenerator": true, "useESModules": false } ], ] }
-
tsx-loader
: Обработать файлы ts -
less-loader
: Обрабатывать меньше файлов и компилировать их в css -
sass-loader
: Обрабатывать файлы sass, scss и компилировать их в css. -
postcss-loader
:// postcss.config.js module.exports = { // 解析CSS文件并且添加浏览器前缀到 CSS 内容里 plugins: [require('autoprefixer')], };
-
css-loader
: обрабатывать css-файлы -
style-loader
: внедрить CSS в DOM -
file-loader
: положить файл наimport
/require
решаетurl
, и выведите файл в выходной каталог -
url-loader
: загрузчик webpack для преобразования файлов в base64 uri -
html-loader
: экспортировать HTML в виде строки, минимизировать HTML, когда компилятор запрашивает это.
Другие загрузчики для просмотраLOADERS.
Шесть, оптимизация оптимизации конфигурации (webpack4)
webapck4 будетmode
Чтобы оптимизировать, вы можете настроить его вручную, он переопределит автоматическую оптимизацию, пожалуйста, обратитесь к подробной настройкеOptimization.
В основном это включает два аспекта оптимизации:
- Свернутый пакет
- Распаковка
1. Минимизируйте пакет
- использовать
optimization.removeAvailableModules
Удалить доступные модули - использовать
optimization.removeEmptyChunks
удалить пустые модули - использовать
optimization.occurrenceOrder
Отметьте порядок загрузки модулей, чтобы уменьшить исходный пакет. - использовать
optimization.providedExports
,optimization.usedExports
,concatenateModules
,optimization.sideEffects
удалить мертвый код - использовать
optimization.splitChunks
Извлечь общедоступные пакеты - использовать
optimization.minimizer
||TerserPlugin
минимизировать пакет
2. Распаковка
Когда пакет слишком велик, если мы обновим небольшую часть контента пакета, весь пакет должен быть перезагружен. Если мы разделим пакет, то нам нужно только перезагрузить пакет, содержание которого изменилось, не все пакеты, эффективно использует кеш.
Сплит Node_Modules.
Во многих случаях нам не нужно вручную разбивать пакет, мы можем использоватьoptimization.splitChunks
:
const path = require('path');
module.exports = {
entry: path.resolve(__dirname, 'src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
},
optimization: {
splitChunks: {
// 对所有的包进行拆分
chunks: 'all',
},
},
};
Нам не нужно разрабатывать стратегию распаковки,chunks: all
будет автоматическиnode_modules
поместите все в файл с именемvendors〜main.js
в файле.
Разделить бизнес-код
module.exports = {
entry: {
main: path.resolve(__dirname, 'src/index.js'),
ProductList: path.resolve(__dirname, 'src/ProductList/ProductList.js'),
ProductPage: path.resolve(__dirname, 'src/ProductPage/ProductPage.js'),
Icon: path.resolve(__dirname, 'src/Icon/Icon.js'),
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash:8].js',
},
};
Применяется многократный метод, когда происходит обновление бизнес-кода, соответствующий пакет может быть обновлен.
Разделить сторонние библиотеки
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: path.resolve(__dirname, 'src/index.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// 获取第三方包名
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// npm 软件包名称是 URL 安全的,但是某些服务器不喜欢@符号
return `npm.${packageName.replace('@', '')}`;
},
},
},
},
},
};
При обновлении стороннего пакета просто обновите соответствующий пакет.
Учтите, что когда пакетов слишком много, браузер будет делать больше запросов, а когда файл слишком мал, это также влияет на сжатие кода.
динамическая нагрузка
Теперь мы должны разделить пакет очень тщательно, но больше, чем просто аспекты оптимизации раздельного кеша браузера, сокращая время загрузки первого экрана, мы также можем использовать фактически загружаемые по требованию для дальнейшего разделения, сворачивания уменьшения времени загрузки:
import React, { useState, useEffect } from 'react';
import './index.scss'
function Main() {
const [NeighborPage, setNeighborPage] = useState(null)
useEffect(() => {
import('../neighbor').then(({ default: component }) => {
setNeighborPage(React.createElement(component))
});
}, [])
return NeighborPage
? NeighborPage
: <div>Loading...</div>;
}
export default Main
Семь, настроить плагин
Настройте плагин для обработки и оптимизации других требований,
module.exports = {
plugins: [
// 优化 require
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en|zh/),
// 用于提升构建速度
createHappyPlugin('happy-babel', [{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', "@babel/preset-react"],
plugins: [
['@babel/plugin-proposal-class-properties', {
loose: true
}]
],
// babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启
cacheDirectory: true,
// Save disk space when time isn't as important
cacheCompression: true,
compact: true,
}
}])
]
}
Общие плагины:
-
html-webpack-plugin
: Создать html-файл и добавить пакет в html -
webpack-parallel-uglify-plugin
: сжать js (многопроцессное сжатие параллельной обработки) -
happypack
: Многопоточный загрузчик для повышения скорости сборки -
hard-source-webpack-plugin
: Обеспечивает промежуточный этап кэширования модулей, значительно повышая скорость упаковки. -
webpack-merge
: объединить конфигурацию веб-пакета -
mini-css-extract-plugin
: извлечь css -
optimize-css-assets-webpack-plugin
: сжать css -
add-asset-html-webpack-plugin
: добавить активы JavaScript или CSS в HTML, сгенерированный плагином html-webpack.
Доступны дополнительные плагины:plugins
Восемь, настройте devtool: исходная карта
Настройте, как webpack генерирует исходные карты, чтобы улучшить процесс отладки. Различные значения могут существенно повлиять на скорость сборки и перестроения:
Рабочая среда: по умолчаниюnull
, вообще не ставить(none
)илиnosources-source-map
Среда разработки: по умолчаниюeval
, обычно устанавливается наeval
,cheap-eval-source-map
,cheap-module-eval-source-map
Стратегия такова:
- Использование дешевого режима может значительно улучшить эффективность генерации SOWREMAP.Информация о столбцах отсутствует (будет отображаться в преобразованном коде, а не в исходном коде), обычно при отладке нам не нужна информация о столбцах, и даже если исходная карта не имеет столбцов, некоторые браузерные движки (например, v8) будут дать информацию о колонке.
- **Использование метода eval может значительно повысить эффективность непрерывных сборок. ** Обратитесь к таблице сравнения скоростей, представленной в официальной документации, чтобы увидеть, что скорость компиляции режима eval очень высока.
- Используйте модули для поддержки babel, инструмента прекомпиляции(Используется как загрузчик в webpack).
Если веб-пакет по умолчаниюminimizer
был переопределен (например,terser-webpack-plugin
), необходимо предоставитьsourceMap:true
возможность включить поддержку исходной карты.
Еще можно посмотреть:devtool
Девять, производительность конфигурации
Когда упаковка является активом и точкой входа, превышающей определенный предел файлов,performance
Контролируйте, как webpack уведомляет:
module.exports = {
// 配置如何显示性能提示
performance: {
// 可选 warning、error、false
// false:性能设置,文件打包过大时,不报错和警告,只做提示
// warning:显示警告,建议用在开发环境
// error:显示错误,建议用在生产环境,防止部署太大的生产包,从而影响网页性能
hints: false
}
}
10. Настройте другое
1. смотреть и смотреть варианты
watch
Следите за обновлениями файлов и перекомпилируйте их при обновлении:
module.export = {
// 启用监听模式
watch: true,
}
существуетwebpack-dev-server
а такжеwebpack-dev-middleware
, режим монитора включен по умолчанию.
Или мы можем начать слушать в командной строке (--watch
):
webpack --watch --config webpack.config.dev.js
watchOptions
module.export = {
watch: true,
// 自定义监视模式
watchOptions: {
// 排除监听
ignored: /node_modules/,
// 监听到变化发生后,延迟 300ms(默认) 再去执行动作,
// 防止文件更新太快导致重新编译频率太高
aggregateTimeout: 300,
// 判断文件是否发生变化是通过不停的去询问系统指定文件有没有变化实现的
// 默认 1000ms 询问一次
poll: 1000
}
}
2. externals
Исключите зависимости при упаковке, не входящие в объем упаковки, например, вы используете проект в своем проектеjquery
, а вы ввели его в html, то при упаковке его повторно не нужно запаковывать:
<script
src="https://code.jquery.com/jquery-3.1.0.js"
integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
crossorigin="anonymous">
</script>
Конфигурация:
module.exports = {
// 打包时排除 jquery 模块
externals: {
jquery: 'jQuery'
}
};
3.target
Создайте цель, чтобы указать среду для веб-пакета:
module.exports = {
// 编译为类浏览器环境里可用(默认)
target: 'web'
};
4. cache
Кэшируйте сгенерированные модули и фрагменты webpack для повышения скорости сборки. В режиме разработки кеш установлен наtype: 'memory'
, отключенный в производственном режиме.cache: true
даcache: {type: 'memory'}
псевдоним.要禁用缓存传递false
:
module.exports = {
cache: false
}
В памяти кеш полезен только в режиме просмотра, и мы предполагаем, что вы используете режим просмотра в процессе разработки. Без кэширования объем памяти меньше.
5. name
Имя конфигурации, используемое для загрузки нескольких конфигураций:
module.exports = {
name: 'admin-app'
};
11. Резюме
В этой статье перечислены только некоторые часто используемые элементы конфигурации, можно увидеть все архитектуры файла конфигурации:WebpackOptions.json, вы также можете перейти на официальный сайт webpack, чтобы узнать больше.
Прошлая серия веб-пакетов
Пять визуальных решений для анализа узких мест производительности упаковки webpack
Принцип снупинга: написание сборщика JavaScript от руки
Хотите увидеть предыдущую серию статей,Нажмите, чтобы перейти на домашнюю страницу блога github.
Ссылаться на:
The 100% correct way to split your chunks with Webpack
webpack 4: mode and optimization
12. Идти до конца
-
❤️ Получайте удовольствие, продолжайте учиться и всегда продолжайте программировать. 👨💻
-
Если у вас есть какие-либо вопросы или уникальные идеи, пожалуйста, прокомментируйте или свяжитесь с бутылкой напрямую (общедоступный номер может ответить на 123)! 👀👇
-
👇Приглашаем обратить внимание: джентльмен с бутылкой переднего плана, обновляется ежедневно! 👇