Введение в вебпак
WebPack на самом деле является статический модульный пакет
Когда webpack обрабатывает проект, он рекурсивно строит граф зависимостей, содержащий каждый модуль, необходимый приложению, а затем объединяет все эти модули в один или несколько пакетов.
Принцип упаковки
- Определите входной файл
Упаковка команд отладки
npm run dev
npm run build
packages.json
...
"scripts": {
"dev_def": "webpack-dev-server --inline --public --config build/dev.js",
"dev": "nodemon --watch config/index.js --exec \"webpack-dev-server --inline --public --config build/dev.js\"",
"start": "npm run dev",
"build": "cross-env NODE_ENV=production node build/build.js"
}
...
webpack-dev-server
Это легкий сервер.После изменения исходного кода файла страница автоматически обновляется, чтобы синхронизировать изменение со страницей.
webpack-dev-server --inline --public --config build/dev.js
- [--inline или --inline=false] Встроенный режим: сценарии будут вставлены в пакет для обработки перезагрузки в реальном времени, а сообщения о сборке будут отображаться в консоли браузера.
module.exports = {
//...
devServer: {
inline: true
}
};
- [--public xxx] При использовании встроенного режима и проксирования dev-сервера встроенные клиентские сценарии не всегда знают, куда подключаться. Он попытается угадать window.location на основе URL-адреса сервера, но ему нужно будет использовать его, если это не удастся.
- [--config xxx] Указать файл конфигурации
- [--progress] Вывести текущий прогресс на консоль.
nodemon
Он будет отслеживать файлы в проекте. Как только файлы будут изменены, Nodemon автоматически перезапустит приложение.
- [--watch xxx] Мониторинг указанного файла или каталога
- [--Exec xxx] выполняет указанную команду
nodemon --watch config/index.js --exec \"webpack-dev-server --inline --public --config build/dev.js\"
Это предложение означает: Используйте nodemon для мониторинга файла config/index.js.Если есть какие-либо изменения, повторно выполните команду [webpack-dev-server --inline --public --config build/dev.js]
Команда [webpack-dev-server --inline --public --config build/dev.js] имеет функцию горячего обновления для самого проекта, но при изменении файла конфигурации webpack сам dev-сервер не возьмет эффект. Использование nodemon заключается в перезапуске службы при изменении файла конфигурации webpack, что является автоматическим дополнением
cross-env
Решите сценарии для кросс-платформенной настройки и использования переменных среды, таких как сглаживание имен переменных, путей
- cross-env NODE_ENV=production устраняет проблему установки кросс-платформенных переменных окружения
базовая конфигурация
module.exports = {
// 入口文件
entry: {
app: './src/js/index.js'
},
// 在哪里输出它所创建的 bundles
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/' //确保文件资源能够在 http://localhost:3000 下正确访问
},
// 开发者工具 source-map
devtool: 'inline-source-map',
// 创建开发者服务器
devServer: {
contentBase: './dist',
hot: true // 热更新
},
plugins: [
// 删除dist目录
new CleanWebpackPlugin(['dist']),
// 重新穿件html文件
new HtmlWebpackPlugin({
title: 'Output Management'
}),
// 以便更容易查看要修补(patch)的依赖
new webpack.NamedModulesPlugin(),
// 热更新模块
new webpack.HotModuleReplacementPlugin()
],
// 环境
mode: "development",
// loader配置
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
}
}
__dirname: абсолютный путь к папке, в которой находится текущий файл
запись (конфигурация входного файла)
Синтаксис одиночной записи (сокращенно)
entry: './path/to/my/entry/file.js'
// 或者(对象写法)
entry: {
main: './path/to/my/entry/file.js'
}
многостраничное приложение
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
entry:{
vendor:[resolve('src/lib/polyfill.js'), 'vue', 'vue-router'], // 不推荐
app: resolve('src/main.ts')
}
В версии до WebPack4 поставщик обычно добавляется как отдельная точка входа для компиляции в отдельный файл Vendor (в сочетании с CommonSchunkPlugin)
Это не рекомендуется в веб-пакете 4. Вместо этогоoptimization.splitChunksПараметры отвечают за разделение модулей поставщиков и приложений и создание отдельных файлов. Не создавайте записи для поставщиков или других вещей, которые не являются отправной точкой для выполнения.
Выход (конфигурация вывода файла)
output: {
filename: '[name].bundle.js',
chunkFilename: [name].min.js,
path: path.resolve(__dirname, 'dist'),
publicPath: '/' //确保文件资源能够在 http://localhost:3000 下正确访问
}
- ChunkFileName: этот параметр определяет имя не входного файла
- путь: путь назначения для всех выходных файлов
- publicPath: укажите каталог, на который ссылается файл ресурсов, файл после сборки и префикс пути ссылки на ресурс.
devtool (инструмент отладки: сопоставление файлов)
// dev
devtool: 'eval-source-map'
// prod
devtool: 'source-map'
Секреты ключевых слов:
ключевые слова | имея в виду |
---|---|
eval | При упаковке сгенерированный файл bundle.js и модули оборачиваются eval, за которым следует sourceUrl, указывающий на исходный файл. |
source-map | Эта конфигурация создаст файл .map, и файл карты будет сопоставлен с исходным файлом.При отладке файл .map используется для определения расположения исходного кода. |
cheap | Упаковка с низким потреблением означает, что файл карты не сохраняет информацию о позиции столбца исходного кода при упаковке, а содержит только информацию о позиции строки, поэтому это объясняет описание, стоящее за официальной картой веб-сайта (только строки). |
... | ... |
devServer
devServer: {
compress: true,
port: 9000,
hot: true,
https: true,
overlay: {
warnings: false,
errors: true
},
publicPath: '/platform/redapply/'
}
- сжать: включить сжатие gzip
- порт: номер порта
- hot: следует ли включить функцию замены горячего модуля.
- HTTPS: Вы можете использовать самозаписанный сертификат, также может настроить подписанный сертификат | Boolean, объект
- Наложение: полноэкранные ошибки компиляции или предупреждения в браузере | Boolean, объект
- publicPath: упакованный файл будет развернут по пути, соответствующему этой конфигурации.http://localhost:8080/platform/redapply/index.html
режим (указывает веб-пакету использовать встроенную оптимизацию соответственно)
// dev
mode: 'development'
// build
mode: 'production'
плагины
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
]
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
}
]
}
Общая конфигурация проекта
решать
resolve: {
extensions: ['.js','.ts', '.vue', '.json'],
alias: {
'@lib': resolve('src/lib'),
'@models': resolve('build/models'),
'@components': resolve('src/components'),
'@data': resolve('src/data'),
'@': resolve('src')
}
}
- Расширения имени файла по умолчанию при выборе суффикса пути разбора (в свою очередь попробуйте заказать)
- Пользовательские символы соответствуют заданному псевдониму пути
Предварительно загрузить файлы
Например, определите несколько общедоступных файлов scss. Чтобы не импортировать этот файл для каждой страницы. Мы можем установить предварительную загрузку файлов
module: {
rules: [
...
{
test: /\.sass|scss|css$/,
use: [
...
{
loader: 'sass-resources-loader',
options: {
resources: [
path.resolve(__dirname, '../src/assets/css/vars.scss'),
path.resolve(__dirname, '../src/assets/css/common.scss')
]
}
}
]
}
]
}
оптимизация (элемент конфигурации оптимизации, настраиваемый при сборке)
optimization: {
minimize: true, // 默认为true,效果就是压缩js代码。
minimizer: [ // 压缩时调用的插件
new TerserPlugin(),
new OptimizeCSSAssetsPlugin({})
],
runtimeChunk: { // 默认为false,抽离出运行时公共代码块。
name: 'manifest'
},
splitChunks:{
chunks: 'all', // 必须三选一: "initial" | "all"(推荐) | "async" (默认就是async)
minSize: 30000, // 生成块的最小字节数,30000
minChunks: 1, // 最少被引用的次数
maxAsyncRequests: 3, // 按需加载时候最大的并行请求数
maxInitialRequests: 3, // 一个入口最大的并行请求数
name: true, // 打包的chunks的名字
cacheGroups: { // 缓存配置
common: {
name: 'common', // 要缓存的 分隔出来的 chunk 名称
chunks: 'initial', // 必须三选一: "initial" | "all" | "async"(默认就是async)
priority: 11,
enforce: true,
reuseExistingChunk: true, // 可设置是否重用该chunk
test: /[\/]node_modules[\/](vue|babel\-polyfill|mint\-ui)/
},
vendor: { // key 为entry中定义的 入口名称
name: 'vendor', // 要缓存的 分隔出来的 chunk 名称
chunks: 'initial', // 必须三选一: "initial" | "all" | "async"(默认就是async)
priority: 10,
enforce: true,
reuseExistingChunk: true, // 可设置是否重用该chunk
test: /node_modules\/(.*)\.js/
},
styles: {
name: 'styles',
test: /\.(scss|css)$/,
chunks: 'all',
minChunks: 1,
reuseExistingChunk: true,
enforce: true
}
}
}
}
runtimeChunk
Значение по умолчанию — false, извлечение общего блока кода времени выполнения.
Что такое время выполнения (время выполнения)?
JS в браузере может вызывать API, предоставляемый браузером, например объект окна, API, связанный с DOM, и т. д. Эти интерфейсы не предоставляются движком V8, но существуют в браузере. Поэтому, проще говоря, для этих связанных внешних интерфейсов JS может вызывать их во время выполнения, а также цикл событий JS (Event Loop) и очередь событий (Callback Queue), которые называются RunTime. В некоторых местах основная библиотека core lib, используемая JS, также считается частью RunTime.
время выполнения фрагмента
Когда окружающая среда выполнения куска зависит (метод)
splitChunks
chunks
function (chunk) | string
Указывает, какие блоки будут выбраны для оптимизации.
string:
- initial - чанк входа, не обработанный для асинхронно импортированных файлов
- async — асинхронный фрагмент, обрабатывающий только файлы, импортированные асинхронно (личное понимание)
- все - все куски
function:
splitChunks: {
chunks (chunk) {
// exclude `my-excluded-chunk`
return chunk.name !== 'my-excluded-chunk';
}
}
cacheGroups
Группы кеша могут наследовать и/или переопределять любые параметры splitChunks.*; чтобы отключить любые группы кеша по умолчанию, установите для этого параметра значение false.
- Приоритет приоритета, модуль может принадлежать нескольким группам кеша и в конечном итоге будет введен в CHUNK с высоким приоритетом.
- ReuseexistingChunk указывает на то, что вы можете использовать уже существующие блоки, то есть, если вы соответствуете уже существуют блоки, используйте существующие, больше не создавайте новый блок.
- Установите Minsize, Minchunks, MaxinitialRequests возможность быстро создать кусок с
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 3,
maxInitialRequests: 3,
name: true,
cacheGroups: {
common: {
name: 'common',
chunks: 'initial',
priority: 11,
enforce: true,
reuseExistingChunk: true, // 可设置是否重用该chunk
test: /[\/|\\]node_modules[\/|\\](vue|babel\-polyfill|mint\-ui)/
},
vendor: {
name: "vendor",
chunks: "initial",
priority: 10,
test: /[\/|\\]node_modules[\/|\\](.*)\.js/
},
styles: {
name: 'styles',
test: /\.(scss|css|less)$/,
chunks: 'initial',
minChunks: 1,
reuseExistingChunk: true,
enforce: true
}
}
}
}
Уведомление:
Вот яма, то есть вопрос пути тестового матча Общий Интернет, чтобы увидеть, например:
...
common: {
name: 'common',
chunks: 'initial',
priority: 11,
enforce: true,
reuseExistingChunk: true,
test: /[\/]node_modules[\/](vue|babel\-polyfill|mint\-ui)/
}
...
Существует регулярный тест на совпадение среды Linux с путем. (Например: node_modules/vue)
Но путь окна не совпадает с путем Linux, это обратная косая черта. (например: node_modules\vue)
Таким образом, мы хотим изменить обычный
/[\/|\\]node_modules[\/|\\](vue|babel\-polyfill|mint\-ui)/
Это совместимо с обеими средами
конфигурация в проекте
Вообще говоря, для веб-пакета требуется 3 файла конфигурации.
- webpack.base.conf.js // общедоступная конфигурация
- webpack.dev.conf.js // Конфигурация среды разработки
- WebPack.Prod.conf.js // Конфигурация рабочей среды
Но конфигурация, которую вы видите в нашем проекте, не совсем такая, как описанная выше.
Это потому, что: когда мы генерируем проект в скаффолдинге, мы уже интегрировали базовую конфигурацию веб-пакета.
Все они находятся под @zz/webpack-vue.
И только некоторые записи объекта конфигурации выставлены в нашем проекте.
Открытая структура элемента конфигурации немного отличается от структуры самого веб-пакета.
Разработчики могут настраивать эти объекты, после чего программа будет объединена с конфигурацией по умолчанию для формирования окончательных параметров конфигурации.
(Эта статья является общем внутренним специальным учебным учетом, контентной основой для сравнения)