Я начну с того, что скажу, что клиентские пакеты в моей компании слишком велики, вроде бы очень велики, или даже удручающе велики.

Я чувствую себя лучше, зная, что раньше они были намного больше, наши приложения в основном используются в современных браузерах на ~ современных компьютерах, и какие бы другие оправдания я ни придумал, чтобы не чувствовать, что я терплю неудачу каждое мгновение дня.

Многие разговоры о производительности в Интернете (по крайней мере, то, с чем я сталкиваюсь) сосредоточены на больших радикальных изменениях, когда мы берем монолитное приложение размером 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 в решения времени сборки, генерирующие различные пакеты, и надеюсь вскоре написать об этом.

Если вы дочитали до этого места, спасибо, потому что не думаю, что я бы стал