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:
Nate Moore 2022-05-19 10:49:14 -05:00 committed by GitHub
parent a7480452b1
commit d34859d750
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 61 additions and 14 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Expose `file` and `url` properties when fetching `.astro` files with `Astro.glob()`

View file

@ -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;

View file

@ -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

View file

@ -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);

View 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 };
}

View file

@ -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);
});
});
});

View 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>

View file

@ -0,0 +1 @@
<h1>Post 3</h1>