js время упаковки сокращается на 90%, сводка практики производственной среды без пакетов

внешний интерфейс JavaScript

最近尝试将bundleless的构建结果直接用到了线上生产环境,因为bundleless只会编译代码,不会打包,因此构建速度极快,同比bundle模式时间缩短了90%以上。 Благодаря тому факту, что большинство браузеров уже поддерживают http2 и модуль es браузера, мы можем применить результаты сборки без пакетов в режиме онлайн к промежуточным и внутренним системам, которые не имеют жестких сценариев совместимости. Эта статья в основном знакомит с проблемами, с которыми я столкнулся на практике использования инструментов построения без пакетов.

  1. источник
  2. Совместите практику снежного покрова
  3. Потоковый импорт для Snowpack
  4. Сравнение производительности
  5. Суммировать
  6. Приложение сравнение снежного покрова и вите

1. Происхождение

1.1 Начиная с http2

В прошлом, поскольку http1.x не поддерживал мультиплексирование, в HTTP 1.x, если вы хотите одновременно запрашивать несколько запросов, вы должны использовать несколько ссылок TCP.А чтобы контролировать ресурсы, в браузере тоже есть ограничение в 6-8 запросов TCP-подключения для одного доменного имени., Поэтому нам нужно объединить некоторые статические ресурсы в одном домене, такие как js и т. Д., В объединение ресурсов и объединить несколько запросов для разных файлов js в один объединенный большой файл js. Вот тут-то и появляются инструменты для пакетов, такие как webpack.

Начиная с http2 реализовано мультиплексирование TCP-ссылок, поэтому больше нет ограничения на количество одновременных запросов под одним доменным именем, мы можем запрашивать несколько ресурсов одного доменного имени одновременно, а одновременный число может быть очень большим, например, 10, 50 100 одновременных запросов для одновременного запроса нескольких ресурсов в рамках одной службы.

Поскольку http2 реализует мультиплексирование, нет необходимости упаковывать несколько статических файлов вместе, чтобы до определенной степени уменьшить количество запросов.

Поддержка основного браузера на http2 выглядит следующим образом:

image.png

除了IE以外,大部分浏览器对http2的支持性都很好,因为我的项目不需要兼容IE,同时也不需要兼容低版本浏览器,不需要考虑不支持http2的场景。 (Это также является одним из предварительных условий для использования разделенного кода в производственной онлайн-среде.)

1.2 Браузер ESM

Мы знакомы с es-модулями.Что такое es-модули, не является предметом этой статьи.Некоторые популярные инструменты упаковки и конструирования, такие как babel и webpack, уже давно поддерживают es-модули.

Давайте рассмотрим самый простой способ написания модулей es:

//main.j
import a from 'a.js'
console.log(a)
//a.js
export let  a = 1

Вышеупомянутые es-модули — это es-модули, которые мы часто используем в наших проектах, такие es-модули можно использовать непосредственно в браузерах, поддерживающих es6.

Давайте рассмотрим пример использования модулей es непосредственно в браузере.

<html  lang="en">
    <body>
        <div id="container">my name is {name}</div>
        <script type="module">
           import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.esm.browser.js'
           new Vue({
             el: '#container',
             data:{
                name: 'Bob'
             }
           })
        </script>
    </body>
</html>

В приведенном выше коде мы можем запустить его напрямую. По типу = "модуль" скрипта мы можем судить, поддерживает ли браузер модули es. Если нет, содержимое скрипта не запустится.

Во-первых, давайте посмотрим на поддержку основных браузеров для модулей ES:

image.pngКак видно из рисунка выше, основные браузеры, такие как Edge, Chrome, Safari и Firefox (+60), начали поддерживать модули es.

Так же как и наш проект не нуждается в сильном бэкграунде в совместимом, поэтому ни один совместимый браузер не поддерживает esm(Это также вторая предпосылка, согласно которой мы можем использовать несвязанный код в производственной онлайн-среде.).

1.3 Резюме

  • Если браузер поддерживает http2, то в определенной степени нам не нужно объединять статические ресурсы.
  • Если браузер поддерживает esm, нам не нужно поддерживать сложные зависимости модулей и загружать отношения с помощью инструментов сборки.

Эти два момента — именно то, что делают инструменты упаковки, такие как webpack, при сборке. Браузерная поддержка http2 и esm позволяет нам сократить количество сценариев с пакетным кодом.

2. Совместите практику снежного покрова

Мы сравниваем SnowPack и Vite, и, наконец, решил использовать SnowPack (см. Окончательное приложение по причинам для выбора и сравнения между SnowPack и Vite). В этой главе описывается, как объединить инструменты SnowPack Construction для создания распаковка онлайн-кода.

2.1 Основное использование снежного покрова

Наши средний и фоновый проекты написаны на React и Typescript, и мы можем напрямую использовать соответствующие шаблоны Snowpack:

npx create-snowpack-app myproject --template @snowpack/app-template-react-typescript

Инструмент сборки Snowpack имеет встроенный tsc, который может обрабатывать файлы с такими суффиксами, как tsx. Вышеприведенное завершает инициализацию проекта.

2.2 Внешняя обработка маршрутизации

Для внешней маршрутизации мы напрямую используем react-router или vue-router и т. д. Когда нам нужно обратить внимание,Если вы находитесь в среде разработки, то вы должны указать файл конфигурации snowpack.config.mjs, чтобы при обновлении он соответствовал внешнему маршруту:

snowpack.config.mjs
...
  routes: [{ match: 'routes', src: '.*', dest: '/index.html' }],
...

Аналогичная конфигурация такая же, как у веб-сервера разработки и т. Д., Так что, когда бэкэнд маршрутизирует 404, он получает статические файлы внешнего интерфейса, чтобы выполнить сопоставление маршрута внешнего интерфейса.

2.3 Обработка css, jpg и других модулей

В Snowpack также идет обработка файлов css и изображений.

  • css

Возьмите sass в качестве примера,

 snowpack.config.mjs
 plugins:  [
      '@snowpack/plugin-sass',
      {
        /* see options below */
      },
    ],

Просто добавьте плагин sass в конфигурацию, чтобы Snowpack поддерживал файлы sass.Кроме того, Snowpack также поддерживает модули css..module.css илиВ файле с именем .module.scss модуль css включен по умолчанию. Кроме того, конечный результат css компилируется в js-модуль и вставляется в тело путем динамического создания тегов стиля.

    //index.module.css文件
    .container{
        padding: 20px;
    }

Файл css.proxy.js после сборки Snowpack:

export let code = "._container_24xje_1 {\n  padding: 20px;\n}";
let json = {"container":"_container_24xje_1"};
export default json;

// [snowpack] add styles to the page (skip if no document exists)
if (typeof document !== 'undefined') {
  const styleEl = document.createElement("style");
  const codeEl = document.createTextNode(code);
  styleEl.type = 'text/css';
  styleEl.appendChild(codeEl);
  document.head.appendChild(styleEl);
}

Мы можем видеть в приведенном выше примере. Конечным результатом построения css является кусок кода js. Динамическая вставка тега стиля в тело позволяет исходному стилю CSS действовать в системе.

  • jpg, png, svg и т. д.

Если тип изображения обработан, Snowpack также скомпилирует изображение в js.

//logo.svg.proxy.js
export default "../dist/assets/logo.svg";

snowpack没有对图片做任何的处理,只是把图片的地址,包含到了一个js模块文件导出地址中。 Стоит отметить, что в модуле es браузера действие импорта аналогично запросу get, импортом из может быть адрес изображения, а сам модуль es браузера может обрабатывать изображения и другие формы. Поэтому в модуле в конце файла .js экспортом может быть изображение.

Версии ниже snowpack 3.5.0 будут терять хэш при использовании модуля css, поэтому вам необходимо выполнить обновление до последней версии.

2.4 Обработка загрузки по запросу

Snowpack по умолчанию не упакован. Просто выполните простую обработку модуля для каждого файла (Преобразование не-js-модулей в js-модули) и обработка синтаксиса, поэтому он, естественно, поддерживает загрузку по требованию, а Snowpack поддерживает метод записи React.lazy.В реактивном проекте, пока React.Lazy используется нормально, может быть достигнута загрузка по требованию.

2.5 Обработка хэшей файлов

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

2.6 Хостинг общедоступного модуля esm

snowpack对于项目构建的bundleless的代码可以直接跑在线上,在bundless的构建结果中,我们想进一步减少构建结果文件大小。 Код, построенный безбандловым способом, по умолчанию при обработке зависимостей стороннего npm-пакета, хотя он и не будет упакован, Snowpack перекомпилирует зависимости в node_modules проекта в esm-форму, а затем помещает их в новый статический каталог. Итак, окончательный код сборки состоит из двух частей:

Код самого проекта, который перерабатывает зависимости в node_modules в статические файлы после esm.

其中node_modules中的依赖处理成esm后的静态文件,可以以cdn或者其他服务形式来托管。 Таким образом, нам не нужно иметь дело с зависимостями в node_modules каждый раз, когда мы собираем. В коде самого проекта, если вы ссылаетесь на пакет npm, вам нужно указать только его cdn-адрес. После этого код сборки становится таким:

*Только код самого проекта (для внедрения стороннего плагина в проект напрямую используется cdn адрес стороннего плагина)*.

Далее, если мы используем адрес cdn, на котором размещены все пакеты npm (форма модуля es), то в процессе локальной разработки или онлайн-сборки нам даже не нужно поддерживать локальный каталог node_modules, а также yarn-lock или package -заблокировать файл. Все, что нам нужно сделать, это файл карты для управления версиями. Сохраните имя пакета npm в проекте и адрес cdn, соответствующий пакету.

Например:

//config.map.json
{
  "react": "https://cdn.skypack.dev/react@17.0.2",
  "react-dom": "https://cdn.skypack.dev/react-dom@17.0.2",
}

Через этот файл карты, будь то в разработке или в Интернете, просто введите:

import React from 'react'

заменить

import React from "https://cdn.skypack.dev/react@17.0.2"

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

Мы упомянули, что размещенный пакет npm имеет службу cdn в виде модуля es. Вышеприведенный пример использует skypack. Это сравнивается со службой cdn unpkg в форме размещенного пакета npm cjs. Разница между ними заключается в следующем. что пакет npm, размещенный unpkg, Большинство из них имеют форму cjs, а пакет npm в виде cjs нельзя напрямую использовать в esm браузера. Что делает skypack, так это конвертирует большинство пакетов npm из cjs в esm, а затем сохраняет и размещает результат в esm.

3. Потоковый импорт снежного покрова

В 2.7 мы упомянули, что скайпак используется в среде разработки, затемНет необходимости в node_modules локально, даже в yarn-lock и package-lockи другие файлы, требуется только один файл json, простой и чистый, содержащий только пару ключ/значение с фиксированным значением. Snowpack3.x предоставляет такую ​​функцию, которая называется Streaming Imports.

3.1 снежный покров и скайпак

В Snowpack3.x скайпак поддерживается в среде разработки:

// snowpack.config.mjs
export default {
  packageOptions: {
    source: 'remote',
  },
};

Таким образом, в процессе dev webserver соответствующий npm-пакет в виде esm в скайпаке напрямую загружается и помещается в конечный результат, без необходимости делать локальное преобразование из cjs в esm. В этом есть несколько преимуществ:

  • Высокая скорость: не нужно npm устанавливать пакет npm, а затем встраивать его в esm, Streaming Imports может напрямую загружать зависимости в виде esm напрямую с адреса cdn.
  • Безопасность: бизнес-коду не нужно иметь дело с преобразованием общедоступного пакета npm cjs в esm, бизнес-код отделен от сторонних зависимостей, а сторонние зависимости передаются в скайпак для обработки.

3.2 Управление зависимостями

Сам Streaming Imports также реализует простой набор управления зависимостями, чем-то похожий на go mod. Это делается через файл с именем snowpack.deps.json. Как мы упоминали в 2.7, если вы используете управляемый cdn, то локальные pack-lock и yarn-lock, и даже node_modules не должны существовать, нужен только простой и чистый json файл, а Snowpack через snowpack.deps. json для реализации управления зависимостями пакетов.

Когда мы устанавливаем пакет npm, в качестве примера мы берем установку ramda:

npx snowpack ramda

В snowpack.deps.json будет сгенерировано:

{
  "dependencies": {
    "ramda": "^0.27.1",
  },
  "lock": {
    "ramda#^0.27.1": "ramda@v0.27.1-3ePaNsppsnXYRcaNcaWn",
  }
}

Командная строка процесса установки выглядит так:

image.pngКак видно из рисунка выше, зависимости, устанавливаемые через npx snowpack, напрямую запрашиваются у skypack cdn.

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

// snowpack.config.mjs

export default {
  packageOptions: {
    source: 'remote',
    types:true //增加type=true
  },
};

Snowpack загрузит файл типов в локальный каталог .snowpack, поэтому вам нужно указать путь поиска типов при компиляции tsc и добавить его в tsconfig.json:

//tsconfig.json
"paths": {
      "*":[".snowpack/types/*"]
    },

3.3 среда сборки

Пример онлайн-кода после сборки выглядит следующим образом:

import * as __SNOWPACK_ENV__ from '../_snowpack/env.271340c8a413.js';
import.meta.env = __SNOWPACK_ENV__;

import ReactDOM from "https://cdn.skypack.dev/react-dom@^17.0.2";
import App from "./App.e1841499eb35.js";
import React from "https://cdn.skypack.dev/react@^17.0.2";
import "./index.css.proxy.9c7da16f4b6e.js";

const start = async () => {
  await ReactDOM.render(/* @__PURE__ */ React.createElement(App, null), document.getElementById("root"));
};
start();
if (undefined /* [snowpack] import.meta.hot */ ) {
  undefined /* [snowpack] import.meta.hot */ .accept();
}

Как видно из вышеизложенного, код после сборки через плагин будет:

import React from 'react'
//替换成了
import React from "https://cdn.skypack.dev/react@^17.0.2";

Сравнение производительности

4.1 сравнение маяков

Просто используйте маяк, чтобы сравнить производительность веб-страниц без пакетов и с пакетами.

  • Простой тест производительности без пакетов:

image.png

  • Внешний тест производительности пакета:

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

4.2 Сравнение сроков строительства

Безбандл-конструкция используется онлайн, в основном для сокращения времени конструирования.Наш традиционный бандл-код, однократная компиляция и упаковка могут занимать несколько минут или даже десять минут. В моем проекте сборка без пакетов занимает всего 4 секунды.

image.png

Для того же проекта сборка пакета с помощью webpack занимает около 60 секунд. Кроме того, для локальной среды разработки, если используется форма snowpack+skypack, также значительно улучшается время холодного старта и горячего обновления.

Время холодного старта проекта Время горячего старта проекта Горячее обновление
Перед миграцией (WebPack) 18 s 18 s около 1 с
После миграции (снежный покров) < 50ms < 50 ms < 50 ms
повышение скорости Более 10 раз

4.3 Сравнение объемов строительной продукции

V. Резюме

В сценариях, где нет строгой совместимости, особенно в промежуточных и фоновых системах, код без пакетов выполняется непосредственно в сети, что является решением, которое можно попробовать.Время работы в сети будет сокращено на 90%, но есть некоторые проблемы, которые необходимо решить. Во-первых, необходимо обеспечить хостинг esm Стабильность службы ресурсов CDN, а также необходимо убедиться, что размещенные ресурсы esm не будут работать ненормально в браузере. Мы запустили несколько распространенных пакетов npm и не нашли исключений, но позже потребуется дополнительное тестирование. Кроме того, если вы запускаете код без пакетов в сети, легко вызвать проблемы с сетевым водопадом, поэтому основной подход заключается в использовании без пакетов в среде разработки, а рабочая онлайн-среда по-прежнему будет выполнять сборку пакетов.

6. Приложение: Сравнение снежного покрова и вите

6.1 Сходства

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

  • В среде dev перерабатываются локальные зависимости, для пакета npm в локальном каталоге node_module он конвертируется в esm через другие инструменты сборки. Затем поместите все преобразованные файлы esm в статический каталог локальной службы.
  • Все поддерживают css, png и другие статические файлы, не нужно устанавливать другие плагины. Специально для css модуль css поддерживается по умолчанию.
  • По умолчанию поддерживаются файлы с такими расширениями, как jsx, tsx и ts.
  • Независимо от фреймворка поддерживаются основные интерфейсные фреймворки, такие как react и vue, но vite лучше всего поддерживает vue.

6.2 Различия

сборка разработчиков:

Snowpack и vite на самом деле похожи, в среде dev пакет npm в локальном node_modules может быть скомпилирован в статическую директорию локального сервера через esinstall и т. д. Разница в среде разработки

  • Snowpack перекомпилирует пакет node_modules в форме esm посредством свертки.
  • vite использует esbuild для перекомпиляции пакета node_modules в форме esm

Таким образом, с точки зрения среды разработки, скорость vite относительно выше, потому что пакет npm будет перекомпилирован только один раз, поэтому скорость среды разработки мало на что влияет, но есть некоторые ошибки во время инициализации. холодный старт проекта.Кроме того, snowpack поддерживает Streaming Imports, вы можете напрямую использовать пакеты npm в виде esm, размещенных на cdn в среде dev, поэтому производительность среды dev не сильно отличается.

сборка сборка:

Когда создается производственная среда, vite не поддерживает развязку.В режиме сборки vite выбирает использование свертывания для упаковки статических файлов, работающих в онлайн-среде, с помощью свертывания. Vite официально поддерживает и поддерживает только накопительный пакет, который может поддерживать согласованность в определенной степени, но его нелегко отделить, поэтому его можно упаковать в сочетании с инструментами сборки без агрегирования. Snowpack по умолчанию является развязкой. Форма развязки по умолчанию не требует инструментов сборки. Для онлайн-сред можно использовать накопительный пакет или веб-пакет. Вы даже можете отказаться от упаковки и использовать развязку напрямую.

Вышеизложенные выводы можно свести в две таблицы:

среда разработки:

товар инструмент для сборки среды разработки
snowpack накопительный пакет (или используйте потоковый импорт)
vite esbuild

построить производственную среду:

товар инструмент для сборки
snowpack 1.unbundle (Esbuild) 2.Rollup 3.webpack ...
vite объединение (и разделение не поддерживается)

Snowpack 6.3 поддерживает потоковый импорт

Streaming Imports是一个新特性,他允许用户,不管是生产环境还是开发环境,都不需要在本地使用npm/yarn来维护一个lock文件,从而下载应用中所使用的npm包到本地的node_module目录下。 Используя Streaming Imports, можно поддерживать файл карты.Ключом в файле карты является имя пакета, а значение напрямую указывает на адрес сервера cdn, на котором размещается esm-файл пакета npm.

6.4 Некоторые преимущества vite

По сравнению со сноупак, вите имеет ряд преимуществ, но лично я считаю, что они не особо полезны.

  • Многостраничная поддержка, в дополнение к root/index.html в корневом каталоге, он также поддерживает страницы, отличные от корневого каталога, например, nest/index.html.
  • Лучшая поддержка препроцессоров css (лично я этого не нашел)
  • Поддержка разделения кода CSS
  • Оптимизирован асинхронный запрос для нескольких файлов фрагментов (он может выполняться синхронно независимо от сценария, тем самым в определенной степени сокращая общее время запроса)

6.5 Резюме

如果想在生产环境使用unbundle,那么vite是不行的,vite对于线上环境的build,是必须要打包的。 Vite оптимизирует только среду разработки. По умолчанию Snowpack развязан, поэтому его можно использовать в качестве предпосылки для использования развязки в рабочей среде.Кроме того, Snowpack Streaming Imports предоставляет полный набор средств управления пакетами локальной карты без необходимости локальной установки пакетов npm, что очень удобно. нам удобно онлайн и офлайн использовать cdn для размещения публичных библиотек.