Skip to content

Commit 7f4753d

Browse files
committed
WebpackManifestLoader // introduce support for "@Vendor" in handle when loading from manifest.json.
1 parent 53a73be commit 7f4753d

4 files changed

Lines changed: 63 additions & 18 deletions

File tree

docs/loaders.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ The [webpack-manifest-plugin](https://www.npmjs.com/package/webpack-manifest-plu
2626
"script.js": "/public/path/script.23dafsf2138d.js",
2727
"module.mjs": "/public/path/module.12aafrf5675d.mjs",
2828
"custom.module.js": "/public/path/custom.12aafrf5675d.module.js",
29+
"@vendor/module.js" "/public/path/@vendor/module.js",
2930
"style.css": "style.23dafsf2138d.css",
3031
"sub-folder/style.css": ""
3132
}
@@ -59,13 +60,8 @@ The loader does support scripts modules, files with the `.mjs` extension.
5960
However, due to the limitations imposed on those files in regard to the MIME, we added a support to those files ending with `.module.js`.
6061
This permits us to load those files as script modules too even if we do not have control over the server configuration.
6162

62-
Moreover, if your file ends with `.module.js` or `.mjs`, the loader will not try to build the asset `handle` from the file name.
63-
Instead, it will use the `key` from the manifest file as the **handle**.
64-
The reason is that there might be conventions regarding the handle naming, which might not be compatible with the `WebpackManifestLoader::parseData` logic.
65-
66-
Imagine that `$handle` is `@vendor/lib-name`, then `pathinfo($handle, PATHINFO_FILENAME)` will return `lib-name`.
67-
68-
This is because `pathinfo` treats the last part after a slash as the filename, so it extracts `lib-name` from `@vendor/lib-name`.
63+
Moreover, if your file ends with `.module.js` or `.mjs`, the loader will automatically resolve these files as a `Inpsyde/Assets/ScriptModule`.
64+
Additionally, we support `@vendor/` in the handle name when parsing from `manifest.json`. Before, the `@vendor/` was detected as part of the filepath and being stripped away.
6965

7066
### `EncoreEntrypointsLoader`
7167

src/Loader/AbstractWebpackLoader.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,34 @@ protected function sanitizeFileName(string $file): string
172172
return ltrim($parsedUrl['path'] ?? $file, './');
173173
}
174174

175+
/**
176+
* Internal function to sanitize the handle based on the file
177+
* by taking into consideration that @vendor can be present.
178+
*
179+
* @example /path/to/script.js -> script
180+
* @example @vendor/script.module.js -> @vendor/script.module
181+
* @example /path/to/@vendor/script.module.js -> @vendor/script.module
182+
*
183+
* @param string $file
184+
*
185+
* @return string
186+
*/
187+
protected function sanitizeHandle(string $file): string
188+
{
189+
$pathInfo = pathinfo($file);
190+
191+
$dirName = $pathInfo['dirname'] ?? '';
192+
$parts = explode('@', $dirName);
193+
$vendor = $parts[1] ?? null;
194+
195+
$handle = $pathInfo['filename'];
196+
if ($vendor !== null) {
197+
$handle = "@{$vendor}/{$handle}";
198+
}
199+
200+
return $handle;
201+
}
202+
175203
/**
176204
* Internal function to resolve a location for a given file name.
177205
*

src/Loader/WebpackManifestLoader.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ protected function parseData(array $data, string $resource): array
1818
$directory = trailingslashit(dirname($resource));
1919
$assets = [];
2020
foreach ($data as $handle => $file) {
21-
if (!self::isModule($file)) {
22-
// It can be possible that the "handle"-key is a filepath.
23-
$handle = pathinfo($handle, PATHINFO_FILENAME);
24-
}
25-
21+
$handle = $this->sanitizeHandle($handle);
2622
$sanitizedFile = $this->sanitizeFileName($file);
2723

2824
$fileUrl = (!$this->directoryUrl)

tests/phpunit/Unit/Loader/WebpackManifestLoaderTest.php

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ public function testLoadFromManifest(
3838
string $expectedHandle,
3939
string $expectedFileName,
4040
string $expectedClass
41-
): void {
42-
41+
): void
42+
{
4343
$expectedDirUrl = 'http://localhost.com/assets/';
44-
$expectedFileUrl = $expectedDirUrl . $expectedFileName;
44+
$expectedFileUrl = $expectedDirUrl . ltrim($expectedFileName, '/');
4545

4646
$loader = new WebpackManifestLoader();
4747
$loader->withDirectoryUrl($expectedDirUrl);
@@ -67,14 +67,17 @@ public function testLoadFromManifestMultipleAssets(): void
6767
'style' => 'style.css',
6868
'module' => 'module.mjs',
6969
'custom-module' => 'custom.module.js',
70+
'@vendor/module' => 'vendor.module.js',
7071
]
7172
);
7273

7374
$loader = new WebpackManifestLoader();
7475
$assets = $loader->load($this->mockManifestJson($json));
7576

76-
static::assertCount(4, $assets);
77+
static::assertCount(5, $assets);
7778

79+
static::assertInstanceOf(ScriptModule::class, $assets[4]);
80+
static::assertInstanceOf(ScriptModule::class, $assets[3]);
7881
static::assertInstanceOf(ScriptModule::class, $assets[2]);
7982
static::assertInstanceOf(Script::class, $assets[0]);
8083
static::assertInstanceOf(Style::class, $assets[1]);
@@ -106,8 +109,8 @@ public function testLoadFromManifestWithAlternativeUrl(
106109
string $json,
107110
string $alternativeUrl,
108111
string $expectedUrl
109-
): void {
110-
112+
): void
113+
{
111114
$loader = new WebpackManifestLoader();
112115
$loader->withDirectoryUrl($alternativeUrl);
113116
$assets = $loader->load($this->mockManifestJson($json));
@@ -201,10 +204,32 @@ public function provideManifest(): \Generator
201204
'sub-folder/script.js',
202205
Script::class,
203206
];
207+
208+
yield 'with @vendor in handle for modules' => [
209+
'{"@vendor/script.module.js": "script.module.js"}',
210+
'@vendor/script.module',
211+
'script.module.js',
212+
ScriptModule::class,
213+
];
214+
215+
yield 'with @vendor in handle for modules and file path' => [
216+
'{"@vendor/script.module.js": "/path/to/script.module.js"}',
217+
'@vendor/script.module',
218+
'/path/to/script.module.js',
219+
ScriptModule::class,
220+
];
221+
222+
yield 'with complex @vendor in handle for modules and file path' => [
223+
'{"path/to/@vendor/script.module.js": "/path/to/script.module.js"}',
224+
'@vendor/script.module',
225+
'/path/to/script.module.js',
226+
ScriptModule::class,
227+
];
204228
}
205229

206230
/**
207231
* @param string $json
232+
*
208233
* @return string
209234
*/
210235
private function mockManifestJson(string $json): string

0 commit comments

Comments
 (0)