diff options
author | 2023-03-27 18:04:37 -0400 | |
---|---|---|
committer | 2023-03-27 18:04:37 -0400 | |
commit | 7c439868a3bc7d466418da9af669966014f3d9fe (patch) | |
tree | af8a8624a96ed9988f475beaed840df28d864646 /packages/integrations/markdoc/src/load-config.ts | |
parent | c13d428a7804b5b9809dbea94a1b17c36714a1e1 (diff) | |
download | astro-7c439868a3bc7d466418da9af669966014f3d9fe.tar.gz astro-7c439868a3bc7d466418da9af669966014f3d9fe.tar.zst astro-7c439868a3bc7d466418da9af669966014f3d9fe.zip |
[Markdoc] New config format with runtime variable support! (#6653)
* deps: esbuild
* feat: support direct component imports for render!
* deps: add devalue back
* refactor: remove unused components prop
* refactor: load experimental assets config separately
* fix: upate Content type def to support props
* refactor: replace astro stub with inline data
* feat: pass through viteId to getRenderMod
* fix: add back $entry var with defaults convention
* chore: remove unneeded validateRenderProps
* chore: remove uneeded validateComponents
* fix: remove userMarkdocConfig prop
* chore: add helpful error for legacy config
* deps: kleur
* fix: add back `isCapitalized`
* fix: log instead of throw to avoid scary stacktrace
* chore: delete more old logic (nice)
* chore: delete MORE unused utils
* chore: comment on separate assets config
* chore: remove console.log
* chore: general code cleanup
* test: new render config
* docs: new README
* fix: add expect-error on astro:assets
* feat: add defineMarkdocConfig helper
* docs: update example README
* test: add runtime variable
* chore: lint
* chore: changeset
* chore: add component import deletion
* docs: add notes on Vite fork
* fix: astro check
* chore: add `.mts` to markdoc config formats
Diffstat (limited to 'packages/integrations/markdoc/src/load-config.ts')
-rw-r--r-- | packages/integrations/markdoc/src/load-config.ts | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/packages/integrations/markdoc/src/load-config.ts b/packages/integrations/markdoc/src/load-config.ts new file mode 100644 index 000000000..db36edf25 --- /dev/null +++ b/packages/integrations/markdoc/src/load-config.ts @@ -0,0 +1,102 @@ +import type { AstroConfig } from 'astro'; +import type { Config as MarkdocConfig } from '@markdoc/markdoc'; +import { build as esbuild } from 'esbuild'; +import { fileURLToPath } from 'node:url'; +import * as fs from 'node:fs'; + +const SUPPORTED_MARKDOC_CONFIG_FILES = [ + 'markdoc.config.js', + 'markdoc.config.mjs', + 'markdoc.config.mts', + 'markdoc.config.ts', +]; + +export async function loadMarkdocConfig(astroConfig: Pick<AstroConfig, 'root'>) { + let markdocConfigUrl: URL | undefined; + for (const filename of SUPPORTED_MARKDOC_CONFIG_FILES) { + const filePath = new URL(filename, astroConfig.root); + if (!fs.existsSync(filePath)) continue; + + markdocConfigUrl = filePath; + break; + } + if (!markdocConfigUrl) return; + + const { code, dependencies } = await bundleConfigFile({ + markdocConfigUrl, + astroConfig, + }); + const config: MarkdocConfig = await loadConfigFromBundledFile(astroConfig.root, code); + + return { + config, + fileUrl: markdocConfigUrl, + }; +} + +/** + * Forked from Vite's `bundleConfigFile` function + * with added handling for `.astro` imports, + * and removed unused Deno patches. + * @see https://github.com/vitejs/vite/blob/main/packages/vite/src/node/config.ts#L961 + */ +async function bundleConfigFile({ + markdocConfigUrl, + astroConfig, +}: { + markdocConfigUrl: URL; + astroConfig: Pick<AstroConfig, 'root'>; +}): Promise<{ code: string; dependencies: string[] }> { + const result = await esbuild({ + absWorkingDir: fileURLToPath(astroConfig.root), + entryPoints: [fileURLToPath(markdocConfigUrl)], + outfile: 'out.js', + write: false, + target: ['node16'], + platform: 'node', + packages: 'external', + bundle: true, + format: 'esm', + sourcemap: 'inline', + metafile: true, + plugins: [ + { + name: 'stub-astro-imports', + setup(build) { + build.onResolve({ filter: /.*\.astro$/ }, () => { + return { + // Stub with an unused default export + path: 'data:text/javascript,export default true', + external: true, + }; + }); + }, + }, + ], + }); + const { text } = result.outputFiles[0]; + return { + code: text, + dependencies: result.metafile ? Object.keys(result.metafile.inputs) : [], + }; +} + +/** + * Forked from Vite config loader, replacing CJS-based path concat + * with ESM only + * @see https://github.com/vitejs/vite/blob/main/packages/vite/src/node/config.ts#L1074 + */ +async function loadConfigFromBundledFile(root: URL, code: string): Promise<MarkdocConfig> { + // Write it to disk, load it with native Node ESM, then delete the file. + const tmpFileUrl = new URL(`markdoc.config.timestamp-${Date.now()}.mjs`, root); + fs.writeFileSync(tmpFileUrl, code); + try { + return (await import(tmpFileUrl.pathname)).default; + } finally { + try { + fs.unlinkSync(tmpFileUrl); + } catch { + // already removed if this function is called twice simultaneously + } + } +} |