На федае, прошедшем в Гуанчжоу в прошлые выходные, когда основной разработчик веб-пакета Шон представил принцип системы плагинов веб-пакета, он торжественно представил плагин веб-пакета, написанный китайским студентом в летнем лагере Google под руководством наставника Тобиаса. .webpack-deep-scope-analysis-plugin, этот плагин может значительно повысить эффективность встряхивания дерева веб-пакетов.
Текущие недостатки в встряхивании деревьев
Как убийственная функция свертки, встряхивание дерева может использовать преимущества статической спецификации импорта ES6, чтобы уменьшить размер пакета и избежать ненужного ввода кода.Webpack2 также быстро представил эту функцию, но в настоящее время webpack может делать только относительно простые решения, такие как:
В этом примере webpack будет искать ссылку на импортированную переменную, а когда обнаружит, что ссылки на isNumber нет, удалит код isNumber. На самом деле это не очень практично, ведь в текущем vscode переменные, на которые нет ссылок, будут выделены в IDE серым цветом, и в целом вы не совершите ошибку, импортировав модуль, но не используя его.
Если это следующий способ введения, я написал демо следующим образом
Этот пример очень прост, если его изобразить на такой диаграмме
В index.js представлен func2 в func.js, а func1 не представлен, но func1 вводит lodash. При проверке веб-пакета было обнаружено, что lodash действительно используется в func.js, поэтому lodash не будет удален. На самом деле, мы его вообще не использовали.
webpack-deep-scope-analysis-plugin может решить эту проблему.
Вспомогательные эффекты
Перед введением
После введения
85,8 КБ -> менее 1 КБ
Конечно, я здесь главный, потому что здесь была напрямую удалена библиотека lodash, поэтому изменение настолько удивительно. Но даже в реальных проектах мы можем легко использовать плагин, чтобы сократить количество ненужных вступлений.
принцип
Так как же этот плагин решает эту проблему? Вот краткое введение в его подход, основанное на статье, написанной первоначальным автором на Medium.
Принцип WebPack, на самом деле, через все модули, упаковываемые их в один файл, в этом процессе он знает, к которому использовались экспортные модули. Тогда мы также можем пройти все одинаковую область (область), чтобы упростить область неиспользованного, оставляя только то, что нам нужно.
На приведенном выше рисунке уровень FUNC5 ссылается на FUN4, FUN3, FUN2, FUN1 и, наконец, разрешает только модуль DeePequal.
Что такое область действия? На самом деле область действия существует в разных языках. Она используется как компьютерный термин в Википедии и имеет более подробное объяснение. Я думаю, что ее можно перевести как область действия или контекст. В ECMAScript есть следующие четкие определения:
// module scope start
// Block
{ // <- scope start
} // <- scope end
// Class
class Foo { // <- scope start
} // <- scope end
// If else
if (true) { // <- scope start
} /* <- scope end */ else { // <- scope start
} // <- scope end
// For
for (;;) { // <- scope start
} // <- scope end
// Catch
try {
} catch (e) { // <- scope start
} // <- scope end
// Function
function() { // <- scope start
} // <- scope end
// Scope
switch() { // <- scope start
} // <- scope end
// module scope end
В ES6 модуль — это своего рода корневая область, и только функция и класс могут быть экспортированы как дочерние области, поэтому при анализе все области не будут считаться узлами.
Упомянутый нами плагин webpack имеет такой встроенный анализатор области видимости, который может анализировать отношение ссылок области действия из файла записи и, наконец, исключать все неиспользуемые модули.
Конечно, этот плагин не делает все сам, он также опирается на работу предшественников.escopeЭто инструмент для анализа области в ES.Автор плагина изменил его на версию ts и интегрировал в плагин, и использовал интерфейс, открытый webpack, для разбора дерева AST модуля.Основываясь на этом AST, он может быть переданы в область для анализа.
некоторые маргинальные варианты использования
Все не идеально, и в этом платене есть некоторые ситуации, которые могут привести к неправильному изменению
Случай 1: Повторное присвоение переменных
Типичным примером является следующий:
import { isNull } from 'lodash-es';
var fun = 1;
fun = function scope(...args) {
return isNull(...args);
}
export { fun }
В этом примере переменной fun сначала присваивается номер, а затем она присваивается функции, но анализатор области просто пропустит эту переменную и не будет рассматривать ее как отдельную область.
Случай 2: чистая функция
// copy from rambda/es/allPass.js
import _curry1 from './internal/_curry1';
import curryN from './curryN';
import max from './max';
import pluck from './pluck';
var allPass = /*#__PURE__*/_curry1(function allPass(preds) {
return curryN(reduce(max, 0, pluck('length', preds)), function () {
var idx = 0;
var len = preds.length;
while (idx < len) {
if (!preds[idx].apply(this, arguments)) {
return false;
}
idx += 1;
}
return true;
});
});
export default allPass;
В этом примереimport allPass
приведет к_curry1
, поэтому он не будет рассматриваться как отдельная область, потому что он может иметь некоторые «побочные эффекты», такие как изменение всей переменной, влияющее на глобальную.
Так вот автор дал план, можно добавить перед этой функцией/*#__PURE__*/
, который рассматривает функцию как чистую функцию без побочных эффектов, если у нас нетimport allPass
, другие модули, на которые он ссылается, будут удалены.
Лучшие практики
Прежде всего, чтобы использовать встряхивание дерева, необходимо убедиться, что модули, на которые ссылаются, соответствуют спецификациям ES6. Вот почему я представил в предыдущей демонстрацииlodash-es
вместоlodash
.
В проекте внимание следуетbabel
настраиватьmodule: false
, чтобы избежать преобразования модулей Babel в спецификации CommonJS. Пакет импортируемого модуля также должен соответствовать спецификации ES6, и в последнем веб-пакете добавлено ограничение, то есть вpackage.json
определено вsideEffect: false
, что также позволяет избежать появленияimport xxx
Заставить некоторые функции внутри модуля влиять на глобальную среду после выполнения, но они будут удалены.
будущее
В то время я общался с автором плагина, и он сказал, что возможно, что Тобиас в будущем встроит этот плагин в webpack, что также соответствует тенденции нулевой конфигурации webpack4. Однако мы также можем видеть, что недостаточно полагаться на эти инструменты для устранения мертвого кода интерфейсных проектов, а также других статических языков, и сами модули также должны взаимодействовать, чтобы соответствовать спецификациям.
Источник статьи:
- адрес проекта на гитхабе:GitHub.com/Винсент Опрос…
- Первоисточник:Винсент Свойства.GitHub.IO/2018/05/bet…
Технологический еженедельник IVWEBШок в сети, обратите внимание на публичный номер: сообщество IVWEB, регулярно каждую неделю публикуйте качественные статьи.