Skip to content

Commit

Permalink
offsets fixed + dox
Browse files Browse the repository at this point in the history
  • Loading branch information
dakujem committed Jan 2, 2023
1 parent f5145c5 commit 43d89c7
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 9 deletions.
26 changes: 23 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ then replace the previous snippet with this one (replace `my-js-widget` with a p
```
It should produce `<script>` and `<link>` tags for your JS and CSS.\
Pay attention to the path to the manifest file, as it will change according to where you run the snippet from. Adjust as needed.\
Understand that `'./my-js-widget/manifest.json'` is a server path, while `'/my-js-widget'` is a URL prefix of the assets
(that is, where you moved the dist files to, relative to the PHP script in your public root).
Understand that `'./my-js-widget/manifest.json'` is a server path, while `'/my-js-widget'` is part of a URL prefixing the assets
(that is, where you moved the dist files to, relative to the PHP script in your public root).\
Also note that '/my-js-widget' is absolute, you may need to add your project's base path or use relative offsets (see below).

Once this works, I suggest you move on to configure the bridge service (see below).

Expand Down Expand Up @@ -135,7 +136,7 @@ Configure `ViteBridge` service along these lines:
$bridgeService = new ViteBridge(
manifestFile: ROOT_DIR . '/public/my-js-widget/manifest.json',
cacheFile: TEMP_DIR . '/vite.php', // can be any writable file
assetPathPrefix: 'my-js-widget', // all asset paths from the manifest will be prefixed by this value
assetPathPrefix: '/my-js-widget', // all asset paths from the manifest will be prefixed by this value
devServerUrl: 'http://localhost:5173',
);
```
Expand Down Expand Up @@ -207,6 +208,25 @@ as one of the build steps during the deployment/CI process.
> or include the cache file in your cache-purging process.

## Handling relative paths

So far we used **absolute paths** to the assets. Which is **recommended**.

> 💡
>
> The `assetPathPrefix` should contain the **project's base path** plus path to the manifest file and should be absolute.
However, if you need to use relative paths, you are able to.

`ViteLocatorContract::entry` method accepts second parameter called **"relative offset"**,
which is designed for cases where `assetPathPrefix` needs to be prefixed per-call.

The parameter should be used in scripts that are not located in public document root.\
The parameter should typically contain strings like `..`, `../..`, etc. leading to the public root.

Do not use this parameter when using absolute paths, as it will break the generated URIs.


## Advanced use

Instead of using `ViteBridge::makePassiveEntryLocator` friction reducer,
Expand Down
6 changes: 3 additions & 3 deletions src/ViteBuildLocator.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@ public function entry(string $name, ?string $relativeOffset = null): ?ViteEntryA

private function buildPath(string $asset, ?string $relativeOffset = null): string
{
$base = $this->assetPathPrefix;
$basePrefix = $this->assetPathPrefix;
if ($relativeOffset !== null && $relativeOffset !== '') {
$relativeOffset = ($base !== '' && $base !== '/' ? '/' : '') . trim($relativeOffset, '/') . '/';
$relativeOffset = rtrim($relativeOffset, '/') . '/';
}
return $base . $relativeOffset . $asset;
return $relativeOffset . $basePrefix . $asset;
}

/**
Expand Down
8 changes: 5 additions & 3 deletions src/ViteHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,19 @@ final class ViteHelper
*
* @param string $entryName typically `main.js`
* @param string $manifestFile server path to Vite-generated manifest file
* @param string $assetPathPrefix relative path from your document root (/public, /www, /web, etc.) to the dir where the manifest file is located
* @param string $assetPathPrefix absolute or relative path from your document root (/public, /www, /web, etc.) to the dir where the manifest file is located
* @param string|null $relativeOffset offset of the current script to the public root; this value comes before $assetPathPrefix and is used when $assetPathPrefix contains a relative path
* @return ViteEntryAsset
*/
public static function extractAssets(
string $entryName,
string $manifestFile,
string $assetPathPrefix = ''
string $assetPathPrefix = '',
?string $relativeOffset = null
): ViteEntryAsset {
$bridgeService = new ViteBridge($manifestFile, null, $assetPathPrefix);
$locator = $bridgeService->makePassiveEntryLocator();
$entry = $locator->entry($entryName);
$entry = $locator->entry($entryName, $relativeOffset);
if ($entry === null) {
throw new RuntimeException(sprintf('Vite entry named %s not found in given manifest located at %s.', $entryName, $manifestFile));
}
Expand Down
56 changes: 56 additions & 0 deletions tests/ViteBridge.default.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,62 @@ class _DefaultExampleViteBridgeTest extends TestCase
);
}

public function testDevelopmentServerLocatorWithOffset()
{
$bridgeService = $this->getBridgeService();
$locator = $bridgeService->makePassiveEntryLocator(true);

// main entry (offsets are ignored)
$assets = $locator->entry('main.js', '../..');
Assert::notNull($assets, 'Server locator not working');
Assert::same(
'<script type="module" src="http://localhost:5173/@vite/client"></script>' .
"\n" .
'<script type="module" src="http://localhost:5173/main.js"></script>',
(string)$assets,
'Localhost url of dev server not provided',
);

// secondary entry (offsets are ignored)
$assets = $locator->entry('views/foo.js', '../..');
Assert::notNull($assets, 'Server locator not working');
Assert::same(
'<script type="module" src="http://localhost:5173/@vite/client"></script>' .
"\n" .
'<script type="module" src="http://localhost:5173/views/foo.js"></script>',
(string)$assets,
'Localhost url of dev server not provided',
);
}

public function testBundleLocatorWithOffset()
{
$bridgeService = $this->getBridgeService();
$locator = $bridgeService->makePassiveEntryLocator(false);

// main entry
$assets = $locator->entry('main.js', '../..');
Assert::notNull($assets, 'Build locator not working');
Assert::same(
'<script type="module" src="../../my-js-widget/assets/main.4889e940.js"></script>' .
"\n" .
'<link rel="stylesheet" href="../../my-js-widget/assets/main.b82dbe22.css" />',
(string)$assets,
'Bundle asset URLs don\'t work',
);

// secondary entry
$assets = $locator->entry('views/foo.js', '../..');
Assert::notNull($assets, 'Build locator not working');
Assert::same(
'<script type="module" src="../../my-js-widget/assets/foo.869aea0d.js"></script>' .
"\n" .
'<script type="module" src="../../my-js-widget/assets/shared.83069a53.js"></script>',
(string)$assets,
'Bundle asset URLs don\'t work',
);
}

private function getBridgeService()
{
return new ViteBridge(
Expand Down

0 comments on commit 43d89c7

Please sign in to comment.