Создайте пакет UX
Дата обновления перевода 2024-07-25
Создайте пакет UX
Tip
Перед тем как это читать, советуем просмотреть Наилучшие практики для повторно используемых пакетов.
Вот несколько секретов, чтобы сделать так, чтобы ваш пакет устанавливался как пакет UX.
Файл composer.json
Ваш файл composer.json
должен иметь ключевое слово symfony-ux
:
1 2 3
{
"keywords": ["symfony-ux"]
}
Расположение ресурсов
Ваши ресурсы должны быть расположены в одном из следующих каталогов с файлом package.json
, чтобы Flex мог
их обрабатывать во время установки/обновления:
/assets
(рекомендуется)/Resources/assets
/src/Resources/assets
Файл package.json
Ваш файл package.json
должен содержать конфигурацию symfony
с определенными контроллерами,
а также добавить необходимые пакеты в peerDependencies
и importmap
(список
пакетов в importmap
должен быть таким же, как и в peerDependencies
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
{
"name": "@acme/feature",
"version": "1.0.0",
"symfony": {
"controllers": {
"slug": {
"main": "dist/controller.js",
"fetch": "eager",
"enabled": true,
"autoimport": {
"@acme/feature/dist/bootstrap4-theme.css": false,
"@acme/feature/dist/bootstrap5-theme.css": true
}
}
},
"importmap": {
"@hotwired/stimulus": "^3.0.0",
"slugify": "^1.6.5"
}
},
"peerDependencies": {
"@hotwired/stimulus": "^3.0.0",
"slugify": "^1.6.5"
}
}
В этом случае будет раскрыт файл, расположенный по адресу [assets directory]/dist/controller.js
.
Tip
Вы можете либо написать сырой JS в этом файле dist/controller.js
, либо вы можете, например,
написать свой контроллер с помощью TypeScript и трансполировать его в JavaScript.
Вот пример, как это сделать:
- Добавьте следующее в ваш файл
package.json
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
.. code-block:: json
{
"scripts": {
"build": "babel src --extensions .ts -d dist"
},
"devDependencies": {
"@babel/cli": "^7.20.7",
"@babel/core": "^7.20.12",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
"@hotwired/stimulus": "^3.2.1",
"typescript": "^4.9.5"
}
}
Добавьте следующее в ваш файл
babel.config.js
(должно располагаться рядом с вашим файломpackage.json
):1 2 3 4 5 6 7 8 9 10 11 12
module.exports = { presets: [ ['@babel/preset-env', { "loose": true, "modules": false }], ['@babel/preset-typescript', { allowDeclareFields: true }] ], assumptions: { superIsCallableConstructor: false, }, };
- Запустите
npm install
для установки новых зависимостей. - Напишите ваш контроллер Stimulus с помощью TypeScript в файле
src/controller.ts
. - Запустите
npm run build
илиyarn run build
, чтобы трансполировать ваш контроллер TypeScript в JavaScript.
Чтобы использовать ваш контроллер в шаблоне (например, определённом в вашем пакете), вы можете использовать его следующим образом:
1 2 3 4 5 6 7 8 9 10
<div
{{ stimulus_controller('acme/feature/slug', { modal: 'my-value' }) }}
{#
will render:
data-controller="acme--feature--slug"
data-acme--feature--slug-modal-value="my-value"
#}
>
...
</div>
Не забудьте добавить symfony/stimulus-bundle:^2.9
в качестве зависимости композитора для использования
функций Twig stimulus_*
.
Tip
Именование контроллеров: В этом примере name
пакета PHP будет acme/feature
, а имя
контроллера в package.json
- slug
. Следовательно, полное имя контроллера для Stimulus
будет таким: acme--feature--slug
; хотя в функции stimulus_controller()
вы можете использовать
acme/feature/slug
.
Каждый контроллер имеет ряд опций в файле package.json
:
????? | ???????? |
---|---|
enabled | ?????? ?? ???? ??????? ?????????? ?? ?????????. |
main | ???? ? ????? ???????????. |
fetch | ??? ?????????? ??????????? ? ??????????? ??? ???????? ????????.
??????????? eager (?? ?????????), ????? ???????? ?????????? ? ??????????? ? JavaScript, ???????
??????????? ??? ???????? ????????.
??????????? lazy , ????? ??????? ?????????? ? ??????????? ?????????????? ? ????????? ????? ? ?????????
?? ?????? ??????????, ???? (? ?????) ?? ???????? ?????????? HTML ?????????? ??????. |
autoimport | ?????? ?????? ??? ??????? ? ????????????. ???????, ????????, ????? ???? ????????? ?????? CSS ? ??????????? ?? ????????????? ????????-?????????? (????????, Bootstrap 4 ??? 5, Tailwind CSS...). ???????? ?????? ???? ???????? ? ??????? ? ???????? ?????? ? ??????? ????????? ??? ??????? ?????, ????? ??????????, ????? ?? ????????????? ????. |
Специфика Asset Mapper
Чтобы ресурсы вашего пакета работали с AssetMapper, вы должны добавить importmap
в файл package.json
, как указано выше, и добавить некоторые настройки
к контейнеру:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
namespace Acme\FeatureBundle;
use Symfony\Component\AssetMapper\AssetMapperInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
class AcmeFeatureBundle extends AbstractBundle
{
public function prependExtension(ContainerConfigurator $configurator, ContainerBuilder $container): void
{
if (!$this->isAssetMapperAvailable($container)) {
return;
}
$container->prependExtensionConfig('framework', [
'asset_mapper' => [
'paths' => [
__DIR__ . '/../assets/dist' => '@acme/feature-bundle',
],
],
]);
}
private function isAssetMapperAvailable(ContainerBuilder $container): bool
{
if (!interface_exists(AssetMapperInterface::class)) {
return false;
}
// проверить, чтобы был установлен FrameworkBundle 6.3 или выше
$bundlesMetadata = $container->getParameter('kernel.bundles_metadata');
if (!isset($bundlesMetadata['FrameworkBundle'])) {
return false;
}
return is_file($bundlesMetadata['FrameworkBundle']['path'] . '/Resources/config/asset_mapper.php');
}
}