Я начну с того, что скажу, что клиентские пакеты в моей компании слишком велики, вроде бы очень велики, или даже удручающе велики.
Я чувствую себя лучше, зная, что раньше они были намного больше, наши приложения в основном используются в современных браузерах на ~ современных компьютерах, и какие бы другие оправдания я ни придумал, чтобы не чувствовать, что я терплю неудачу каждое мгновение дня.
Многие разговоры о производительности в Интернете (по крайней мере, то, с чем я сталкиваюсь) сосредоточены на больших радикальных изменениях, когда мы берем монолитное приложение размером 7 МБ, разбиваем его на код и выходим на улицу, а незнакомец протягивает нам сотню долларов на улице. , но мой мир сегодня не работает. Мне нравится сосредотачиваться на внесении мельчайших изменений, которые могут привести к самым большим немедленным улучшениям, иногда вы вносите радикальные изменения, но обычно время просто не позволяет этого.
Мы используем много значков svg в наших приложениях React, и многие из них используются совместно между приложениями, поэтому мы заключили некоторые из них в общую библиотеку, которая используется примерно 5 приложениями. Вы можете представить, что «application a» использует 40 из них, «application b» использует 15 из них, и так далее и так далее, вы понимаете, а может и нет, обычно это занимает у меня много времени чтобы добраться до цели вообще.
В любом случае, вернемся к svgs, поскольку мы не распространяем esmodules прямо сейчас, я заметил, что, хотя наши приложения импортировали значки вроде этого:
import { Chair } from "@socialtables/icon-svg";
В итоге мы собрали все 226 (и их число постоянно растет) в библиотеке. Моя первая идея заключалась в том, чтобы подтолкнуть людей к прямому импорту следующим образом:
import Chair from "@socialtables/icon-svg/dist/chair";
но в этом случае все, что нужно, - это один человек испортить его, чтобы в конечном итоге пакет раздулся.
Webpack 2 становится здесь лучше с предупреждениями о размере пакета, но нам все еще нужно решить основную проблему, когда я хочу использовать синтаксис один, но в итоге вывод синтаксиса два входит в мой пакет.
Для этого я написал плагин babel для поиска импорта с использованием синтаксиса 1 и преобразования импорта в стиль синтаксиса 2.
const componentToFileMapping = require("./component-mapping"); module.exports = function replace() { const visitor = { Program(path) { const file = path.hub.file; const imports = file.metadata.modules.imports; imports.forEach(imp => { if (imp.source === "@socialtables/icon-svg") { imp.specifiers.forEach(spec => { const imported = spec.imported; const local = spec.local; const binding = file.scope.getBinding(local); binding.referencePaths.forEach(refPath => { const type = refPath.node.type; if (imported && imported !== "default") { const fileName = componentToFileMapping[imported]; const name = refPath.hub.file.addImport( `@socialtables/icon-svg/dist/icon-components/${fileName}`, "default", imported ).name; refPath.replaceWith({ type, name }); } }); }); } }); }, ImportDeclaration(path) { if (path.node.source.value === "@socialtables/icon-svg") { path.remove(); } } } return { visitor }; }
Я уверен, что здесь допустил ошибки, и хотел бы получить отзывы, если вы их заметите, но по сути мы просто ищем в программе импорт компонентов icon-svg не по умолчанию и заменяем их импортом по умолчанию в конкретный файл компонента. (много вдохновения для этого пришло из babel-plugin-lodash). Это помогает нам сэкономить на размере пакета, не изменяя рабочий процесс разработчика и не позволяя одной ошибке выстрелить нам в ногу. (Небольшое примечание, мне очень жаль, что я не знал об astexplorer.net, когда я это сделал, так что, конечно, используйте это, если вы собираетесь сделать что-то подобное.
В одном из наших приложений это увеличило размер пакета на 710 КБ. Пакет по-прежнему слишком велик и требует большой работы, но главное, что я думаю, что я пытаюсь сделать, это то, что люди думают о babel как о esnext = ›текущем компиляторе javascript, хотя он действительно может быть намного больше.
Недавно я экспериментировал с использованием babel, чтобы превратить принятие решений времени выполнения в разветвленных компонентах React в решения времени сборки, генерирующие различные пакеты, и надеюсь вскоре написать об этом.
Если вы дочитали до этого места, спасибо, потому что не думаю, что я бы стал