Исследование модульной разработки ESM с точки зрения инструментов Vite (1)

Vue.js

Изучив существующий процесс упаковки Webpack в компании, я обнаружил, что из-за узких мест производительности и объема WebGL, threejs, pixijs и других пакетов, когда наш код перестраивается или выполняется горячее обновление HotReplacement, скорость будет очень низкой.

Сцена большая, бизнес сложный и кодов много, что приводит к следующим болевым точкам бизнеса в существующей модели разработки:

  1. Скорость упаковки и компиляции слишком медленная, а эффективность разработки низкая, иногда компиляция занимает 8 минут, а самое медленное горячее обновление каждый раз занимает несколько минут.
  2. Горячие обновления не очень близки к потребностям бизнеса, и страницу нужно каждый раз перезагружать, что неэффективно.

Исследуйте отправную точку

Первоначально у меня возникла эта идея, когда я увидел инструмент упаковки vite, используемый You Yuxi и You Da в прямой трансляции плана Vue 3.0. В то время во введении говорилось, что этот инструмент упаковки компилируется очень быстро, а спецификация ESModule использовала , что вызвало в то время сильные чувства.

В то время я думал о внутреннем коде нашей компании.Благословение webpack,это был "тяжелый".Каждый раз, когда я запускал проект, мой MBP с памятью 16G не мог его нести, вентилятор был очень громким , и было достаточно жарко, чтобы сварить яйца.Время компиляции также является головной болью.

Затем при последующем развитии я также обратил внимание на обновление кода vite склада Youda и обнаружил, что он обновлял его чаще.Видно, что Youda все еще имеет определенные инвестиции в этот проект.

В последующем я узнал о полуфабрикатах, таких как Snowpack и esbuild.Поняв принципы, я почувствовал, что это подходящая возможность для продвижения практики в соответствии со спецификацией ESModule.На ранней стадии исследования , может ли это повысить качество нашей разработки?Улучшение еще предстоит изучить.

Техническое происхождение

В качестве отправной точки ESModule вы можете начать сscriptпомеченtype="module"Говоря о:

<script type="module">
	import foo from '../foo.js';
  import bar from '../bar.js'
  
  foo(bar);
  //... to do
</script>

Теперь, с развитием браузеров и усовершенствованием технических спецификаций, большинство современных браузеров уже поддерживаютtype="module"изscriptВыполнять парсинг прямо под тегомimportзаявление, при непосредственном выполнении этого шага браузерАвтоматически запрашивать ресурсы по пути в соответствии с путем к каталогу, пока триггерпросить, мы можем «перехватывать», перехватывать запрошенный ресурс ресурсов для обработки и возвращать его в браузер для выполнения.

Согласно приведенной выше технической теории, пока существуетindex.jsВы можете импортировать и собирать зависимости шаг за шагом и продолжать собирать зависимости до последней зависимости и выполнять их последовательно.Разве инструменты упаковки (похожие на webpack) в предыдущие годы не делали этого? Конечно, интеграция, которую он делает, более сложная и детальная, но теперь, когда браузеры ее поддержали, этот шаг можно передать браузеру.Что нам нужно сделать, так это проанализировать зависимости.

Технические исследования

Для предыдущего технического исследования я видел статью АлиУпаковка Webpack работает слишком медленно? Приходите попробовать Bundleless!, когда я увидел это, я почувствовал очень похожее на болевые точки нашего бизнес-сценария:

Мы также полагаемся на базовую внутреннюю поддержку и интегрируем бизнес-архитектуру многосторонних бизнес-плагинов.Из-за чрезмерно раздутых пакетов WebGL, Threejs и pixjs общий опыт горячего обновления не очень хорош, а выходные данные sourceMap увеличивает нагрузку на архитектуру.Первый опыт разработки сборки плохой.

В текущем исследовании по продвижению ESM было обнаружено, что существуют некоторые технические проблемы:

1. Синтаксис импорта модуля не поддерживается

Поскольку все процессы разработки в соответствии со спецификацией ESM сильно зависят от браузера, мы также полагаемся на браузер для прямого анализа следующих операторов для сбора зависимостей модулей:

import foo from '../foo.js'

Файл foo будет искать файл пути в соответствии с контекстом, а затем напрямую инициировать запрос, но вопрос в том, разве мы все не писали это так?

import React from 'react';

Он найдет текущий каталог, как и ожидалосьreact.js? Ответ, конечно, нет. Исходный упаковщик отобразит в соответствии с требованием (спецификация commonJs) и введетnode_modulesсоответствующий модуль ниже.

Но теперь он сообщит об ошибке, браузер сообщит следующую ошибку:

Учитывая безопасность браузера, не поддерживается прямой поиск модуля для импорта таким способом, а указание конкретного пути.Есть ли решение? Конечно, есть

Решить проблемы, связанные с модуляризацией

мы запускаемimportПеред утверждением его можно перевести в AST, после перезаписи текущего пути к узлу импорта, сопоставить со статическим каталогом ресурсов нашего сервера (Vite делает это) или напрямую сопоставить с node_modules:

// 转译前
import React from 'react'

// 转译后
import React from '__Module__react';

// 路径解析的时候替换 __Module__
import React from '../node_modules/react/entry.js'

анализируется в__Module__reactПосле того, как ключевое слово может быть заменено, сопоставлено с реальным модулем node_module, черезpackage.jsonизmainполе (найдите главный вход, здесь как пример)lookupFilesРабота, найдите реальную запись после упаковки, а затем импортировать его непосредственно в соответствии с пути модуля.

Конечно, не забывайте кэшировать каждый модуль при его импорте.

2. Многие модули не поддерживают экспорт ESModule.

В этом опросе было обнаружено, что он так же силен, как React, и не поддерживает экспорт ESModule.Они дали следующий ответ:The React team is working on ESM support, они не поддерживают экспорт ESModule в пакет dist, что также приводит к ошибке, если вы используете спецификацию ESM для внедрения React.Можно ли решить существующее решение? ответ да

Rollup обрабатывает экспорт ESModule

rollup также поддерживает модули ES:

Why are ES modules better than CommonJS Modules?

ES modules are an official standard and the clear path forward for JavaScript code structure, whereas CommonJS modules are an idiosyncratic legacy format that served as a stopgap solution before ES modules had been proposed. ES modules allow static analysis that helps with optimizations like tree-shaking and scope-hoisting, and provide advanced features like circular references and live bindings.

Можно сказать, что лучшая стандартная экология ES может лучше прояснить общее направление будущего развития.Мы можем выполнить предварительную оптимизацию при запуске сервера через роллап, который может быть хорошо оптимизирован для каждого модуля, не поддерживающего ESM.

3. Слишком много зависимостей и слишком много запросов делают фактическую разработку очень медленной

Или с помощью объединения вы можете упаковать некоторые файлы на этапе перед запуском и кэшировать (service-worker), если позволяют условия, оптимизировать зависимости следующего запроса и уменьшить проблему слишком большого количества запросов, вызванных слишком большим количеством операторов импорта в браузер.

4. Как решить стили и другие ресурсы, такие как Css, меньше?

Для следующего письма

import './index.module.less'

На самом деле браузер не может его распарсить.Так же мы можем перенять опыт оригинального упаковщика, импортировать его через режим импорта js модуля, а для обработки прекомпилированных возможностей использовать post-css, less и т.д.css-loader, style-loaderАналогичным образом встраивается тег стиля, а также здесь могут обрабатываться некоторые хэш-значения и префиксы.

5.jsx,typescript?

Я нашел очень полезный инструмент esbuild, основанный на спецификации ESModule, который может поддерживать сборку и транспиляцию кода, и он чрезвычайно быстр (язык go имеет высокую степень параллелизма), строит напрямую с нативным кодом, а скорость сборки также чрезвычайно высока. При загрузке он может быть переведен переводчиком.

6. Среда разработки и производственная среда?

Мы используем принцип, что браузер поддерживает спецификацию ESModule.Конечно, мы можем наслаждаться очень быстрой компиляцией и разработкой, но проблема, которая возникает при этом, заключается в том, что эти конфигурации вашей среды разработки нельзя применять к производственной среде? В конце концов, вы не можете просить всех использовать поддерживаемый ESModule браузер. Есть также некоторые грамматики, которые требуют полифиллов для решения проблем совместимости.

Rollup может поддерживать эту операцию. В то же время необходимо убедиться, что некоторые пакеты rollup в среде разработки соответствуют производительности рабочей среды. Кроме того, обратите внимание на некоторые операции Babel во время выполнения. Babel не должен полностью поддерживают аналогичную упаковку и анализ и могут запрашивать пути или ресурсы.В реальности будут расхождения.

7. Todo — горячее обновление?

Технические особенности

1. services-worker

Для некоторых редко меняющихся ресурсов, потому что все они запросы, мы можем даже сделать некоторое кэширование на уровне ПО.После сбора некоторых зависимостей мы можем дать поле конфигурации для настройки некоторых упакованных файлов, которые необходимо кэшировать локально в течение длительного времени. Возврат напрямую через ПО для ускорения передачи и повышения эффективности разработки

2. HTTP2

Для сжатия заголовков и двоичной передачи, предоставляемых HTTP2 для нашего сценария.Передача данных большой модели происходит медленнопроблема может быть эффективно решена? Этот вопрос нуждается в проверке, но это идея, которую можно исследовать, и мультиплексирование определенно имеет большое преимущество для загрузки большого количества моделей и ресурсов в нашу сцену.Это технический момент, и его можно изучить.

Прогноз результатов практики посадки

Опыт запуска

Я запустил несколько демонстраций, эффект очевиден, первая среда разработки уровня веб-пакета:

  • webpack

  • vite

Можно увидеть, что эффективность первой упаковки относительно очевидна в демоверсии, веб-пакет значительно медленнее, а vite добился незаметного опыта разработки.

Опыт горячего обновления

  • webpack

  • vite

Опыт упаковки

В окончательной упаковке производственной среды они почти одинаковы, а веб-пакет даже быстрее:

  • Webpack

  • Vite

SourceMap

Среди них более заманчивым моментом является функция SourceMap.Если вы используете ESM, у вас будет эта функция.Поскольку адрес каждого запроса сопоставляется с реальным файлом, вам не нужен какой-то раздутый SourceMap.Вы можете искать исходник прямо в Source.Файл можно сказать очень ароматный. На рисунке, поскольку vite выполняет слой перевода, соответствующий файлу js, а затем каталогу статических ресурсов, он практически не изменился.

разное

Поскольку проекты на уровне компании более сложны и включают больше сторон, стоимость миграции для упаковки немного высока.Здесь мы смотрим на внутреннюю практику внедрения Alibaba, и эффект все еще очевиден:

  • webpack

  • вит (например)

С точки зрения практики Alibaba, при запуске одного пакета Webpack занимает около 10 секунд, а Vite (в соответствии со спецификацией ESModule) — всего около 1 секунды, что в 10 раз быстрее, а горячее обновление достигло уровня миллисекунд.

будущее

Целью исследования является прояснение будущего направления.Можно сказать, что стандартизация и продвижение ESModule неуклонно растут.Это то, что нужно каждому, чтобы использовать эти функции в разработке.Из Уда отчет о модификации отправляется каждые несколько дней Видно, что он тоже очень заинтересован в этом проекте.

Можно сказать, что поощрение стандартизации способствует непрерывному развитию интерфейса.Можно сказать, что результаты этого исследования очень полезны.Представьте, что при разработке вам не нужно слишком долго ждать компиляции. и упаковка, а «миллисекундный» опыт, ускорит вашу эффективность разработки. Раньше вы компилировали 2 минуты, а отлаживали 3. В течение дня время, потраченное впустую на эти бесполезные места, может иметь часовой уровень, что неэффективно.

Суть упаковки ESM в будущем — передать неэффективный сбор и анализ зависимостей webpack браузеру для исполнения, ускорить компиляцию и конвертацию, повысить эффективность.

В следующем выпуске мы завершим упаковщик из простой демонстрации и закрепим полученные знания.