Skip to content

Commit c8cd91f

Browse files
author
arnoson
committed
feat: allow multiple panel assets
closes #38
1 parent 745c5fa commit c8cd91f

File tree

2 files changed

+62
-48
lines changed

2 files changed

+62
-48
lines changed

packages/kirby-vite/Vite.php

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use Kirby\Filesystem\F;
55
use \Exception;
66
use Kirby\Cms\App;
7+
use Kirby\Toolkit\A;
78

89
class Vite {
910
protected static Vite $instance;
@@ -100,7 +101,7 @@ public function manifest(): array {
100101

101102
$index = kirby()->root('index');
102103
$outDir = $this->outDir();
103-
$manifest = $this->config()['manifest'];
104+
$manifest = $this->config()['manifest'] ?? '.vite/manifest.json';
104105
$manifestPath = "$index/$outDir/$manifest";
105106

106107
if (!F::exists($manifestPath)) {
@@ -161,48 +162,60 @@ protected function client(): ?string {
161162
return js($this->assetDev('@vite/client'), ['type' => 'module']);
162163
}
163164

164-
public function panelJs(?string $entry = null): string|array|null {
165+
public function panelJs(string|array $entries = []): array|null {
165166
if (App::version() < 4) {
166167
if (option('debug')) {
167168
throw new Exception('`vite()->panelJs()` requires Kirby 4');
168169
}
169170
return null;
170171
}
171172

172-
if (!$entry) {
173-
return $this->isDev() ? '@vite/client' : null;
173+
$files = [];
174+
175+
if ($this->isDev()) {
176+
array_push($files, '@vite/client');
177+
}
178+
179+
foreach (A::wrap($entries) as $entry) {
180+
$file = ltrim($this->file($entry), '/');
181+
array_push($files, $file);
174182
}
175-
$asset = $this->file($entry);
176-
$asset = ltrim($asset, '/');
177-
return $this->isDev() ? ['@vite/client', $asset] : $asset;
183+
184+
return count($files) ? $files : null;
178185
}
179186

180-
public function panelCss($entry) {
187+
public function panelCss(string|array $entries = []): array|null {
181188
if (App::version() < 4) {
182189
if (option('debug')) {
183190
throw new Exception('`vite()->panelCss()` requires Kirby 4');
184191
}
185192
return null;
186193
}
187194

188-
$entryIsStyle = $this->isStyle($entry);
189-
if ($this->isDev()) {
190-
return $entryIsStyle ? $this->assetDev($entry) : null;
191-
}
192-
193-
$file = null;
194-
if ($entryIsStyle) {
195-
$file = $this->manifestProperty($entry, 'file');
196-
} else {
197-
$css = $this->manifestProperty($entry, 'css');
198-
$file = $css ? $css[0] : null;
199-
}
200-
if (!$file) {
201-
return null;
195+
$files = [];
196+
197+
foreach (A::wrap($entries) as $entry) {
198+
$isStyle = $this->isStyle($entry);
199+
if ($isStyle) {
200+
$file = ltrim($this->file($entry), '/');
201+
array_push($files, $file);
202+
continue;
203+
}
204+
// The css for an js entry will be injected automatically in development,
205+
// so only have to handle production.
206+
if (!$isStyle && !$this->isDev()) {
207+
$cssList = $this->manifestProperty($entry, 'css', true) ?? [];
208+
foreach ($cssList as $css) {
209+
$file = ltrim($this->assetProd($css), '/');
210+
array_push($files, $file);
211+
}
212+
foreach ($this->collectImportCss($entry) as $css) {
213+
array_push($files, ltrim($css, '/'));
214+
}
215+
}
202216
}
203217

204-
$asset = $this->assetProd($file);
205-
return ltrim($asset, '/');
218+
return count($files) ? $files : null;
206219
}
207220

208221
/**
@@ -253,6 +266,7 @@ public function css(
253266
array $options = [],
254267
bool $try = false
255268
): ?string {
269+
$isStyle = $this->isStyle($entry);
256270
$tags = [];
257271

258272
// Client is only needed during development.
@@ -261,27 +275,23 @@ public function css(
261275
$this->hasClient = true;
262276
}
263277

264-
$entryIsStyle = $this->isStyle($entry);
265-
// During development, we only have to include the style if it is
266-
// 'standalone', meaning a css (or sass, ...) file. The css for an js entry
267-
// like `vite()->css('entry.js')` will be injected automatically.
268-
if ($this->isDev() && $entryIsStyle) {
269-
array_push($tags, css($this->assetDev($entry), $options));
278+
if ($isStyle) {
279+
$file = $this->file($entry, $try);
280+
if ($file) {
281+
array_push($tags, css($file, $options));
282+
}
270283
}
271284

272-
// If the entry is a css file we can simply add it...
273-
if (!$this->isDev() && $entryIsStyle) {
274-
$file = $this->manifestProperty($entry, 'file', $try);
275-
if ($file) array_push($tags, css($this->assetProd($file), $options));
276-
}
277-
// ...but if it is a js file we have to look up the manifest and add all
278-
// css files associated with the entry and it's imports.
279-
if (!$this->isDev() && !$entryIsStyle) {
285+
// The css for an js entry will be injected automatically in development,
286+
// so only have to handle production.
287+
if (!$isStyle && !$this->isDev()) {
280288
$cssList = $this->manifestProperty($entry, 'css', $try) ?? [];
281289
foreach ($cssList as $css) {
282290
array_push($tags, css($this->assetProd($css), $options));
283291
}
284-
array_push($tags, ...$this->collectImportCss($entry, $options));
292+
foreach ($this->collectImportCss($entry, $options) as $css) {
293+
array_push($tags, css($css, $options));
294+
}
285295
}
286296

287297
return count($tags) ? implode("\n", $tags) : null;
@@ -290,15 +300,15 @@ public function css(
290300
/**
291301
* Recursively collect all the css of the manifest item and it's imports.
292302
*/
293-
protected function collectImportCss(string $key, array $options = []): array {
303+
protected function collectImportCss(string $key): array {
294304
$imports = $this->manifestProperty($key, 'imports', true) ?? [];
295305
$tags = [];
296306
foreach ($imports as $import) {
297307
$cssList = $this->manifestProperty($import, 'css', true) ?? [];
298308
foreach ($cssList as $css) {
299-
array_push($tags, css($this->assetProd($css), $options));
309+
array_push($tags, $this->assetProd($css));
300310
}
301-
array_push($tags, ...$this->collectImportCss($import, $options));
311+
array_push($tags, ...$this->collectImportCss($import));
302312
}
303313
return $tags;
304314
}

packages/kirby-vite/test/ViteTest.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,21 +114,25 @@ function setMode($mode) {
114114

115115
it('generates panel assets in development', function () {
116116
setMode('development');
117-
expect($this->vite->panelJs())->toBe('@vite/client');
117+
expect($this->vite->panelJs())->toBe(['@vite/client']);
118118
expect($this->vite->panelJs('main.js'))->toBe([
119119
'@vite/client',
120120
'http://localhost:5173/main.js',
121121
]);
122122
expect($this->vite->panelCss('main.js'))->toBe(null);
123-
expect($this->vite->panelCss('main.css'))->toBe(
123+
expect($this->vite->panelCss('main.css'))->toBe([
124124
'http://localhost:5173/main.css'
125-
);
125+
]);
126126
});
127127

128128
it('generates panel assets in production', function () {
129129
setMode('production');
130130
expect($this->vite->panelJs())->toBe(null);
131-
expect($this->vite->panelJs('main.js'))->toBe('dist/assets/main.1234.js');
132-
expect($this->vite->panelCss('main.js'))->toBe('dist/assets/main.1234.css');
133-
expect($this->vite->panelCss('main.css'))->toBe('dist/assets/main.1234.css');
131+
expect($this->vite->panelJs('main.js'))->toBe(['dist/assets/main.1234.js']);
132+
expect($this->vite->panelCss('main.js'))->toBe([
133+
'dist/assets/main.1234.css',
134+
'dist/assets/chunk-1234.css',
135+
'dist/assets/chunk-5678.css',
136+
]);
137+
expect($this->vite->panelCss('main.css'))->toBe(['dist/assets/main.1234.css']);
134138
});

0 commit comments

Comments
 (0)