Skip to content

Commit

Permalink
feat: add the ability to load selected entrypoints
Browse files Browse the repository at this point in the history
- Add the ability to load a selected entrypoints
- Add BudEntrypointsLoader
  • Loading branch information
nlemoine committed Dec 15, 2022
1 parent f99dccf commit ed54da0
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 5 deletions.
47 changes: 47 additions & 0 deletions docs/loaders.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,53 @@ $third->dependencies(); // handles from $asset[1] and $asset[2]
```


Since your `entrypoints.json` file can contain multiple entries, you can choose to load only some of them.

```json
{
"entrypoints": {
"theme": {
"css": [
"./theme.css",
"./theme1.css",
"./theme2.css",
]
},
"contact": {
"css": [
"./contact.css",
]
},
"editor": {
"css": [
"./editor.css",
]
}
}
}
```

And loading this file:

```php
<?php
use Inpsyde\Assets\Loader\EncoreEntrypointsLoader;

$loader = new EncoreEntrypointsLoader();
/** @var \Inpsyde\Assets\Asset[] $assets */
$assets = $loader->load('entrypoints.json', ['theme', 'contact']);

$second = $assets[1]; // theme1.css
$second->dependencies(); // handle from $asset[0]

$third = $assets[2]; // theme2.css
$third->dependencies(); // handles from $asset[1] and $asset[2]
```

### `BudEntrypointsLoader`

[Bud](https://bud.js.org/) also provides an `entrypoints.json` file and can be used with API as `EncoreEntrypointsLoader`.

## `ArrayLoader`

To create multiple Assets you can use following:
Expand Down
5 changes: 3 additions & 2 deletions src/Loader/AbstractWebpackLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,14 @@ abstract protected function parseData(array $data, string $resource): array;

/**
* @param mixed $resource
* @param array $entrypoints
*
* @return array
*
* phpcs:disable Inpsyde.CodeQuality.ArgumentTypeDeclaration
* @psalm-suppress MixedArgument
*/
public function load($resource): array
public function load($resource, array $entrypoints = []): array
{
if (!is_string($resource) || !is_readable($resource)) {
throw new FileNotFoundException(
Expand All @@ -79,7 +80,7 @@ public function load($resource): array
);
}

return $this->parseData($data, $resource);
return $this->parseData($data, $resource, $entrypoints);
}

/**
Expand Down
40 changes: 40 additions & 0 deletions src/Loader/BudEntrypointsLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

/*
* This file is part of the Assets package.
*
* (c) Inpsyde GmbH
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Inpsyde\Assets\Loader;

class BudEntrypointsLoader extends EncoreEntrypointsLoader
{
protected function parseData(array $data, string $resource, array $entrypoints = []): array
{
$directory = trailingslashit(dirname($resource));
/** @var array{css:string[], js:string[]} $data */
$data = is_array($data) ? $data : [];
if (!empty($entrypoints)) {
$data = array_filter($data, static function (string $handle) use ($entrypoints) {
return in_array($handle, $entrypoints, true);
}, ARRAY_FILTER_USE_KEY);
}

$assets = [];
foreach ($data as $handle => $filesByExtension) {
$files = $filesByExtension['css'] ?? [];
$assets = array_merge($assets, $this->extractAssets($handle, $files, $directory));

$files = $filesByExtension['js'] ?? [];
$assets = array_merge($assets, $this->extractAssets($handle, $files, $directory));
}

return $assets;
}
}
7 changes: 6 additions & 1 deletion src/Loader/EncoreEntrypointsLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@ class EncoreEntrypointsLoader extends AbstractWebpackLoader implements LoaderInt
/**
* {@inheritDoc}
*/
protected function parseData(array $data, string $resource): array
protected function parseData(array $data, string $resource, array $entrypoints = []): array
{
$directory = trailingslashit(dirname($resource));
/** @var array{entrypoints:array{css?:string[], js?:string[]}} $data */
$data = $data['entrypoints'] ?? [];
if (!empty($entrypoints)) {
$data = array_filter($data, static function (string $handle) use ($entrypoints) {
return in_array($handle, $entrypoints, true);
}, ARRAY_FILTER_USE_KEY);
}

$assets = [];
foreach ($data as $handle => $filesByExtension) {
Expand Down
4 changes: 2 additions & 2 deletions tests/phpunit/Unit/Loader/AbstractWebpackLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ protected function parseData(array $data, string $resource): array
return [];
}

public function load($filePath): array
public function load($filePath, array $entrypoints = []): array
{
return parent::load($filePath);
}
Expand All @@ -77,7 +77,7 @@ protected function parseData(array $data, string $resource): array
return [];
}

public function load($filePath): array
public function load($filePath, array $entrypoints = []): array
{
return parent::load($filePath);
}
Expand Down
142 changes: 142 additions & 0 deletions tests/phpunit/Unit/Loader/BudEntrypointsLoaderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Assets package.
*
* (c) Inpsyde GmbH
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Inpsyde\Assets\Tests\Unit\Loader;

use Inpsyde\Assets\Asset;
use Inpsyde\Assets\Loader\BudEntrypointsLoader;
use Inpsyde\Assets\Script;
use Inpsyde\Assets\Style;
use Inpsyde\Assets\Tests\Unit\AbstractTestCase;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;

class BudEntrypointsLoaderTest extends AbstractTestCase
{
/**
* @var vfsStreamDirectory
*/
private $root;

public function setUp(): void
{
$this->root = vfsStream::setup('tmp');
parent::setUp();
}

/**
* @test
*/
public function testLoad()
{
$testee = new BudEntrypointsLoader();

$file = $this->mockEntrypointsFile(
[
"theme" => [
"css" => [
"./theme.css",
],
"js" => [
"./theme.js",
],
],
]
);

$assets = $testee->load($file);

static::assertCount(2, $assets);
static::assertInstanceOf(Style::class, $assets[0]);
static::assertInstanceOf(Script::class, $assets[1]);
}

/**
* @test
*/
public function testLoadSelectedEntrypoints(): void
{
$testee = new BudEntrypointsLoader();

$file = $this->mockEntrypointsFile(
[
"theme" => [
"css" => [
"./theme.css",
],
"js" => [
"./theme.js",
],
],
"contact" => [
"css" => [
"./contact.css",
],
],
"editor" => [
"css" => [
"./editor.css",
],
"js" => [
"./editor.js",
],
],
]
);

$assets = $testee->load($file, ['theme', 'contact']);

static::assertCount(3, $assets);
static::assertInstanceOf(Style::class, $assets[0]);
static::assertInstanceOf(Script::class, $assets[1]);
static::assertInstanceOf(Style::class, $assets[2]);
}

/**
* @test
*/
public function testLoadWithDependencies()
{
$testee = new BudEntrypointsLoader();

$file = $this->mockEntrypointsFile(
[
"theme" => [
"css" => [
"./theme.css",
"./theme1.css",
"./theme2.css",
],
],
]
);

$assets = $testee->load($file);
static::assertCount(3, $assets);

/** @var Asset $asset */
$asset = $assets[1];
static::assertSame(['theme'], $asset->dependencies());

$asset = $assets[2];
static::assertSame(['theme', 'theme-1'], $asset->dependencies());
}

private function mockEntrypointsFile(array $json): string
{
return vfsStream::newFile('entrypoints.json')
->withContent(json_encode($json))
->at($this->root)
->url();
}
}
43 changes: 43 additions & 0 deletions tests/phpunit/Unit/Loader/EncoreEntrypointsLoaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,49 @@ public function testLoad()
static::assertInstanceOf(Script::class, $assets[1]);
}

/**
* @test
*/
public function testLoadSelectedEntrypoints(): void
{
$testee = new EncoreEntrypointsLoader();

$file = $this->mockEntrypointsFile(
[
"entrypoints" => [
"theme" => [
"css" => [
"./theme.css",
],
"js" => [
"./theme.js",
],
],
"contact" => [
"css" => [
"./contact.css",
],
],
"editor" => [
"css" => [
"./editor.css",
],
"js" => [
"./editor.js",
],
],
],
]
);

$assets = $testee->load($file, ['theme', 'contact']);

static::assertCount(3, $assets);
static::assertInstanceOf(Style::class, $assets[0]);
static::assertInstanceOf(Script::class, $assets[1]);
static::assertInstanceOf(Style::class, $assets[2]);
}

/**
* @test
*/
Expand Down

0 comments on commit ed54da0

Please sign in to comment.