предисловие
Предположительно, большинство людей будут использовать его напрямую при разработке проектов SPA, таких как vue.vue-cli
В ожидании развития строительных лесов, во-первых, это удобно, чтобы сэкономить много усилий по настройке, а во-вторых, это то, чтоvue-cli
В конце концов, какова доказанная зрелая, возникающие проблемы могут найти соответствующие решения в Интернете.
Однако, если мы хотим лучше понять конфигурацию скаффолдинга, его конструкцию и механизм упаковки, нам необходимо с нуля настроить проект, аналогичный vue-cli. Здесь я сделал следующую простую конфигурацию, пожалуйста, критикуйте и исправьте меня, и искренне надеюсь, что я смогу получить руководство от большого человека, чтобы решить проблему в конце статьи.Tree Shaking
Проблемы, приводящие к отсутствию css в упаковке.
Эта статья в основном включает следующие конфигурации:
- Различать переменные среды и объединять конфигурацию
-
webpack-dev-server
локальный сервер -
HtmlWebpackPlugin
сгенерировать html -
CleanWebpackPlugin
очистить папки -
loader
а такжеbabel
настроить -
HotModuleReplacementPlugin
Горячее обновление -
postcss-loader
добавить префикс css -
vue SPA
Введение и анализ -
vue-router
установка и использование -
mini-css-extract-plugin
Отдельные CSS -
purifycss-webpack purify-css
Устранить избыточные CSS -
optimize-css-assets-webpack-plugin
сжатый css -
terser-webpack-plugin
сжатый js -
splitChunks
Извлечь общедоступный код -
image-webpack-loader
Сжатие изображения -
gZip
Ускорить оптимизацию
Исходный код проекта:GitHub.com/Майкл-Ли Чжиган...
Если вы не знаете базовую конфигурацию маленького партнера webpack, просмотрите следующую статью.
Создайте проект веб-пакета с нуля
Создайте мобильную среду vue-cli4+webpack (из коробки)
Создайте структуру проекта веб-пакета
Создайте структуру проекта
-
Создайте
webpack-vue-cli
папка,npm-init-y
Инициализировать проект -
Установите зависимости, связанные с веб-пакетом
npm i webpack webpack-cli webpack-dev-server webpack-merge --save-dev
еслиwebpack
а такжеwebpack-cli
Если нет глобальной установки, вы должны сначала установить ее глобально
- Создать папку проекта
├── src // webpack配置文件
|——main.js // 入口文件
├── static // 项目打包路径
├── index.html // 模板html
├── webpack.base.js // 打包基本配置
├── webpack.dev.js // 本地环境配置
├── webpack.prod.js // 生产环境配置
index.html
а такжеmain.js
Нечего сказать о коде, перейдите непосредственно по ссылке конфигурации веб-пакета.
Различайте окружающую среду
Чтобы лучше оптимизировать упаковку, мы разделяем конфигурацию WebPack в разработку окружающей среды и производственной среде.
- общедоступный файл конфигурации webpack.base.js
- Файл конфигурации для среды разработки webpack.dev.js
- Файл конфигурации webpack.prod.js для рабочей среды
существуетwebpack.dev.js
а такжеwebpack.prod.js
, мы можем использоватьwebpack-merge
Объединить конфигурацию.
Затем мы определяем команды упаковки для разных сред в package.json.
"scripts": {
"dev": "webpack-dev-server --config webpack.dev.js --mode development",
"build": "webpack --config webpack.prod.js"
}
общедоступная конфигурация
Давайте сначала посмотримwebpack.base.js
общедоступная конфигурация, определите файл входа и файл выхода
module.exports = {
entry: {
index: path.join(__dirname, '/src/main.js'),
},
output: {
path: path.join(__dirname, '/dist'), //打包后的文件存放的地方
filename: 'js/[name].[hash].js', // 每次保存 hash 都变化
},
}
webpack-dev-server
webpack предоставляет дополнительный локальный сервер разработки на основеnode.js
построить, так что вwebpack.dev.js
настроить
const merge = require('webpack-merge') // 引入webpack-merge功能模块
const common = require('./webpack.base.js') // 引入webpack.common.js
module.exports = merge(common, {
// 将webpack.common.js合并到当前文件
devServer: {
contentBase: './dist', // 本地服务器所加载文件的目录
port: '8899', // 设置端口号为8088
inline: true, // 文件修改后实时刷新
historyApiFallback: true, //不跳转
hot: true, // 热更新
},
mode: 'development', // 设置mode
})
HtmlWebpackPlugin
HtmlWebpackPlugin
Упрощает создание HTML-файлов, может автоматически создавать для вас упакованные html-файлы после упаковки в соответствии с html-шаблоном. Это полезно для файлов, которые содержат хэш в имени файла, который меняется каждый раз при компиляции.bundle
.
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, '/index.html'), // new一个这个插件的实例,并传入相关的参数
}),
]
Пока построена нищенская версияwebpack
Проект готов, вы можете писать код по своему желанию и выполнять команды в среде разработки и производственной среде, чтобы увидеть эффект.
конфигурация загрузчика
loader
может позволитьwebpack
способен справиться с темиjavaScript
документ(webpack
только понятьjavaScript
).loader
Вы можете преобразовать все типы файлов в действительные модули, которые может обрабатывать веб-пакет, а затем вы можете воспользоваться возможностями упаковки веб-пакета и обработать их.
дляloader
Научно-популярная и конфигурация .js
и файлloader
.
module: {
rules: [
{
test: /\.css$/, // 正则匹配以.css结尾的文件
use: ['style-loader', 'css-loader'],
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'],
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src')],
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]'),
},
},
]
}
Для более удобной настройки и оптимизацииbabel-loader
, мы можем извлечь его и создать новый в корневом каталоге.babelrc
документ
{
"presets": ["env"]
}
CleanWebpackPlugin
Очищайте папку /dist перед каждой сборкой, чтобы создавать последние упакованные файлы, которые используются в настоящее время.CleanWebpackPlugin
плагин тоже.
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, '/index.html'), // new一个这个插件的实例,并传入相关的参数
}),
new CleanWebpackPlugin(), // 所要清理的文件夹名称
]
HotModuleReplacementPlugin
HotModuleReplacementPlugin
(HMR) — очень практичный плагин, который может автоматически обновлять эффект предварительного просмотра после того, как мы изменим код и используем его в среде разработки.
-
devServer
Набор элементов конфигурацииhot: true
-
HotModuleReplacementPlugin
Он поставляется с модулем webpack, поэтому после введения webpack вplugins
Его можно использовать непосредственно в элементе конфигурации.
plugins: [
new webpack.HotModuleReplacementPlugin(), // 热更新插件
]
добавить префикс css
Обычно, когда мы пишем css, некоторым свойствам нужно добавлять префикс вручную, например-webkit-border-radius: 10px;
, в вебпаке мы можем позволить ему автоматически добавлять
- Установить зависимости
npm i postcss-loader autoprefixer -D
- Создайте новый проект в корневом каталоге проекта
postcss.config.js
документ
module.exports = {
plugins: [
require('autoprefixer'), // 引用autoprefixer模块
],
}
- Изменить загрузчик стилей
rules: [
{
test: /\.css$/, // 正则匹配以.css结尾的文件
use: ['style-loader', 'css-loader', 'postcss-loader'],
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'],
},
]
На данный момент проект веб-пакета в основном построен, далее представлены ссылка на vue и оптимизация проекта.
Создайте шаблон vue SPA
vue SPA
1. Создайтеvue-cli
Подмости, прежде всего, нарисуем черпак по тыкве, вmain.js
написать код
import Vue from 'vue'
import App from './App.vue'
new Vue({
el: '#app',
render: (h) => h(App),
})
2. Затем создайте новый в папке srcAPP.vue
<div id="app">SPA项目</div>
3. Установите связанные зависимости
мы здесьnpm run dev
Попробуйте и получите ошибку. Поскольку мы не устанавливали соответствующие зависимости, давайте установим зависимости
npm install vue vue-loader vue-template-compiler -D
- vue: исходный код vue
- vue-loader: анализ файлов .vue
- vue-template-compiler: скомпилировать vue
4, веб-пакет конфигурации vue-loader
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
],
},
plugins: [new VueLoaderPlugin()],
}
vue-router
1. Установите зависимости
npm install vue-router -D
2. Создайте новый маршрутизатор/индекс в папке src.
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/',
component: () => import('../views/Home.vue'),
},
{
path: '/admin',
component: () => import('../views/admin.vue'),
},
],
})
export default router
3. Ссылка в main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
el: '#app',
router,
render: (h) => h(App),
})
Просто так, аvue-cli
Строительные леса установлены, и вы можете с радостью писать.vue
файл для разработки SPA.
webpack оптимизирует упаковку
Отдельные CSS
Хотя идея webpack заключается в том, чтобы упаковать все css и js в один файл, если мы хотим разделить css, здесь мы используемmini-css-extract-plugin
. Еще один плагин контрастаextract-text-webpack-plugin
, имеет следующие преимущества:
- Асинхронная загрузка
- Нет повторной компиляции, лучшая производительность
- проще в использовании
- Только для CSS
ноmini-css-extract-plugin
не поддерживаетсяHMR
, поэтому мы можем использовать его только в производстве.
1. Установите зависимости
npm install mini-css-extract-plugin -D
2. Вwebpack.prod.js
настроитьloader
а такжеplugin
module: {
rules: [
{
test: /\.(le|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
},
},
'css-loader',
'postcss-loader',
'less-loader',
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "css/[name].[contenthash:8].css",
chunkFilename: 'css/[id].[contenthash:8].css'
})
]
Разделение css требует помещенияcss loader
серединаstyle-loader
заменитьMiniCssExtractPlugin
Удалите избыточный CSS
Иногда мы пишем слишком много или дублируем CSS, что приводит к избыточному коду, который мы хотим удалить в рабочей среде.
1. Установите зависимости
npm i purifycss-webpack purify-css glob -D
2. Конфигурация webpack.prod.js
const path = require('path')
const PurifyCssWebpack = require('purifycss-webpack') // 引入PurifyCssWebpack插件
const glob = require('glob') // 引入glob模块,用于扫描全部html文件中所引用的css
module.exports = merge(common, {
plugins: [
new PurifyCssWebpack({
paths: glob.sync(path.join(__dirname, 'src/*.html')),
}),
],
})
сжатый css
Мы хотим уменьшить объем упакованного css, который можно использоватьoptimize-css-assets-webpack-plugin
.
1. Установите зависимости
npm install optimize-css-assets-webpack-plugin -D
2. Конфигурация webpack.prod.js
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin") // 压缩css代码
optimization: {
minimizer: [
// 压缩css
new OptimizeCSSAssetsPlugin({})
]
сжатый js
Webpack4.0 по умолчанию используетterser-webpack-plugin
Этот плагин сжатия, ранее использовавшийсяuglifyjs-webpack-plugin
Разница между ними заключается в том, что последнее сжатие ES6 не очень хорошее, и мы можем открытьparallel
1. Установите зависимости
npm install terser-webpack-plugin -D
2. Конфигурация webpack.prod.js
const TerserPlugin = require('terser-webpack-plugin') // 压缩js代码
optimization: {
minimizer: [
new TerserPlugin({
parallel: 4, // 开启几个进程来处理压缩,默认是 os.cpus().length - 1
cache: true, // 是否缓存
sourceMap: false,
}),
// 压缩css
new OptimizeCSSAssetsPlugin({}),
]
}
Извлечь общедоступный код
При упаковке с помощью webpack для некоторых сторонних библиотек, которые не обновляются часто, таких как некоторые вещи в корзине семейства vue, мы надеемся, что они будут отделены от нашего собственного кода. использование веб-пакета4splitChunks
способ настройки.
optimization: {
// 分离chunks
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
name: "vendor",
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: "initial" // 只打包初始时依赖的第三方
},
}
}
}
Сжатие изображения
Некоторые картинки в проекте слишком велики, чтобы повлиять на загрузку, мы используемimage-webpack-loader
Сжатие.
1. Установите зависимости
npm install image-webpack-loader -D
2. Настроить загрузчик
{
test: /\.(png|jpg|svg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
esModule: false,
limit: 1000, // 限制只有小于1kb的图片才转为base64
outputPath: 'images', // 设置打包后图片存放的文件夹名称
name: '[name][hash:8].[ext]'
}
},
{
loader: 'image-webpack-loader',
options: {
// 压缩 jpeg 的配置
mozjpeg: {
progressive: true,
quality: 65
},
// 使用 imagemin**-optipng 压缩 png,enable: false 为关闭
optipng: {
enabled: false,
},
// // 使用 imagemin-pngquant 压缩 png
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
// 压缩 gif 的配置
gifsicle: {
interlaced: false,
},
// 开启 webp,会把 jpg 和 png 图片压缩为 webp 格式
webp: {
quality: 75
}
}
}
]
}
ускоренная оптимизация gZip
Все современные браузеры поддерживаютgzip
сжатие, включитьgzip
Сжатие может значительно уменьшить размер ресурсов передачи, тем самым сокращая время загрузки ресурсов, уменьшая время первого белого экрана и улучшая взаимодействие с пользователем.
gzip лучше всего работает с текстовыми форматами файлов (например, CSS, JavaScript и HTML), часто достигая 70–90% сжатия при сжатии больших файлов, а также для уже сжатых ресурсов (например, изображений). очень плохой.
const CompressionPlugin = require('compression-webpack-plugin')
configureWebpack: (config) => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new CompressionPlugin({
// gzip压缩配置
test: /\.js$|\.html$|\.css/, // 匹配文件名
threshold: 10240, // 对超过10kb的数据进行压缩
deleteOriginalAssets: false, // 是否删除原文件
})
)
}
}
tree-shaking (помогите, производственная среда не может быть упакована для создания стилей)
Сборка проекта описанным выше способом всегда была гладкой в среде разработки, но после выполненияnpm run build
, откройте страницу и обнаружите, что все стили отсутствуют. Открытьdist/css
папку, нашел три файла css, толькоindex.css
Есть некоторые файлы (main.js вводит начальные стили, но они неполные), а два других css файла пустые, то есть все стили в .vue отсутствуют.
Глядя на ресурсы, изначально предполагается, что по умолчанию используется webpack4.tree-shaking
, БудуНа уровне модуля упакованный код содержит только те модули, на которые есть ссылки и которые выполняются, а модули, на которые нет ссылок или которые не выполняются, удаляются для уменьшения размера пакета.. Но я следил за соответствующими ресурсами наpackage.json
настроенsideEffects
Да, но это все еще не работает, это действительно раздражает! ! !
"sideEffects": [
"*.less",
"*.css",
"*.vue"
]
Я хотел бы попросить вас о помощи здесь.Если вы сталкивались с подобными проблемами или знаете решение, пожалуйста, не стесняйтесь, просветите меня, мой брат будет очень благодарен! ! !