fgeierst / typo3-vite-demo

GNU General Public License v2.0
20 stars 5 forks source link

Viewhelper (instead of UserFunction) #21

Open fgeierst opened 1 year ago

fgeierst commented 1 year ago

@misterboe and @helhum both suggested to use a Fluid Viewhelper to include Vite generated CSS and JS - instead of the UserFunction InsertViteAssets.php included by setup.typoscript.

What are the advantages of this approach?

misterboe commented 1 year ago

My suggestion was to use a viewhelper that passes the assets to the b13asset viewhelper. so you could write css inline if you want. here is a test:

<?php

declare(strict_types=1);

namespace Analogde\SitePackage\ViewHelpers\Vite;

/*
 * This file is part of TYPO3 CMS-based extension "assetcollector" by b13.
 *
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
 */

use B13\Assetcollector\AssetCollector;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;

/**
 * Adding CSS files or CSS inline code from a Fluid template
 */
class MainViewHelper extends AbstractViewHelper
{
    protected AssetCollector $assetCollector;

    public function __construct(AssetCollector $assetCollector)
    {
        $this->assetCollector = $assetCollector;
    }

    public function initializeArguments(): void
    {
        parent::initializeArguments();
        $this->registerArgument(
            'outdir',
            'string',
            'Vite output directory (manifest.json location from sitepackage root)',
            true,
        );
        $this->registerArgument(
            'input',
            'string',
            'Vite main entry file (main.js location from sitepackage root)',
            true,
        );
    }

    public function render(): void
    {
        $currentApplicationContext = \TYPO3\CMS\Core\Core\Environment::getContext()->__toString();
        if ($currentApplicationContext === 'Development/Local') {
            $pageRenderer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Page\PageRenderer::class);
            $pageRenderer->addHeaderData('<script type="module" src="http://localhost:5999/typo3conf/ext/site_package/Resources/Public/@vite/client"></script>');
            $pageRenderer->addHeaderData('<script type="module" src="http://localhost:5999/typo3conf/ext/site_package/Resources/Public/'.$this->arguments['input'].'"></script>');
        } else {
            $file = file_get_contents(
                \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($this->arguments['outdir']) . '/manifest.json'
            );

            $manifest = json_decode($file, true);
            $path = $this->arguments['outdir'];
            if (!str_ends_with($path, '/')) {
                $path .= '/';
            }

            $mainJsFile = $path . $manifest[$this->arguments['input']]['file'];
            if ($mainJsFile) {
                $this->assetCollector->addJavaScriptFile($mainJsFile,  ['type' => 'module', 'async' => 'true']);
            }

            if ($manifest[$this->arguments['input']]['css']) {
                foreach ($manifest[$this->arguments['input']]['css'] as $maincssfile) {
                    $this->assetCollector->addCssFile($path . $maincssfile);
                }
            }
        }
    }
}

https://github.com/b13/assetcollector

peter-neumann-dev commented 1 year ago

Another idea of handling the assets with very less complexity: #23

helhum commented 1 year ago

b13/assetcollector

Isn't the asset collector now part of TYPO3 core? At least I'm using the AssetCollector class in my view helper to add vite assets