DevGang
Авторизоваться

Справочник по компилятору Svelte 

Процесс компиляции Svelte можно разбить на 4 этапа

  1. Разбор исходного кода в абстрактном синтаксическом дереве (AST)
  2. Отслеживание ссылок и зависимостей
  3. Создание блоков кода и фрагментов
  4. Генерировать код

Который суммируется следующим псевдокодом:

const source = fs.readFileSync('App.svelte');

// parse source code into AST
const ast = parse(source);

// tracking references and dependencies
const component = new Component(ast);

// creating code blocks and fragments
const renderer = options.generate === 'ssr' ? SSRRenderer(component) : DomRenderer(component);

// Generate code
const { js, css } = renderer.render();

fs.writeFileSync('App.js', js);
fs.writeFileSync('App.css', css);

1. Разбор исходного кода в AST

// parse source code into AST
const ast = parse(source);

Синтаксис Svelte - это расширенный набор HTML. Svelte реализует собственный синтаксический анализатор для синтаксиса Svelte, который обрабатывает:

  1. Синтаксис HTML div
  2. Фигурные скобки { data }
  3. Логические блоки {#each list as item}

Анализатор обрабатывает специальные теги script и style.

Когда синтаксический анализатор обнаруживает тег script, он использует acorn для анализа содержимого тега. Когда анализатор тег style, он использует css-tree для анализа содержимого CSS.

Кроме того, синтаксический анализатор Svelte различает скрипт экземпляра script и скрипт модуля script context="module".

Svelte AST выглядит так:

{
  html: { type: 'Fragment', children: [...] },
  css: { ... },
  instance: { context: 'default', content: {...} },
  module: { context: 'context', content: {...} },
}

Вы можете попробовать парсер Svelte в ASTExplorer. Вы можете найти анализатор Svelte в HTML> Svelte.

2. Отслеживание ссылок и зависимостей

// tracking references and dependencies
const component = new Component(ast);

На этом этапе Svelte использует AST, чтобы отследить все объявленные и на которые ссылаются переменные и их зависимости.

а. Svelte создает экземпляр Component.

Component xранит информацию класса компонента, который включает в себя:

  1. HTML-фрагмент, fragment
  2. скрипт экземпляра и скрипт модуля AST и их лексические области действия, instance_scope и module_scope
  3. переменные экземпляра, vars
  4. реактивные переменные, reactive_declarations
  5. слоты, slots
  6. использовали имена переменных для предотвращения конфликта имен при создании временных переменных
  7. предупреждения и ошибки
  8. параметры компиляции и игнорируемые предупреждения

б. Пройдите сценарий экземпляра и сценарий модуля AST

Component обходит скрипт экземпляра и скрипт модуля AST, чтобы найти все переменные, объявленные, на которые есть ссылки и которые были обновлены в скрипте экземпляра и скрипте модуля.

Svelte определяет все доступные переменные перед тем, как перейти к шаблону. При обнаружении переменной во время обхода шаблона Svelte помечает переменную как referenced из шаблона.

с. Пройдите шаблон

Svelte проходит через шаблон AST и создает дерево фрагментов из шаблона AST.

Каждый узел фрагмента содержит такую ​​информацию, как:

- выражение и зависимости

Логические блоки {#if} и теги { data } содержат выражения и зависимости выражения.

- сфера

{#each} и {#await} логический блок и let: привязка создают новые переменные для дочернего шаблона.

Svelte создает отдельный узел Fragment для каждого типа узла в AST, поскольку разные виды узла Fragment по-разному обрабатывают вещи:

  1. Элемент узла проверяет атрибутпривязкиконтент и обработчики событий.
  2. Узел слота регистрирует имя слота в Component.
  3. EachBlock узел создает новые возможности и отслеживает keyindex и название итерируемого списка.
  4. ...

д. Пройдите через скрипт AST

После обхода шаблона Svelte теперь знает, обновляется ли когда-либо переменная в компоненте или когда на нее ссылаются.

С помощью этой информации Svelte пытается подготовиться к оптимизации вывода, например:

  1. определить, какие переменные или функции могут быть безопасно выведены из функции instance.
  2. определить реактивные декларации, которые не должны быть реактивными

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

Svelte обновляет селекторы CSS, добавляя класс .svelte-xxx к селекторам при необходимости.

В конце этого шага у Svelte достаточно информации для генерации скомпилированного кода, что приводит нас к следующему шагу.

3. Создание блоков кода и фрагментов

// creating code blocks and fragments
const renderer =
  options.generate === 'ssr' ? SSRRenderer(component) : DomRenderer(component);

На этом этапе Svelte создает экземпляр Renderer, который отслеживает информацию, необходимую для генерации скомпилированного вывода. В зависимости от того, выводить ли код в DOM или SSR , Svelte создает различные экземпляры Renderer.

DOM Renderer

DOM Renderer отслеживает список блоков и контекст.

Блок содержит фрагменты кода для генерации create_fragment.

Контекст отслеживает список переменных экземпляра, которые будут представлены в $$.ctx скомпилированном выводе.

В рендере Svelte создает дерево рендеринга из дерева фрагментов.

Каждый узел в дереве визуализации реализует функцию render, которая генерирует коды, которые создают и обновляют DOM для узла.

SSR Renderer

SSR Renderer предоставляет помощники для генерации литералов шаблона в скомпилированном выводе, таких как add_string(str) и add_expression(node).

Где я могу найти Rendererв исходном коде?

DOM Renderer реализован в src/compiler/compile/render_dom/Renderer.ts, и вы можете проверить код SSR Renderer в src/compiler/compile/render_ssr/Renderer.ts.

4. Генерация кода

// Generate code
const { js, css } = renderer.render();

Разный рендер рендерит по разному.

Рендерер DOM проходит по дереву рендеринга и по пути вызывает функцию render каждого узла. Экземпляр Block передается в функцию render, так что каждый узел вставляет код в соответствующую функцию create_fragment.

Рендерер SSR, с другой стороны, использует разные обработчики узлов для вставки строк или выражений в конечный литерал шаблона.

Функция визуализации возвращает js и css которая будет потребляться в Bundler, через rollup-plugin-svelte и svelte-loader для WebPack соответственно.

Svelte Runtime

Для удаления дублирующегося кода в скомпилированном выводе Svelte предоставляет функцию util, которую можно найти в src/runtime/internal, например:

  1. РОМ связанные Utils, например: appendinsert,detach
  2. планирования Utils, например: schedule_updateflush
  3. Жизненный цикл утилитами, например: onMount,beforeUpdate
  4. анимации, например: create_animation

Источник:

#Svelte
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу