-
Notifications
You must be signed in to change notification settings - Fork 14
WIP: build docs #907
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
shining-mind
wants to merge
13
commits into
v4
Choose a base branch
from
st-4704/build-docs
base: v4
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
WIP: build docs #907
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
1d00bb7
docs(build): add readme
shining-mind f0ca768
docs(build): update readme
shining-mind e42f007
docs(build): add info about webpack build and monic
shining-mind 99bb24d
docs(build): minor improvements
shining-mind 1487126
docs(build): add info about graph and pzlr
shining-mind 3da1118
docs(build/graph): fix jsdoc
shining-mind 4989aee
docs(build): add info about snakeskin and fatHTML
shining-mind d688d13
docs(build): review fixes
shining-mind bd2e3fa
docs(build): add build diagram
shining-mind 16e1f8c
docs(build): improve diagram image quality
shining-mind 275ae2f
docs(build): fix grammar error
shining-mind 88e90a1
docs(build): add info about external deps
shining-mind c71c900
docs(build): add mermaid diagram
shining-mind File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,303 @@ | ||
| # V4Fire Сборка <!-- omit in toc --> | ||
|
|
||
| - [Введение](#введение) | ||
| - [Предусловия](#предусловия) | ||
| - [Концептуальное описание сборки](#концептуальное-описание-сборки) | ||
| - [Диаграмма сборки](#диаграмма-сборки) | ||
| - [Конфигурация](#конфигурация) | ||
| - [Граф зависимостей](#граф-зависимостей) | ||
| - [Создание графа зависимостей](#создание-графа-зависимостей) | ||
| - [Параметры компонентов (build/graph/component-params)](#параметры-компонентов-buildgraphcomponent-params) | ||
| - [Внешние зависимости в (dist/client/lib)](#внешние-зависимости-в-distclientlib) | ||
| - [PZLR](#pzlr) | ||
| - [Модуль block](#модуль-block) | ||
| - [getAll](#getall) | ||
| - [Модуль resolve](#модуль-resolve) | ||
| - [sourceDirs](#sourcedirs) | ||
| - [Модуль entries](#модуль-entries) | ||
| - [getBuildConfig](#getbuildconfig) | ||
| - [getUnionEntryPoints](#getunionentrypoints) | ||
| - [Advanced](#advanced) | ||
| - [Особенности сборки snakeskin](#особенности-сборки-snakeskin) | ||
| - [Особенности сборки стилей](#особенности-сборки-стилей) | ||
| - [Сборка fatHTML](#сборка-fathtml) | ||
|
|
||
| ## Введение | ||
|
|
||
| Для сборки используется [`webpack5`](https://webpack.js.org/concepts/) | ||
| и [`pzlr`](https://github.com/pzlr/build-core). | ||
| Конфигурация сборки и окружения осуществляется с помощью библиотеки [`config`](https://www.npmjs.com/package/config/v/1.31.0). | ||
|
|
||
| Для сборки шаблонов используется компилятор [`snakeskin`](https://github.com/SnakeskinTpl/Snakeskin) | ||
| и `webpack` загрузчик [`snakeskin-loader`](https://github.com/SnakeskinTpl/snakeskin-loader). | ||
|
|
||
| Также мы активно используем препроцессор [`monic`](https://www.npmjs.com/package/monic), | ||
| который позволяет в зависимости от параметров окружения вырезать/заменять/добавлять части исходного кода. | ||
|
|
||
| ## Предусловия | ||
|
|
||
| - Ожидается, что проект имеет слои, например для `@v4fire/client` нижележащим слоем является | ||
| `@v4fire/core`, это означает, что исходный код при сборке может подключаться | ||
| как из директории `./src`, так и из директории `./node_modules/@v4fire/core/src`. | ||
| - В корне проекта должен присутствовать файл `.pzlrrc`, | ||
| в котором указаны слои проекта (`dependencies`), директория с исходным кодом и иные параметры. | ||
| - В корне проекта должен присутствовать файл `.tsconfig`, | ||
| при необходимости можно создать файл `client.tsconfig` со специфичными параметрами для сборки. | ||
| - В директории `src/entries` должны быть размещены файлы входных точек (`entry`) для `webpack`. | ||
|
|
||
| ## Концептуальное описание сборки | ||
|
|
||
|
|
||
| При запуске `npm run build` создается `tsconfig.json`, а затем вызывается CLI `webpack`. | ||
|
|
||
| > У каждого проекта разный набор слоев, поэтому `tsconfig.json` создается динамически, | ||
| > с помощью `pzlr` генерируются правильные пути для компилятора TS (`compilerOptions.paths`). | ||
|
|
||
| Конфиг `webpack` генерируется автоматически (см. `webpack.config.js`). | ||
|
|
||
| Перед генерацией конфига в первую очередь подключается модуль `build/snakeskin`, | ||
| который добавляет в `snakeskin` различные | ||
| [фильтры](http://snakeskintpl.github.io/docs/guide-ru.html#filters), | ||
| а также поддержку импортов из слоев. | ||
|
|
||
| Затем с помощью графа зависимостей (`build/graph`) генерируются конфиги сборок `webpack` | ||
| (для параллелизации), далее будем их называть процессами. | ||
|
|
||
| Каждый процесс отвечает за сборку определенной части проекта: стили, js, html и т.д. | ||
|
|
||
| > Граф зависимостей (`build/graph`) играет ключевую роль при сборке, его назначение и функции | ||
| > описаны в соответствующем разделе. | ||
|
|
||
| В момент построения графа создаются конечные входные точки в директории `src/entries/tmp`, | ||
| которые затем будут переданы в качестве параметра `entry` в `webpack`. | ||
|
|
||
| > Промежуточные файлы входных точек создаются для того, чтобы оптимизировать импорты стилей, | ||
| > шаблонов и исходного кода из слоев проекта. | ||
| > Рекурсивно добавляются необходимые `require` согласно указанным | ||
| [зависимостям компонента](https://github.com/V4Fire/Client/wiki/Базовое-создание-компонента#indexjs), | ||
| > при этом происходит автоматическое разрешение путей к файлам с исходным кодом | ||
| > с учетом их местоположения в иерархии слоев. | ||
|
|
||
| Для каждого процесса формируется своя конфигурация с помощью модулей, | ||
| которые расположены в директории `build/webpack`, названия модулей совпадают | ||
| с параметрами конфигурации `webpack`, например: module, alias, output и т.д. | ||
|
|
||
| > Стоит обратить внимание, что для импорта модулей используется функция [`include`](https://github.com/V4Fire/Core/blob/v4/build/include.js) | ||
| > она ищет модуль по слоям проекта, что позволяет переопределять модули в вышележащих слоях. | ||
|
|
||
| Далее осуществляется сборка: | ||
| - Шаблоны `snakeskin` компилируются в низкоуровневые команды Vue. | ||
| - `stylus` собирается с использованием кастомных плагинов, которые расположены в директории [`build/stylus`](/build/stylus). | ||
shining-mind marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - TypeScript собирается с помощью `ts-loader`. | ||
|
|
||
| Практически все типы файлов перед сборкой предварительно обрабатываются с помощью `monic`: | ||
| - Импорты с использованием `@super` разрешаются относительно нижележащего слоя. | ||
| - Разрешает `@context` импорты (см. `components/directives/icon`) | ||
| - Преобразовывает динамические импорты компонентов в группу импортов: стилей, шаблонов и исходного кода. | ||
| - Подгружает зависимости компонентов: шаблоны, стили и т.д. | ||
|
|
||
| ### Диаграмма сборки | ||
|
|
||
| ```mermaid | ||
| flowchart TB | ||
| A((Start)) -->|npx webpack| prepare | ||
|
|
||
| subgraph prepare | ||
| direction TB | ||
|
|
||
| B(Load `webpack.config.js`) | ||
| B --> C(Add custom filters to `snakeskin` compiler) | ||
|
|
||
| end | ||
|
|
||
| prepare --> |call buildProjectGraph|buildgraph | ||
|
|
||
| subgraph buildgraph [module build/graph] | ||
| direction TB | ||
|
|
||
| A1(Scan layers for the components) | ||
| A1 --> B1(Generate `component-lock.json`) | ||
| B1 --> C1(Read entries from `./src/entries`) | ||
| C1 --> D1(Build graph using `entries` and `components`) | ||
| D1 --> E1(Transform graph entries using `entryReducer`) | ||
| E1 --> F1(Write entries to `./src/entries/tmp`) | ||
|
|
||
| end | ||
|
|
||
| buildgraph --> build | ||
|
|
||
| subgraph build | ||
| direction TB | ||
|
|
||
| A2(Generate webpack config\n using graph `processes`) | ||
| Runtime(Build runtime) | ||
| Standalone(Build standalone) | ||
| Styles(Build styles) | ||
| A2 --> Runtime & Standalone & Styles | ||
| Runtime & Standalone & Styles --> HTML(Build HTML) | ||
|
|
||
| end | ||
|
|
||
| build --> Z((End)) | ||
| ``` | ||
| ## Конфигурация | ||
|
|
||
| Конфиги проекта расположены в директории `config`. | ||
| Как говорилось ранее используется библиотека [`config`](https://www.npmjs.com/package/config/v/1.31.0). | ||
| Здесь указываются следующие параметры: | ||
|
|
||
| - движок рендера, по-умолчанию: `vue3` | ||
| - параметры сборки: режим, кол-во CPU под сборку и др. | ||
| - параметры webpack: режим, тип кэширования, SSR сборка и др. | ||
| - тема приложения | ||
| - параметры стилей, snakeskin, monic и т.д. | ||
|
|
||
| Управлять параметрами конфигурации при сборке, можно с помощью флага `--env`, | ||
| например: | ||
|
|
||
| ``` | ||
| npx webpack --env build-mode=production | ||
| ``` | ||
|
|
||
| или с помощью `.env` файла: | ||
|
|
||
| ``` | ||
| BUILD_MODE=production | ||
shining-mind marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ``` | ||
|
|
||
| или с помощью установки переменной окружения (только для `unix` систем) | ||
|
|
||
| ``` | ||
| BUILD_MODE=production npx webpack | ||
| ``` | ||
|
|
||
| ## Граф зависимостей | ||
|
|
||
| Ускоряет сборку за счёт кэширования `webpack` процессов, входных точек и их зависимостей, а также | ||
| полного списка компонентов с их расположением на файловой системе. | ||
|
|
||
| Граф зависимостей хранится в директории `app-cache/{hash}/graph.json`, | ||
| где `hash` - это параметр `build.hash` из конфига проекта. | ||
|
|
||
| Он включает в себя 4 поля: | ||
| - `entry` - конечные входные точки для сборки `webpack`, | ||
| - `processes` - процессы для сборки `webpack`, | ||
| - `dependencies` - здесь указаны runtime зависимости входных точек, | ||
| - `components` - все компоненты проекта (с учётом родительских слоев), | ||
| хранятся в файле `components-lock.json`. | ||
|
|
||
| **Информация о компонентах:** | ||
|
|
||
| Это хеш-таблица, где ключом является имя компонента, а значением метаданные компонента. | ||
| В метаданных указан путь к компоненту на файловой системе. | ||
|
|
||
| Данный путь используется при сборке, чтобы избежать чтений с файловой системы. | ||
shining-mind marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Это особенно актуально, когда у проекта несколько слоев и поиск файла в каждом слое, | ||
| может существенно замедлить сборку. | ||
|
|
||
| ### Создание графа зависимостей | ||
|
|
||
| Граф зависимостей строится непосредственно перед генерацией конфигурации для `webpack`. | ||
| В процессе его построения генерируются промежуточные входные точки в `src/entries/tmp` | ||
| (см. `entryReducer` в `build/graph`) при помощи функций `getBuildConfig` и `getUnionEntryPoints` | ||
| из модуля `entries` библиотеки `pzlr`. | ||
|
|
||
| ### Параметры компонентов (build/graph/component-params) | ||
|
|
||
| `TODO`: описать назначение | ||
|
|
||
| ## Внешние зависимости в (dist/client/lib) | ||
|
|
||
| Внешние зависимости описаны в `src/components/super/i-static-page/deps.js`. | ||
| В момент сборки они перемещаются в директорию `dist/client/lib` | ||
| и затем подключаются на страницу как отдельные скрипты. | ||
|
|
||
| Это сделано для оптимизации сборки за счёт `QUESTION` | ||
|
|
||
| ## PZLR | ||
|
|
||
| `TODO`: описать назначение и функции | ||
|
|
||
| ### Модуль block | ||
|
|
||
| #### getAll | ||
|
|
||
| Формирует `component-lock.json` на базе всех компонентов в проекте. | ||
|
|
||
| Хэш для файла `components-lock.json` вычисляется: | ||
| - на базе `index.js` компонентов всех слоев, | ||
| - исходного кода компонентов текущего проекта, | ||
| - параметров конфига проекта `build.componentLockPrefix` и `componentDependencies`. | ||
|
|
||
| ### Модуль resolve | ||
|
|
||
| #### sourceDirs | ||
|
|
||
| Пути к исходному коду всех слоев проекта. Например: | ||
|
|
||
| ```JS | ||
| // Первый путь не имеет `blocks` на конце, т.к. в файле .pzlrrc `blockDir = ''` | ||
| ['./src', './node_modules/@v4fire/core/src/blocks'] | ||
| ``` | ||
|
|
||
| ### Модуль entries | ||
|
|
||
| #### getBuildConfig | ||
|
|
||
| Возвращает метаданные и исходный код входных точек расположенных в `src/entries`. | ||
| При необходимости исходный код входных точек обрабатывается с помощью `monic`. | ||
|
|
||
| #### getUnionEntryPoints | ||
|
|
||
| Вычисляет входные точки и их зависимости на базе входных точек, полученных из `getBuildConfig`. | ||
|
|
||
| ## Advanced | ||
|
|
||
| ### Особенности сборки snakeskin | ||
|
|
||
| Все шаблоны загружаются в глобальную переменную `TPLS`. Для этого создается отдельная точка входа | ||
| в `src/entries/tmp` с расширением `*.ss.js` в которой перечисляются все шаблоны компонентов. | ||
|
|
||
| ```JS | ||
| globalThis.TPLS = globalThis.TPLS || Object.create(null) | ||
| Object.assign(TPLS, require('./../../../components/icons/b-progress-icon/b-progress-icon.ss')); | ||
| Object.assign(TPLS, require('./../../../components/form/b-button/b-button.ss')); | ||
| // ... | ||
| ``` | ||
|
|
||
| Загрузка шаблонов реализована таким образом, потому что `QUESTION`. | ||
|
|
||
| При загрузке `*.ts` файлов с помощью специального `monic` заменителя | ||
| `attach-component-dependencies` добавляются `require` для загрузки шаблонов | ||
| под именем компонента в исходный код. | ||
|
|
||
| ```JS | ||
| TPLS['b-select'] = require("./src/components/form/b-select/b-select.ss")["b-select"]; | ||
| ``` | ||
| **Важно!** данная операция не применяется если включена `fatHTML` сборка | ||
|
|
||
| `QUESTION`: не совсем понятно зачем повторно подключать шаблон в TPLS в runtime, если | ||
| есть входная точка с расширением `*.ss.js`. | ||
|
|
||
| Исходный код шаблона компилируется в набор низкоуровневых Vue команд, для этого используется | ||
| snakeskin loader (см. `build/webpack/module.js`). | ||
|
|
||
| ### Особенности сборки стилей | ||
|
|
||
| Для написания стилей компонента мы используем язык [`stylus`](https://github.com/stylus/stylus), | ||
| а также плагин собственной разработки | ||
| [`stylus-inheritance`](https://github.com/pzlr/stylus-inheritance/tree/master), который | ||
| добавляет функциональность наследования. | ||
|
|
||
| `TODO` | ||
|
|
||
| ### Сборка fatHTML | ||
|
|
||
| Все ресурсы добавляются напрямую в HTML страницу - мы это называем толстым HTML. | ||
|
|
||
| Регулируется через конфиг (см. `webpack.fatHTML`), если следующие режимы сборки: | ||
|
|
||
| - 0 - отключено | ||
| - 1 - только скрипты и ссылки встраиваются в страницу | ||
| - 2 - все ресурсы встраиваются в страницу (`QUESTION`: похоже, что он не работает) | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.