Expose file
and url
for Astro files (#3385)
* feat: update test * feat: return `file` and `url` for astro files * chore: add changeset * fix: use private names $$file and $$url * test: update markdown test * chore: update fileId logic to strip query params
This commit is contained in:
parent
a7480452b1
commit
d34859d750
8 changed files with 61 additions and 14 deletions
5
.changeset/quiet-pumpkins-hunt.md
Normal file
5
.changeset/quiet-pumpkins-hunt.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Expose `file` and `url` properties when fetching `.astro` files with `Astro.glob()`
|
|
@ -216,7 +216,7 @@ export interface AstroGlobalPartial {
|
|||
*
|
||||
* [Astro reference](https://docs.astro.build/en/reference/api-reference/#astroglob)
|
||||
*/
|
||||
glob(globStr: `${any}.astro`): Promise<ComponentInstance[]>;
|
||||
glob(globStr: `${any}.astro`): Promise<AstroInstance[]>;
|
||||
glob<T extends Record<string, any>>(globStr: `${any}.md`): Promise<MarkdownInstance<T>[]>;
|
||||
glob<T extends Record<string, any>>(globStr: string): Promise<T[]>;
|
||||
/**
|
||||
|
@ -752,6 +752,12 @@ export interface ComponentInstance {
|
|||
getStaticPaths?: (options: GetStaticPathsOptions) => GetStaticPathsResult;
|
||||
}
|
||||
|
||||
export interface AstroInstance {
|
||||
file: string;
|
||||
url: string | undefined;
|
||||
default: AstroComponentFactory;
|
||||
}
|
||||
|
||||
export interface MarkdownInstance<T extends Record<string, any>> {
|
||||
frontmatter: T;
|
||||
file: string;
|
||||
|
|
|
@ -14,6 +14,7 @@ import ancestor from 'common-ancestor-path';
|
|||
import { trackCSSDependencies, handleHotUpdate } from './hmr.js';
|
||||
import { isRelativePath, startsWithForwardSlash } from '../core/path.js';
|
||||
import { PAGE_SCRIPT_ID, PAGE_SSR_SCRIPT_ID } from '../vite-plugin-scripts/index.js';
|
||||
import { getFileInfo } from '../vite-plugin-utils/index.js';
|
||||
import { resolvePages } from '../core/util.js';
|
||||
|
||||
const FRONTMATTER_PARSE_REGEXP = /^\-\-\-(.*)^\-\-\-/ms;
|
||||
|
@ -168,6 +169,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
|
|||
|
||||
try {
|
||||
const transformResult = await cachedCompilation(compileProps);
|
||||
const { fileId: file, fileUrl: url } = getFileInfo(id, config);
|
||||
|
||||
// Compile all TypeScript to JavaScript.
|
||||
// Also, catches invalid JS/TS in the compiled output before returning.
|
||||
|
@ -180,6 +182,7 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu
|
|||
});
|
||||
|
||||
let SUFFIX = '';
|
||||
SUFFIX += `\nconst $$file = ${JSON.stringify(file)};\nconst $$url = ${JSON.stringify(url)};export { $$file as file, $$url as url };\n`;
|
||||
// Add HMR handling in dev mode.
|
||||
if (!resolvedConfig.isProduction) {
|
||||
// HACK: extract dependencies from metadata until compiler static extraction handles them
|
||||
|
|
|
@ -9,8 +9,9 @@ import type { Plugin } from 'vite';
|
|||
import type { AstroConfig } from '../@types/astro';
|
||||
import { PAGE_SSR_SCRIPT_ID } from '../vite-plugin-scripts/index.js';
|
||||
import { pagesVirtualModuleId } from '../core/app/index.js';
|
||||
import { appendForwardSlash, prependForwardSlash } from '../core/path.js';
|
||||
import { prependForwardSlash } from '../core/path.js';
|
||||
import { resolvePages, viteID } from '../core/util.js';
|
||||
import { getFileInfo } from '../vite-plugin-utils/index.js';
|
||||
|
||||
interface AstroPluginOptions {
|
||||
config: AstroConfig;
|
||||
|
@ -78,17 +79,7 @@ export default function markdown({ config }: AstroPluginOptions): Plugin {
|
|||
// Return the file's JS representation, including all Markdown
|
||||
// frontmatter and a deferred `import() of the compiled markdown content.
|
||||
if (id.endsWith(`.md${MARKDOWN_IMPORT_FLAG}`)) {
|
||||
const sitePathname = appendForwardSlash(
|
||||
config.site ? new URL(config.base, config.site).pathname : config.base
|
||||
);
|
||||
|
||||
const fileId = id.replace(MARKDOWN_IMPORT_FLAG, '');
|
||||
let fileUrl = fileId.includes('/pages/')
|
||||
? fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(\/index)?\.md$/, '')
|
||||
: undefined;
|
||||
if (fileUrl && config.trailingSlash === 'always') {
|
||||
fileUrl = appendForwardSlash(fileUrl);
|
||||
}
|
||||
const { fileId, fileUrl } = getFileInfo(id, config);
|
||||
|
||||
const source = await fs.promises.readFile(fileId, 'utf8');
|
||||
const { data: frontmatter } = matter(source);
|
||||
|
|
17
packages/astro/src/vite-plugin-utils/index.ts
Normal file
17
packages/astro/src/vite-plugin-utils/index.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import type { AstroConfig } from '../@types/astro';
|
||||
import { appendForwardSlash } from '../core/path.js';
|
||||
|
||||
export function getFileInfo(id: string, config: AstroConfig) {
|
||||
const sitePathname = appendForwardSlash(
|
||||
config.site ? new URL(config.base, config.site).pathname : config.base
|
||||
);
|
||||
|
||||
const fileId = id.split('?')[0];
|
||||
let fileUrl = fileId.includes('/pages/')
|
||||
? fileId.replace(/^.*?\/pages\//, sitePathname).replace(/(\/index)?\.(md|astro)$/, '')
|
||||
: undefined;
|
||||
if (fileUrl && config.trailingSlash === 'always') {
|
||||
fileUrl = appendForwardSlash(fileUrl);
|
||||
}
|
||||
return { fileId, fileUrl };
|
||||
}
|
|
@ -2,7 +2,7 @@ import { expect } from 'chai';
|
|||
import * as cheerio from 'cheerio';
|
||||
import { loadFixture } from './test-utils.js';
|
||||
|
||||
describe('Astro.*', () => {
|
||||
describe('Astro Global', () => {
|
||||
let fixture;
|
||||
|
||||
before(async () => {
|
||||
|
@ -76,5 +76,12 @@ describe('Astro.*', () => {
|
|||
const $ = cheerio.load(html);
|
||||
expect($('.post-url').attr('href')).to.equal('/blog/post/post-2');
|
||||
});
|
||||
|
||||
it('Astro.glob() correctly returns meta info for MD and Astro files', async () => {
|
||||
const html = await fixture.readFile('/glob/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
expect($('[data-file]').length).to.equal(3);
|
||||
expect($('.post-url[href]').length).to.equal(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
17
packages/astro/test/fixtures/astro-global/src/pages/glob.astro
vendored
Normal file
17
packages/astro/test/fixtures/astro-global/src/pages/glob.astro
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
const data = await Astro.glob('./post/**/*');
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>All Posts</title>
|
||||
</head>
|
||||
<body>
|
||||
{data.map((page: any) => (
|
||||
<div>
|
||||
<h1 data-file={page.file} />Title</h1>
|
||||
<a class="post-url" href={page.url}>Read</a>
|
||||
</div>
|
||||
))}
|
||||
</body>
|
||||
</html>
|
1
packages/astro/test/fixtures/astro-global/src/pages/post/post-3.astro
vendored
Normal file
1
packages/astro/test/fixtures/astro-global/src/pages/post/post-3.astro
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
<h1>Post 3</h1>
|
Loading…
Reference in a new issue