fix(engine): support fragments when adjusting urls

This commit is contained in:
Thomas Allmer
2022-08-21 10:57:55 +02:00
parent 57ec19fecc
commit 0ed3d6d0e9
5 changed files with 85 additions and 11 deletions

View File

@@ -0,0 +1,16 @@
---
'@rocket/engine': patch
---
Adjust urls containing url fragments
```html
<!-- user writes -->
<a href="./about.rocket.js#some-id"></a>
<!-- rocket outputs -->
<!-- before -->
<a href="./about.rocket.js#some-id"></a>
<!-- after -->
<a href="/about/#some-id"></a>
```

View File

@@ -19,32 +19,39 @@ import { parser, SaxEventType } from '../web-menu/sax-parser.js';
* @returns
*/
async function defaultAdjustAssetUrl({
url,
url: fullUrl,
sourceFilePath,
sourceRelativeFilePath,
outputFilePath,
}) {
let url = fullUrl;
let fragment = '';
if (!url.startsWith('resolve:#') && url.includes('#')) {
const urlParts = url.split('#');
url = urlParts[0];
fragment = `#${urlParts[1]}`;
}
if (url.startsWith('resolve:')) {
const bareImport = url.substring(8);
const requireOfSource = createRequire(sourceFilePath);
const resolvedPath = requireOfSource.resolve(bareImport);
const rel = path.relative(path.dirname(outputFilePath), resolvedPath);
return rel;
return rel + fragment;
}
if (url.match(/^[a-z]+:/) || url.startsWith('//')) {
return url;
return url + fragment;
}
if (isRocketPageFile(url)) {
const dir = path.dirname(sourceRelativeFilePath);
return sourceRelativeFilePathToUrl(path.join(dir, url));
return sourceRelativeFilePathToUrl(path.join(dir, url)) + fragment;
}
if (url.startsWith('./') || url.startsWith('../')) {
return path.relative(
path.dirname(outputFilePath),
path.join(path.dirname(sourceFilePath), url),
return (
path.relative(path.dirname(outputFilePath), path.join(path.dirname(sourceFilePath), url)) +
fragment
);
}
return url;
return url + fragment;
}
export class AdjustAssetUrls {

View File

@@ -1,5 +1,6 @@
import chai from 'chai';
import { AdjustAssetUrls } from '@rocket/engine';
import { expectThrowsAsync } from './test-helpers.js';
const { expect } = chai;
@@ -48,7 +49,7 @@ describe('AdjustAssetUrls', () => {
);
});
it('ignores <a href="#foo"></a>', async () => {
it('does not adjust <a href="#foo"></a>', async () => {
const adjust = new AdjustAssetUrls();
expect(await adjust.transform('<a href="#foo">go</a>', options)).to.equal(
'<a href="#foo">go</a>',
@@ -104,4 +105,43 @@ describe('AdjustAssetUrls', () => {
}),
).to.equal('<a href="/">go</a>');
});
it('adjust <a href="./about.rocket.js#some-id"></a>', async () => {
const adjust = new AdjustAssetUrls();
expect(await adjust.transform('<a href="./about.rocket.js#some-id">go</a>', options)).to.equal(
'<a href="/about/#some-id">go</a>',
);
expect(
await adjust.transform('<a href="./about.rocket.js#some-id">go</a>', {
sourceRelativeFilePath: 'components/index.rocket.js',
outputFilePath: '/my/path/to/__output/components/index.html',
}),
).to.equal('<a href="/components/about/#some-id">go</a>');
expect(
await adjust.transform('<a href="./about.rocket.js#some-id">go</a>', {
sourceRelativeFilePath: 'components.rocket.js',
outputFilePath: '/my/path/to/__output/components/index.html',
}),
).to.equal('<a href="/about/#some-id">go</a>');
expect(
await adjust.transform('<a href="./index.rocket.js#some-id">go</a>', {
sourceRelativeFilePath: 'about.rocket.js',
outputFilePath: '/my/path/to/__output/about/index.html',
}),
).to.equal('<a href="/#some-id">go</a>');
});
it('still resolves private imports <img src="resolve:#src/logo.svg" />', async () => {
const adjust = new AdjustAssetUrls();
// we check for the resolve throw as this private import does not exists =>
// which means if a not resolve related error in our code happens the test fails
await expectThrowsAsync(
() => adjust.transform('<img src="resolve:#src/logo.svg" />', options),
{
errorMatch: /Cannot find module '#src\/logo\.svg'/,
},
);
});
});

View File

@@ -13,6 +13,17 @@ const { expect } = chai;
const __dirname = path.dirname(fileURLToPath(import.meta.url));
/**
* Expect a throw in an async function
*
* @example
* await expectThrowsAsync(() => myAsyncFunction(), {
* errorMatch: /exact throw message/,
* });
* @example
* await expectThrowsAsync(() => myAsyncFunction(), {
* errorMatch: /check throw message with a regex/,
* });
*
* @param {function} method
* @param {string} errorMessage
*/

View File

@@ -81,7 +81,7 @@ You write modern JavaScript using the latest browser features. Rollup will optim
Our config sets you up with good defaults for most projects. Additionally you can add more plugins and adjust predefined plugins or even remove them if needed.
We use the [plugins-manager](./plugins-manager.md) for it.
We use the [plugins-manager](../10--plugins-manager/10--overview.rocket.md) for it.
### Customizing the Babel Config
@@ -112,7 +112,7 @@ SPA and MPA plugins:
- [polyfills-loader](https://modern-web.dev/docs/building/rollup-plugin-polyfills-loader/)
- [workbox](https://www.npmjs.com/package/rollup-plugin-workbox)
You can customize options for these plugins by using [adjustPluginOptions](./plugins-manager.md#adjusting-plugin-options).
You can customize options for these plugins by using [adjustPluginOptions](../10--plugins-manager/10--overview.rocket.md#adjusting-plugin-options).
```js
import { createSpaConfig } from '@rocket/building-rollup';