Skip to content

Commit

Permalink
✨ inital commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Kanti committed May 17, 2024
0 parents commit 26077f7
Show file tree
Hide file tree
Showing 14 changed files with 1,284 additions and 0 deletions.
723 changes: 723 additions & 0 deletions .editorconfig

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions .github/workflows/tasks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Tasks

on: [push, pull_request]

jobs:
lint-php:
name: "php: ${{ matrix.php }} TYPO3: ${{ matrix.typo3 }}"
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: [ '8.1', '8.2', '8.3' ]
typo3: [ '11', '12', '13' ]
steps:
- name: Setup PHP with PECL extension
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: ~/.composer/cache/files
key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-${{ matrix.php }}-composer-
- run: composer require typo3/minimal="^${{ matrix.typo3 }}" -W --dev
- run: composer install --no-interaction --no-progress
- run: ./vendor/bin/grumphp run --ansi
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
public/
vendor/
var/
80 changes: 80 additions & 0 deletions Classes/ViteUtility.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace AUS\ViteHelper;

use Exception;
use TYPO3\CMS\Core\Core\Environment;

final class ViteUtility
{
/**
* @param array{ 'js.'?: string[], 'css.'?: string[], 'fontPreLoad.'?: string[] } $conf
*/
public function headTag(string $content, array $conf): string
{
if (getenv('NODE_ACTIVE') === 'TRUE') {
$lines = [$content, ...$this->developmentVite($conf)];
} else {
$lines = [$content, ...$this->productionVite($conf)];
}

return implode("\n", $lines);
}

/**
* @param array<string, string[]> $conf
* @return array<string>
*/
private function productionVite(array $conf): array
{
$path = Environment::getPublicPath() . '/assets/manifest.json';
$content = file_get_contents($path);
if (!$content) {
throw new Exception(sprintf('vite manifest is necessary, tried to find it here: %s', $path));
}

$data = json_decode(json: $content, associative: true, flags: JSON_THROW_ON_ERROR);

$lines = [];
foreach ($conf as $type => $files) {
foreach ($files as $fileName) {
$fileName = ltrim($fileName, '/');
if (!isset($data[$fileName])) {
throw new Exception(sprintf('configured %s %s not found in manifest.json', $type, $fileName));
}

$fileName = '/' . $data[$fileName]['file'];
$lines[] = match ($type) {
'js.' => sprintf('<script defer type="module" src="%s"></script>', $fileName),
'css.' => sprintf('<link rel="stylesheet" href="%s" media="all">', $fileName),
'fontPreLoad.' => sprintf('<link rel="preload" href="%s" as="font" crossorigin />', $fileName),
default => throw new Exception(sprintf('type not defined %s', $type))
};
}
}

return $lines;
}

/**
* @param array{ 'js.'?: string[], 'css.'?: string[], 'fontPreLoad.'?: string[] } $conf
* @return array<string>
*/
private function developmentVite(array $conf): array
{
$lines = [];
$jsFiles = [
'@vite/client',
...($conf['js.'] ?? []),
'@vite-plugin-checker-runtime-entry'
];
foreach ($jsFiles as $jsFile) {
$url = rtrim(getenv('NODE_DOMAIN') ?: '', '/') . '/' . ltrim($jsFile, '/');
$lines[] = '<script type="module" src="' . $url . '"></script>';
}

return $lines;
}
}
8 changes: 8 additions & 0 deletions Configuration/Services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false
AUS\ViteHelper\:
resource: '../Classes/*'
exclude: '../Classes/Domain/Model/*'
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Vite Helper (highly opinionated)

Can only be used together with our internal setup.

## Installation

```bash
composer require andersundsehr/vite_helper
```

## Usage

add this to your `page.typoscript`

````typoscript
page.headTag.stdWrap.postUserFunc = AUS\ViteHelper\ViteUtility->headTag
page.headTag.stdWrap.postUserFunc {
fontPreLoad {
0 = src/fonts/Iconfont/icomoon.ttf
1 = src/fonts/lato-v23-latin-300.woff2
2 = src/fonts/lato-v23-latin-700.woff2
3 = src/fonts/lato-v23-latin-regular.woff2
}
css {
0 = src/typescript/index.css
}
js {
0 = src/typescript/index.ts
}
}
````

you need to have a `vite.config.js` in your project root

# with ♥️ from anders und sehr GmbH

> If something did not work 😮
> or you appreciate this Extension 🥰 let us know.
> We are hiring https://www.andersundsehr.com/karriere/
138 changes: 138 additions & 0 deletions Tests/Unit/ViteUtilityTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?php

namespace AUS\ViteHelper\Tests\Unit;

use Generator;
use AUS\ViteHelper\ViteUtility;
use TYPO3\CMS\Core\Core\ApplicationContext;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;

final class ViteUtilityTest extends UnitTestCase
{
protected function setUp(): void
{
parent::setUp();
Environment::initialize(
new ApplicationContext('Testing'),
true,
true,
'/app',
__DIR__ . '/fixtures',
'/app/var',
'/app/config',
'/app/public/index.php',
'UNIX'
);
}

/**
* @test
* @covers \AUS\ViteHelper\ViteUtility
*/
public function exceptionUnsupported(): void
{
$utility = new ViteUtility();
putenv('NODE_ACTIVE=FALSE');
$this->expectExceptionMessage('type not defined unsupported.');
$utility->headTag('', ['unsupported.' => ['src/typescript/index.ts']]);
}

/**
* @test
* @covers \AUS\ViteHelper\ViteUtility
*/
public function exceptionFileNotFoundInManifest(): void
{
$utility = new ViteUtility();
putenv('NODE_ACTIVE=FALSE');
$this->expectExceptionMessage('configured js. src/typescript/fileNotFoundInManifest.ts not found in manifest.json');
$utility->headTag('', ['js.' => ['src/typescript/fileNotFoundInManifest.ts']]);
}

/**
* @test
* @covers \AUS\ViteHelper\ViteUtility
* @dataProvider headTagProvider
*
* @param array<string, string[]> $config
*/
public function headTag(string $expected, array $config, bool $nodeActive, string $nodeDomain): void
{
$utility = new ViteUtility();
putenv('NODE_ACTIVE=' . ($nodeActive ? 'TRUE' : 'FALSE'));
putenv('NODE_DOMAIN=' . $nodeDomain);
$result = $utility->headTag('<head>', $config);
self::assertSame(explode("\n", $expected), explode("\n", $result));
}

public static function headTagProvider(): Generator
{
yield [
'expected' => '<head>',
'config' => [

],
'nodeActive' => false,
'nodeDomain' => 'https://node.test.vm23.iveins.de',
];
yield [
'expected' => <<<'EOF'
<head>
<script type="module" src="https://node.test.vm23.iveins.de/@vite/client"></script>
<script type="module" src="https://node.test.vm23.iveins.de/@vite-plugin-checker-runtime-entry"></script>
EOF,
'config' => [

],
'nodeActive' => true,
'nodeDomain' => 'https://node.test.vm23.iveins.de',
];

yield [
'expected' => <<<'EOF'
<head>
<link rel="preload" href="/assets/icomoon-04f9b5bd.ttf" as="font" crossorigin />
<link rel="preload" href="/assets/lato-v23-latin-700-c447dd76.woff2" as="font" crossorigin />
<link rel="stylesheet" href="/assets/index-efe754a5.css" media="all">
<script defer type="module" src="/assets/index-51605102.js"></script>
EOF,
'config' => [
'fontPreLoad.' => [
'src/fonts/Iconfont/icomoon.ttf',
'src/fonts/lato-v23-latin-700.woff2',
],
'css.' => [
'src/typescript/index.css',
],
'js.' => [
'/src/typescript/index.ts',
],
],
'nodeActive' => false,
'nodeDomain' => 'https://node.test.vm23.iveins.de',
];
yield [
'expected' => <<<'EOF'
<head>
<script type="module" src="https://node.test.vm23.iveins.de/@vite/client"></script>
<script type="module" src="https://node.test.vm23.iveins.de/src/typescript/index.ts"></script>
<script type="module" src="https://node.test.vm23.iveins.de/@vite-plugin-checker-runtime-entry"></script>
EOF,
'config' => [
'fontPreLoad.' => [
'src/fonts/Iconfont/icomoon.ttf',
'src/fonts/lato-v23-latin-700.woff2',
],
'css.' => [
'src/typescript/index.css',
],
'js.' => [
'/src/typescript/index.ts',
],
],
'nodeActive' => true,
'nodeDomain' => 'https://node.test.vm23.iveins.de',
];
}
}
Loading

0 comments on commit 26077f7

Please sign in to comment.