К содержанию
Medusa
Документация

ViteEntry

Medusa\Frontend\ViteEntry отвечает за подключение ассетов и подготовку mount/state для frontend-приложений.

Инициализация класса

В рамках HTTP-запроса класс инициализируется автоматически при загрузке приложения: Medusa\Frontend\ViteEntry::addSrcPath(Medusa\Frontend\Path $srcPath) и Medusa\Frontend\ViteEntry::setOutPath(Medusa\Frontend\Path $outPath). В методы передаются пути, сформированные на основе src[].path и out.path из www/config/frontend.json.

Выбор frontend-сущности

Для работы с Vite используется фабричный метод Medusa\Frontend\ViteEntry::from($entity), где $entity — имя каталога внутри одного из зарегистрированных source-путей frontend:

use Medusa\Frontend;

$viteEntry = Frontend\ViteEntry::from('themes');

Монтирование entry-приложения

Монтирование выполняется методом $viteEntry->mount($name, $data = []), где $name — имя каталога внутри зарегистрированного source-каталога frontend, например, внутри www/frontend/{entity}/, а $data — состояние, передаваемое во frontend:

$result = $viteEntry->mount('default', [
    'title' => 'Добро пожаловать!',
    'subTitle' => 'Это страница приветствия!',
]);

$preload = $result->preload;
$css = $result->css;
$js = $result->js;
$json = $result->json;
$html = $result->html;

$defaultTheme = sprintf('<!doctype html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Приветствие</title>
    %s
    %s
</head>
<body>
    %s
    %s
    %s
</body>
</html>',
    implode("\n\t", $preload),
    implode("\n\t", $css),
    $html,
    implode("\n\t", $js),
    $json
);

Метод mount() возвращает объект с полями:

  • preload — массив preload-тегов;
  • css — массив CSS-тегов;
  • js — массив JavaScript-тегов;
  • json — готовый <script type="application/json" id="medusa-state-{name}-{index}">{data}</script> с JSON-данными состояния;
  • html — mount-контейнер <div data-medusa-app-id="{name}" data-medusa-state-id="medusa-state-{name}-{index}"></div>.

Пример содержимого файла www/frontend/themes/default/entry.js:

import {mount} from '@shared/js/mount';
import {state} from '@shared/js/state';

import {createApp} from 'vue';
import DefaultTheme from './DefaultTheme.vue';
import './style.css';

mount('default')
   .state(state)
   .each((node, props) => {
       createApp(DefaultTheme, props).mount(node);
   });

Пример содержимого файла www/frontend/themes/default/DefaultTheme.vue:

<script setup>
import {defaultThemeProps} from './props.js';

defineProps(defaultThemeProps);
</script>

<template>
 <h1>{{ title }}</h1>
 <p>{{ subTitle }}</p>
</template>

Пример содержимого файла www/frontend/themes/default/props.js:

export const defaultThemeProps = {
  title: {
    type: String,
    required: true,
  },
  subTitle: {
    type: String,
    required: true,
  },
};

Пример содержимого файла www/frontend/themes/default/style.css:

h1 {
   color: blue;
}

p {
   color: green;
}

Изменение имени entry-файла

Для изменения имени entry-файла используется метод $viteEntry->setEntryFilename($filename):

$viteEntry->setEntryFilename('entry.custom.js');