Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add the ability to load selected entrypoints #47

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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