[Content collections] Remove experimental flag (#5825)
* refactor: remove experimental.cc from core * chore: remove experimental flag from tests * fix: mock contentDir in remark tests * fix: check vfile.path in rel-image-error plugin * fix: move .astro/ excludes to all test/fixtures * fix: include test/**/fixtures in ignore * chore: changeset
This commit is contained in:
parent
665a2c2225
commit
52209ca2ad
27 changed files with 58 additions and 103 deletions
14
.changeset/thin-beers-drive.md
Normal file
14
.changeset/thin-beers-drive.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
'astro': major
|
||||
'@astrojs/mdx': major
|
||||
'@astrojs/markdown-remark': major
|
||||
---
|
||||
|
||||
Baseline the experimental `contentCollections` flag. You're free to remove this from your astro config!
|
||||
|
||||
```diff
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
export default defineConfig({
|
||||
- experimental: { contentCollections: true }
|
||||
})
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -24,3 +24,7 @@ packages/integrations/**/.netlify/
|
|||
|
||||
# exclude IntelliJ/WebStorm stuff
|
||||
.idea
|
||||
|
||||
# ignore content collection generated files
|
||||
packages/**/test/**/fixtures/**/.astro/
|
||||
packages/**/test/**/fixtures/**/env.d.ts
|
||||
|
|
|
@ -7,7 +7,4 @@ import sitemap from '@astrojs/sitemap';
|
|||
export default defineConfig({
|
||||
site: 'https://example.com',
|
||||
integrations: [mdx(), sitemap()],
|
||||
experimental: {
|
||||
contentCollections: true,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -83,7 +83,6 @@ export interface CLIFlags {
|
|||
port?: number;
|
||||
config?: string;
|
||||
drafts?: boolean;
|
||||
experimentalContentCollections?: boolean;
|
||||
}
|
||||
|
||||
export interface BuildConfig {
|
||||
|
@ -911,34 +910,13 @@ export interface AstroUserConfig {
|
|||
legacy?: object;
|
||||
|
||||
/**
|
||||
* @docs
|
||||
* @kind heading
|
||||
* @name Experimental Flags
|
||||
* @description
|
||||
* Astro offers experimental flags to give users early access to new features.
|
||||
* These flags are not guaranteed to be stable.
|
||||
*/
|
||||
experimental?: {
|
||||
/**
|
||||
* @docs
|
||||
* @name experimental.contentCollections
|
||||
* @type {boolean}
|
||||
* @default `false`
|
||||
* @version 1.7.0
|
||||
* @description
|
||||
* Enable experimental support for [Content Collections](https://docs.astro.build/en/guides/content-collections/). This makes the `src/content/` directory a reserved directory for Astro to manage, and introduces the `astro:content` module for querying this content.
|
||||
*
|
||||
* To enable this feature, set `experimental.contentCollections` to `true` in your Astro config:
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* experimental: {
|
||||
* contentCollections: true,
|
||||
* },
|
||||
* }
|
||||
*/
|
||||
contentCollections?: boolean;
|
||||
};
|
||||
experimental?: object;
|
||||
|
||||
// Legacy options to be removed
|
||||
|
||||
|
|
|
@ -349,7 +349,6 @@ async function generatePath(
|
|||
logging,
|
||||
markdown: {
|
||||
...settings.config.markdown,
|
||||
isExperimentalContentCollections: settings.config.experimental.contentCollections,
|
||||
contentDir: getContentPaths(settings.config).contentDir,
|
||||
},
|
||||
mode: opts.mode,
|
||||
|
|
|
@ -157,8 +157,7 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
|
|||
}),
|
||||
vitePluginPrerender(opts, internals),
|
||||
...(viteConfig.plugins || []),
|
||||
settings.config.experimental.contentCollections &&
|
||||
astroBundleDelayedAssetPlugin({ internals }),
|
||||
astroBundleDelayedAssetPlugin({ internals }),
|
||||
// SSR needs to be last
|
||||
ssr && vitePluginSSR(internals, settings.adapter!),
|
||||
],
|
||||
|
|
|
@ -76,15 +76,13 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
|
|||
// For CSS, create a hash of all of the pages that use it.
|
||||
// This causes CSS to be built into shared chunks when used by multiple pages.
|
||||
if (isCSSRequest(id)) {
|
||||
if (settings.config.experimental.contentCollections) {
|
||||
for (const [pageInfo] of walkParentInfos(id, {
|
||||
getModuleInfo: args[0].getModuleInfo,
|
||||
})) {
|
||||
if (new URL(pageInfo.id, 'file://').searchParams.has(DELAYED_ASSET_FLAG)) {
|
||||
// Split delayed assets to separate modules
|
||||
// so they can be injected where needed
|
||||
return createNameHash(id, [id]);
|
||||
}
|
||||
for (const [pageInfo] of walkParentInfos(id, {
|
||||
getModuleInfo: args[0].getModuleInfo,
|
||||
})) {
|
||||
if (new URL(pageInfo.id, 'file://').searchParams.has(DELAYED_ASSET_FLAG)) {
|
||||
// Split delayed assets to separate modules
|
||||
// so they can be injected where needed
|
||||
return createNameHash(id, [id]);
|
||||
}
|
||||
}
|
||||
return createNameForParentPages(id, args[0]);
|
||||
|
@ -174,17 +172,10 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin[]
|
|||
id,
|
||||
this,
|
||||
function until(importer) {
|
||||
if (settings.config.experimental.contentCollections) {
|
||||
// Short circuit when `contentCollections` is enabled.
|
||||
return new URL(importer, 'file://').searchParams.has(DELAYED_ASSET_FLAG);
|
||||
}
|
||||
return false;
|
||||
return new URL(importer, 'file://').searchParams.has(DELAYED_ASSET_FLAG);
|
||||
}
|
||||
)) {
|
||||
if (
|
||||
settings.config.experimental.contentCollections &&
|
||||
new URL(pageInfo.id, 'file://').searchParams.has(DELAYED_ASSET_FLAG)
|
||||
) {
|
||||
if (new URL(pageInfo.id, 'file://').searchParams.has(DELAYED_ASSET_FLAG)) {
|
||||
for (const parent of walkParentInfos(id, this)) {
|
||||
const parentInfo = parent[0];
|
||||
if (moduleIsTopLevelPage(parentInfo)) {
|
||||
|
|
|
@ -210,7 +210,6 @@ function buildManifest(
|
|||
base: settings.config.base,
|
||||
markdown: {
|
||||
...settings.config.markdown,
|
||||
isExperimentalContentCollections: settings.config.experimental.contentCollections,
|
||||
contentDir: getContentPaths(settings.config).contentDir,
|
||||
},
|
||||
pageMap: null as any,
|
||||
|
|
|
@ -100,10 +100,6 @@ export function resolveFlags(flags: Partial<Flags>): CLIFlags {
|
|||
host:
|
||||
typeof flags.host === 'string' || typeof flags.host === 'boolean' ? flags.host : undefined,
|
||||
drafts: typeof flags.drafts === 'boolean' ? flags.drafts : undefined,
|
||||
experimentalContentCollections:
|
||||
typeof flags.experimentalContentCollections === 'boolean'
|
||||
? flags.experimentalContentCollections
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -132,7 +128,6 @@ function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags) {
|
|||
// TODO: Come back here and refactor to remove this expected error.
|
||||
astroConfig.server.host = flags.host;
|
||||
}
|
||||
if (flags.experimentalContentCollections) astroConfig.experimental.contentCollections = true;
|
||||
return astroConfig;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,9 +34,6 @@ const ASTRO_CONFIG_DEFAULTS: AstroUserConfig & any = {
|
|||
},
|
||||
vite: {},
|
||||
legacy: {},
|
||||
experimental: {
|
||||
contentCollections: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const AstroConfigSchema = z.object({
|
||||
|
@ -167,15 +164,7 @@ export const AstroConfigSchema = z.object({
|
|||
vite: z
|
||||
.custom<ViteUserConfig>((data) => data instanceof Object && !Array.isArray(data))
|
||||
.default(ASTRO_CONFIG_DEFAULTS.vite),
|
||||
experimental: z
|
||||
.object({
|
||||
contentCollections: z
|
||||
.boolean()
|
||||
.optional()
|
||||
.default(ASTRO_CONFIG_DEFAULTS.experimental.contentCollections),
|
||||
})
|
||||
.optional()
|
||||
.default({}),
|
||||
experimental: z.object({}).optional().default({}),
|
||||
legacy: z.object({}).optional().default({}),
|
||||
});
|
||||
|
||||
|
|
|
@ -104,13 +104,9 @@ export async function createVite(
|
|||
astroHeadPropagationPlugin({ settings }),
|
||||
astroScannerPlugin({ settings, logging }),
|
||||
astroInjectEnvTsPlugin({ settings, logging, fs }),
|
||||
...(settings.config.experimental.contentCollections
|
||||
? [
|
||||
astroContentVirtualModPlugin({ settings }),
|
||||
astroContentServerPlugin({ fs, settings, logging, mode }),
|
||||
astroDelayedAssetPlugin({ mode }),
|
||||
]
|
||||
: []),
|
||||
astroContentVirtualModPlugin({ settings }),
|
||||
astroContentServerPlugin({ fs, settings, logging, mode }),
|
||||
astroDelayedAssetPlugin({ mode }),
|
||||
],
|
||||
publicDir: fileURLToPath(settings.config.publicDir),
|
||||
root: fileURLToPath(settings.config.root),
|
||||
|
|
|
@ -24,7 +24,6 @@ export function createDevelopmentEnvironment(
|
|||
logging,
|
||||
markdown: {
|
||||
...settings.config.markdown,
|
||||
isExperimentalContentCollections: settings.config.experimental.contentCollections,
|
||||
contentDir: getContentPaths(settings.config).contentDir,
|
||||
},
|
||||
mode,
|
||||
|
|
|
@ -71,7 +71,6 @@ export default function markdown({ settings, logging }: AstroPluginOptions): Plu
|
|||
const renderResult = await renderMarkdown(raw.content, {
|
||||
...settings.config.markdown,
|
||||
fileURL: new URL(`file://${fileId}`),
|
||||
isExperimentalContentCollections: settings.config.experimental.contentCollections,
|
||||
contentDir: getContentPaths(settings.config).contentDir,
|
||||
frontmatter: raw.data,
|
||||
});
|
||||
|
|
2
packages/astro/test/fixtures/.gitignore
vendored
2
packages/astro/test/fixtures/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
.astro/
|
||||
env.d.ts
|
|
@ -4,7 +4,4 @@ import mdx from '@astrojs/mdx';
|
|||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [mdx()],
|
||||
experimental: {
|
||||
contentCollections: true,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -4,7 +4,4 @@ import mdx from '@astrojs/mdx';
|
|||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [mdx()],
|
||||
experimental: {
|
||||
contentCollections: true,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -4,7 +4,4 @@ import mdx from '@astrojs/mdx';
|
|||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
integrations: [mdx()],
|
||||
experimental: {
|
||||
contentCollections: true,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -3,5 +3,4 @@ import mdx from '@astrojs/mdx';
|
|||
|
||||
export default defineConfig({
|
||||
integrations: [mdx()],
|
||||
experimental: { contentCollections: true },
|
||||
});
|
||||
|
|
|
@ -47,7 +47,6 @@ describe('Content Collections - render()', () => {
|
|||
userConfig: {
|
||||
integrations: [mdx()],
|
||||
vite: { server: { middlewareMode: true } },
|
||||
experimental: { contentCollections: true },
|
||||
},
|
||||
},
|
||||
async (container) => {
|
||||
|
@ -121,7 +120,6 @@ describe('Content Collections - render()', () => {
|
|||
userConfig: {
|
||||
integrations: [mdx()],
|
||||
vite: { server: { middlewareMode: true } },
|
||||
experimental: { contentCollections: true },
|
||||
},
|
||||
},
|
||||
async (container) => {
|
||||
|
@ -193,7 +191,6 @@ describe('Content Collections - render()', () => {
|
|||
userConfig: {
|
||||
integrations: [mdx()],
|
||||
vite: { server: { middlewareMode: true } },
|
||||
experimental: { contentCollections: true },
|
||||
},
|
||||
},
|
||||
async (container) => {
|
||||
|
@ -259,7 +256,6 @@ describe('Content Collections - render()', () => {
|
|||
userConfig: {
|
||||
integrations: [mdx()],
|
||||
vite: { server: { middlewareMode: true } },
|
||||
experimental: { contentCollections: true },
|
||||
},
|
||||
},
|
||||
async (container) => {
|
||||
|
|
|
@ -161,9 +161,8 @@ export async function getRemarkPlugins(
|
|||
remarkPlugins = [...remarkPlugins, ...ignoreStringPlugins(mdxOptions.remarkPlugins)];
|
||||
|
||||
// Apply last in case user plugins resolve relative image paths
|
||||
if (config.experimental.contentCollections) {
|
||||
remarkPlugins.push(toRemarkContentRelImageError(config));
|
||||
}
|
||||
remarkPlugins.push(toRemarkContentRelImageError(config));
|
||||
|
||||
return remarkPlugins;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ export async function renderMarkdown(
|
|||
remarkRehype = markdownConfigDefaults.remarkRehype,
|
||||
gfm = markdownConfigDefaults.gfm,
|
||||
smartypants = markdownConfigDefaults.smartypants,
|
||||
isExperimentalContentCollections = false,
|
||||
contentDir,
|
||||
frontmatter: userFrontmatter = {},
|
||||
} = opts;
|
||||
|
@ -91,9 +90,7 @@ export async function renderMarkdown(
|
|||
}
|
||||
|
||||
// Apply later in case user plugins resolve relative image paths
|
||||
if (isExperimentalContentCollections) {
|
||||
parser.use([toRemarkContentRelImageError({ contentDir })]);
|
||||
}
|
||||
parser.use([toRemarkContentRelImageError({ contentDir })]);
|
||||
|
||||
parser.use([
|
||||
[
|
||||
|
|
|
@ -10,6 +10,8 @@ import type { VFile } from 'vfile';
|
|||
export default function toRemarkContentRelImageError({ contentDir }: { contentDir: URL }) {
|
||||
return function remarkContentRelImageError() {
|
||||
return (tree: any, vfile: VFile) => {
|
||||
if (typeof vfile?.path !== 'string') return;
|
||||
|
||||
const isContentFile = pathToFileURL(vfile.path).href.startsWith(contentDir.href);
|
||||
if (!isContentFile) return;
|
||||
|
||||
|
|
|
@ -59,8 +59,6 @@ export interface MarkdownRenderingOptions extends AstroMarkdownOptions {
|
|||
scopedClassName: string | null;
|
||||
};
|
||||
/** Used to prevent relative image imports from `src/content/` */
|
||||
isExperimentalContentCollections?: boolean;
|
||||
/** Used to prevent relative image imports from `src/content/` */
|
||||
contentDir: URL;
|
||||
/** Used for frontmatter injection plugins */
|
||||
frontmatter?: Record<string, any>;
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import { renderMarkdown } from '../dist/index.js';
|
||||
import chai from 'chai';
|
||||
import { mockRenderMarkdownParams } from './test-utils.js';
|
||||
|
||||
describe('autolinking', () => {
|
||||
describe('plain md', () => {
|
||||
it('autolinks URLs starting with a protocol in plain text', async () => {
|
||||
const { code } = await renderMarkdown(`See https://example.com for more.`, {});
|
||||
const { code } = await renderMarkdown(
|
||||
`See https://example.com for more.`,
|
||||
mockRenderMarkdownParams
|
||||
);
|
||||
|
||||
chai
|
||||
.expect(code.replace(/\n/g, ''))
|
||||
|
@ -12,7 +16,10 @@ describe('autolinking', () => {
|
|||
});
|
||||
|
||||
it('autolinks URLs starting with "www." in plain text', async () => {
|
||||
const { code } = await renderMarkdown(`See www.example.com for more.`, {});
|
||||
const { code } = await renderMarkdown(
|
||||
`See www.example.com for more.`,
|
||||
mockRenderMarkdownParams
|
||||
);
|
||||
|
||||
chai
|
||||
.expect(code.trim())
|
||||
|
@ -22,7 +29,7 @@ describe('autolinking', () => {
|
|||
it('does not autolink URLs in code blocks', async () => {
|
||||
const { code } = await renderMarkdown(
|
||||
'See `https://example.com` or `www.example.com` for more.',
|
||||
{}
|
||||
mockRenderMarkdownParams
|
||||
);
|
||||
|
||||
chai
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import { renderMarkdown } from '../dist/index.js';
|
||||
import { expect } from 'chai';
|
||||
import { mockRenderMarkdownParams } from './test-utils.js';
|
||||
|
||||
describe('entities', () => {
|
||||
it('should not unescape entities in regular Markdown', async () => {
|
||||
const { code } = await renderMarkdown(`<i>This should NOT be italic</i>`, {});
|
||||
const { code } = await renderMarkdown(
|
||||
`<i>This should NOT be italic</i>`,
|
||||
mockRenderMarkdownParams
|
||||
);
|
||||
|
||||
expect(code).to.equal(`<p><i>This should NOT be italic</i></p>`);
|
||||
});
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { renderMarkdown } from '../dist/index.js';
|
||||
import { mockRenderMarkdownParams } from './test-utils.js';
|
||||
import chai from 'chai';
|
||||
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
@ -8,6 +9,7 @@ describe('plugins', () => {
|
|||
it('should be able to get file path when passing fileURL', async () => {
|
||||
let context;
|
||||
await renderMarkdown(`test`, {
|
||||
...mockRenderMarkdownParams,
|
||||
fileURL: new URL('virtual.md', import.meta.url),
|
||||
remarkPlugins: [
|
||||
function () {
|
||||
|
|
3
packages/markdown/remark/test/test-utils.js
Normal file
3
packages/markdown/remark/test/test-utils.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export const mockRenderMarkdownParams = {
|
||||
contentDir: new URL('file:///src/content/'),
|
||||
};
|
Loading…
Reference in a new issue