EasyAdminBundle icon indicating copy to clipboard operation
EasyAdminBundle copied to clipboard

AssetsDto not working as Expected for custom build-path

Open typoworx-de opened this issue 2 years ago • 4 comments

Describe the bug Trying to separate easy-admin assets from frontend by using webpack parallel build creating separate build-packages:

  • public/build/frontend/entrypoint.json & asset-files (js, css, ...)
  • public/build/backend/entrypoint.json & asset-files (js, css, ...)

For the frontend-app this simply works by using:

 {{ encore_entry_link_tags('app', null, 'frontend') }}

targeting public/build/frontend/entrypoint.json and app.js / app.css.

I would expect easyAdmin to use this as well, here: vendor/easycorp/easyadmin-bundle/src/Resources/views/includes/*assets.html.twig

Referencing also to the same encore functions, but asset/dto object looses the package-name!

class DashboardController extends AbstractDashboardController
{
    public function configureAssets(): Assets
    {
        $assets = Assets::new();
        $assetDto = new AssetDto('app');
        $assetDto->setWebpackEntrypointName('backend');   // this is not passed to rendering, results in '_default' there

        $assets->addWebpackEncoreEntry($assetDto);

        return parent::configureAssets()
            ->addWebpackEncoreEntry($assetDto)
        ;
    }
}

To Reproduce see example webpack.config.js implementing parallel builds to separate frontend/backend context into two sub-folders into build/.

Try to configure EasyAdmin DashboardController with assets that work for the entrypoint.json in sub-folder "backend/" inside public/build/.

(OPTIONAL) Additional context

my _encore_link_Tags.html.twig trying to debug:

{# @var assets \EasyCorp\Bundle\EasyAdminBundle\Dto\AssetDto[] #}
{{ dump(assets) }}

{#
{% for encore_asset in assets %}
    {{ ea_call_function_if_exists('encore_entry_link_tags', encore_asset.value, encore_asset.webpackPackageName, encore_asset.webpackEntrypointName, encore_asset.htmlAttributes) }}
{% endfor %}
#}

Resulting dump:

array:1 [▼
  "app" => [EasyCorp\Bundle\EasyAdminBundle\Dto\AssetDto](phpstorm://open?file=/var/www/customer/florian/tourer.metzgerei-reichenbach/vendor/easycorp/easyadmin-bundle/src/Dto/AssetDto.php&line=11) {#799 ▶
    -value: "app"
    -async: false
    -defer: false
    -preload: false
    -nopush: false
    -webpackPackageName: null
    -webpackEntrypointName: "_default"
    -htmlAttributes: []
    -loadedOn: [EasyCorp\Bundle\EasyAdminBundle\Config\KeyValueStore](phpstorm://open?file=/var/www/customer/florian/tourer.metzgerei-reichenbach/vendor/easycorp/easyadmin-bundle/src/Config/KeyValueStore.php&line=11) {#798 ▶
      -map: array:4 [▶
        "index" => "index"
        "detail" => "detail"
        "edit" => "edit"
        "new" => "new"
      ]
    }
  }
]

typoworx-de avatar Nov 21 '22 16:11 typoworx-de

Here's what I've figured out so far:

$assetDto = new AssetDto('app');
$assetDto->setWebpackEntrypointName('backend');

// webpackEntrypointName seems to be ignored by Asset::new($assetDto)
dd($assetDto, Asset::new($assetDto));

typoworx-de avatar Nov 21 '22 16:11 typoworx-de

This is how I finally was able to get rid of the error... just have to figure out everything works as expected for the assets:

    public function configureAssets(): Assets
    {
        $assetDto = new AssetDto('app');
        $assetDto->setWebpackEntrypointName('backend');

        /** @var Asset $asset */
        $asset = Asset::new($assetDto);
        // FIX we have to manually re-assign our custom entrypointName?!
        $asset->webpackEntrypointName($assetDto->getWebpackEntrypointName());

        return parent::configureAssets()
            ->addWebpackEncoreEntry($asset)
        ;
    }

I would expect that Asset::new() will transfer ALL attributes given by AssetDto previously. Why isn't this be done for entryPointName?

typoworx-de avatar Nov 21 '22 16:11 typoworx-de

I've checked SCSS/CSS and JS and my custom-assets are not available in backend-asset namespace as expected. So the workaround above works.

So the question is why is the webpackEntrypointName dropped by using Asset::new($assetDto) as $assetDto has the entrypointName and the created asset has not without doing it manually.

typoworx-de avatar Nov 22 '22 10:11 typoworx-de

This can be done shorter:

public function configureAssets(Assets $assets): Assets
{
    $asset = Asset::new('app');
    $asset->getAsDto()->setWebpackEntrypointName('backend');

    return parent::configureAssets($assets)
        ->addWebpackEncoreEntry($asset);
}

Although I agree, that intuitively, you'd expect addWebpackEncoreEntry() to take an optional argument for entrypoint name, similar to encore_entry_link_tags('app', null, 'backend').

ameotoko avatar May 03 '24 11:05 ameotoko