привет~ уважаемые наблюдатели и господа, привет всем~ я недавно изучалwebpack
соответствующие знания. Когда-то я всегда чувствовалwebpack
Система огромна и сложна в освоении, ее избегают и не хотят учиться. Однако великий человек Лу Синь однажды сказал:В мире так много вещей, которые могут сделать вас маниакальным и беспокойным, и лучшее решение — стиснуть зубы и начать это делать!Поэтому из более простогоCommonsChunkPlugin
Начнем учиться~
Хотя эта статья относительно проста, в ней все же нужно немногоwebpack
знание, если не совсемwebpack
, рекомендуется двигаться первымофициальная документацияа такжеWebpack 3, от входа до отказаУзнать оwebpack
Хорошая основа~
Базовая конфигурация
CommonsChunkPlugin
Плагин - это дополнительная функция для создания отдельного файла (также называемого кусочками), который содержит общие модули нескольких кусков ввода. Вынимая общие модули, окончательный синтезированный файл может быть загружен один раз в начале, а затем сохраняется в кэше для последующего использования. Это приводит к увеличению скорости, потому что браузер быстро вытаскивает общий код из кэша, вместо того, чтобы загружать больший файл каждый раз, когда доступна новая страница.
Проще говоря, это немного похоже на обертку функции. Отделение инварианта от изменения обеспечивает эффективное повторное использование инварианта и гибкую конфигурацию изменения. Далее будем оптимизировать наш проект по этому принципу.Теперь посмотрим как выглядит виртуальный проект~
создать новыйindex.html
Шаблоны и вводindex.js
файл, простая конфигурация выглядит следующим образом:
index.html
:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<p>{{ vue_test }}</p>
</div>
<div class="jq_test"></div>
</body>
</html>
index.js
:
import Vue from 'vue';
import $ from 'jquery';
new Vue({
el: '#app',
data: {
vue_test: 'vue is loaded!'
}
})
$(function() {
$('.jq_test').html('jquery is loaded!')
})
Для наглядности код очень простой, думаю объяснять не надо. Далее просто настройтеwebpack.config.js
, код показан ниже:
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
entry: {
index: path.join(__dirname, 'index.js')
},
output: {
path: path.join(__dirname, '/dist'),
filename: 'js/[name].[chunkhash].js'
},
resolve: { alias: { 'vue': 'vue/dist/vue.js' } },
plugins: [
new CleanWebpackPlugin(['./dist']),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
new BundleAnalyzerPlugin(),
]
};
CleanWebpackPlugin
В основном используется для очисткиdist
Файлы в каталоге, чтобы вам не приходилось вручную очищать их каждый раз при упаковке.HtmlWebpackPlugin
дляdist
новый каталогhtml
шаблон и автоматически вставлять зависимыеjs
.BundleAnalyzerPlugin
В основном для создания упакованныхjs
Зависимости, содержащиеся в файле, при упаковке в это время генерируют:
можно увидеть сгенерированныйindex.js
файл содержитvue
а такжеjquery
.
первая оптимизация
Вообще говоря, библиотека классов в нашем проекте меняется меньше, но бизнес-код поддается изменениям. Необходимо найти способ извлечь библиотеку классов и упаковать бизнес-код отдельно. Это вредитhash
После того, как браузер сможет кэшировать библиотеку классовjs
файлы для оптимизации взаимодействия с пользователем. Наш главный геройCommonsChunkPlugin
официально дебютировал. мы вwebpack.config.js
документplugins
добавлено вCommonsChunkPlugin
, настроенный следующим образом:
plugins: [
//...此前的代码
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function(module) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, './node_modules')
) === 0
)
}
}),
]
Вышеупомянутая конфигурация выполняетсяCommonsChunkPlugin
создать файл с именемvendor
изjs
файл, он извлекает файл записи, которыйindex.js
в источникеnode_modules
состав зависимостей. В данном случае этоvue
а такжеjquery
. Стиль упаковки выглядит так:
На данный момент кажется, что наша проблема решена, библиотека зависимых классов извлекается и упаковывается независимо, а кеш может кэшироваться браузером. Однако все не так просто, нет, вы можете изменить вход по своему желанию.index.js
Код, упакованный снова:
Отчаявшись найтиvendor.js
документhash
измененный. Проще говоря, это вызвано изменением идентификации модуля, более конкретные причины можно найти вСвязанная китайская документация~ Метод исправления на самом деле довольно прост, просто используйте его сноваCommonsChunkPlugin
Извлеките модуль один раз, поместите неизменную библиотеку классов и извлеките измененную. Поэтому добавьте следующий код:
plugins: [
//...此前的代码
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function(module) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, './node_modules')
) === 0
)
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor', 'index']
})
]
После упаковки,dist/js
В каталоге есть дополнительный файл с именемmanifest
изjs
файл, и в этот момент вы меняете, несмотря ни на чтоindex.js
код, упаковкаvendor.js
изhash
больше не изменится.
Но подождите, когда вы захотите хлопнуть в ладоши и покончить с этим, подумайте об этом сценарии: пока проект продолжает итерацию,vendor
Зависимости постоянно добавляются и удаляются, что делает егоhash
Будут постоянные изменения, которые явно не в наших интересах, так как же именно это можно решить?
оптимизировать снова
теперь, когдаCommonsChunkPlugin
Можно извлекать модули в соответствии с нашими потребностями, а внешние модули, которые от них зависят, могут постоянно меняться, так почему бы не извлечь основные зависимые модули в виде файла, а другие зависимости, такие как подключаемые модули, в виде отдельного файла?
Проще говоря, как в нашем проектеvue
является базовой зависимостью и должна использоваться, иjquery
Etc. — это библиотека классов, добавленная позже, которая может быть изменена позже. тогда будетvue
Упакуйте файл независимо, что хорошо для кеширования браузера, потому что независимо от того, добавите ли вы больше библиотек классов или удалите их позжеjquery
час,vue
Файловый кеш все еще действует. Итак, мы можем сделать это, сначала создайте новую запись:
entry: {
index: path.join(__dirname, 'index.js'),
vendor: ['vue'],
},
В основном это используется для указания того, какие зависимости должны быть упакованы независимо. позжеplugins
Внесите следующие изменения:
plugins: [
//...此前的代码
new webpack.HashedModuleIdsPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: function(module) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, './node_modules')
) === 0
)
},
chunks: ['index'],
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor', 'common', 'index']
})
]
плагинHashedModuleIdsPlugin
, используется для хранения ссылок на модулиmodule id
постоянный. а такжеCommonsChunkPlugin
Затем извлеките зависимости, указанные в записи, и упакуйте независимо друг от друга,minChunks: Infinity,
Цель состоит в том, чтобы позволить плагину игнорировать другие вещи, просто извлекая файлы в соответствии с установленным массивом. Затем измените оригиналvendor
, переименован вcommon
, указав его из записиindex.js
извлеченный изnode_modules
зависимость. Наконец, извлечениеwebpack
Функции времени выполнения и идентификаторы их модулейmanifest
. запустить егоwebpack
, который строится, как показано на рисунке:
можно увидетьvue
а такжеjquery
Упакован отдельно в два файла, попробуем добавить новую зависимостьvuex
, результат после упаковки такой:
Таким образом, наша цель оптимизации была достигнута, неизмененные извлекаются, а измененные могут быть динамически настроены ~
резюме
webpack
плагинCommonsChunkPlugin
Это все, что я представил здесь, но есть еще много оптимизаций, таких как включение сжатия, удаление комментариев и т. д. Когда объем проекта постепенно увеличивается,CommonsChunkPlugin
Это не обязательно оптимальное решение для извлечения кода. Сочетание скорости упаковки с детализацией контроля сборкиDLLPlugin
будет работать лучше. Комбинируя разные плагины по разным сценариям для достижения нашей цели, изначальноwebpack
один из прелестей.
Спасибо всем официалам за то, что это увидели, это легче сказать, чем сделать, надеюсь эта статья будет вам полезна, все коды будут загружены наgithubвставай, умоляйstar
~ Спасибо!