From ca01a71eb0937eae3ddc34d48396df8161e830db Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Thu, 1 Dec 2022 00:00:13 +0800 Subject: [PATCH] Refactor internal plugins code (#5497) * Share normalizeFilename * Simplify types * Remove unused imports variable * Update README * Add changeset --- .changeset/tall-goats-knock.md | 5 +++ packages/astro/src/vite-plugin-astro/index.ts | 35 +++++++------------ packages/astro/src/vite-plugin-env/README.md | 9 ++--- packages/astro/src/vite-plugin-html/README.md | 3 ++ .../src/vite-plugin-html/transform/index.ts | 9 ----- .../src/vite-plugin-load-fallback/README.md | 3 ++ .../src/vite-plugin-markdown-legacy/index.ts | 14 ++------ .../astro/src/vite-plugin-markdown/README.md | 4 +-- .../astro/src/vite-plugin-scripts/README.md | 3 ++ .../astro/src/vite-plugin-scripts/page-ssr.ts | 13 ++----- packages/astro/src/vite-plugin-utils/index.ts | 18 ++++++++++ 11 files changed, 54 insertions(+), 62 deletions(-) create mode 100644 .changeset/tall-goats-knock.md create mode 100644 packages/astro/src/vite-plugin-html/README.md create mode 100644 packages/astro/src/vite-plugin-load-fallback/README.md create mode 100644 packages/astro/src/vite-plugin-scripts/README.md diff --git a/.changeset/tall-goats-knock.md b/.changeset/tall-goats-knock.md new file mode 100644 index 000000000..55b63e567 --- /dev/null +++ b/.changeset/tall-goats-knock.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Refactor internal plugins code diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts index f81266846..59aea73a0 100644 --- a/packages/astro/src/vite-plugin-astro/index.ts +++ b/packages/astro/src/vite-plugin-astro/index.ts @@ -1,10 +1,9 @@ -import type { PluginContext, SourceDescription } from 'rollup'; +import type { SourceDescription } from 'rollup'; import type * as vite from 'vite'; import type { AstroSettings } from '../@types/astro'; import type { LogOptions } from '../core/logger/core.js'; import type { PluginMetadata as AstroPluginMetadata } from './types'; -import ancestor from 'common-ancestor-path'; import esbuild from 'esbuild'; import slash from 'slash'; import { fileURLToPath } from 'url'; @@ -16,7 +15,7 @@ import { startsWithForwardSlash, } from '../core/path.js'; import { viteID } from '../core/util.js'; -import { getFileInfo } from '../vite-plugin-utils/index.js'; +import { getFileInfo, normalizeFilename } from '../vite-plugin-utils/index.js'; import { handleHotUpdate } from './hmr.js'; import { parseAstroRequest, ParsedRequestResult } from './query.js'; @@ -29,20 +28,6 @@ interface AstroPluginOptions { /** Transform .astro files for Vite */ export default function astro({ settings, logging }: AstroPluginOptions): vite.Plugin { const { config } = settings; - function normalizeFilename(filename: string) { - if (filename.startsWith('/@fs')) { - filename = filename.slice('/@fs'.length); - } else if (filename.startsWith('/') && !ancestor(filename, config.root.pathname)) { - filename = new URL('.' + filename, config.root).pathname; - } - return filename; - } - function relativeToRoot(pathname: string) { - const arg = startsWithForwardSlash(pathname) ? '.' + pathname : pathname; - const url = new URL(arg, config.root); - return slash(fileURLToPath(url)) + url.search; - } - let resolvedConfig: vite.ResolvedConfig; // Variables for determining if an id starts with /src... @@ -51,8 +36,14 @@ export default function astro({ settings, logging }: AstroPluginOptions): vite.P const isFullFilePath = (path: string) => path.startsWith(prependForwardSlash(slash(fileURLToPath(config.root)))); + function relativeToRoot(pathname: string) { + const arg = startsWithForwardSlash(pathname) ? '.' + pathname : pathname; + const url = new URL(arg, config.root); + return slash(fileURLToPath(url)) + url.search; + } + function resolveRelativeFromAstroParent(id: string, parsedFrom: ParsedRequestResult): string { - const filename = normalizeFilename(parsedFrom.filename); + const filename = normalizeFilename(parsedFrom.filename, config); const resolvedURL = new URL(id, `file://${filename}`); const resolved = resolvedURL.pathname; if (isBrowserPath(resolved)) { @@ -208,10 +199,10 @@ export default function astro({ settings, logging }: AstroPluginOptions): vite.P return null; } }, - async transform(this: PluginContext, source, id, opts) { + async transform(source, id) { const parsedId = parseAstroRequest(id); - const query = parsedId.query; - if (!id.endsWith('.astro') || query.astro) { + // ignore astro file sub-requests, e.g. Foo.astro?astro&type=script&index=0&lang.ts + if (!id.endsWith('.astro') || parsedId.query.astro) { return; } // if we still get a relative path here, vite couldn't resolve the import @@ -219,7 +210,7 @@ export default function astro({ settings, logging }: AstroPluginOptions): vite.P return; } - const filename = normalizeFilename(parsedId.filename); + const filename = normalizeFilename(parsedId.filename, config); const compileProps: CompileProps = { astroConfig: config, viteConfig: resolvedConfig, diff --git a/packages/astro/src/vite-plugin-env/README.md b/packages/astro/src/vite-plugin-env/README.md index 0e2a7d7d5..dbaf4b8bf 100644 --- a/packages/astro/src/vite-plugin-env/README.md +++ b/packages/astro/src/vite-plugin-env/README.md @@ -2,10 +2,7 @@ Improves Vite's [Env Variables](https://vitejs.dev/guide/env-and-mode.html#env-files) support to include **private** env variables during Server-Side Rendering (SSR) but never in client-side rendering (CSR). -Note that for added security, this plugin does not include **globally available env variable** that exist on `process.env`. It only loads variables defined in your local `.env` files. +Private env variables can be accessed through `import.meta.env.SECRET` like Vite. Where the env variable is declared changes how it is replaced when transforming it: -Because of this, `MY_CLI_ARG` will never be added to `import.meta.env` during SSR or CSR. - -```shell -MY_CLI_ARG=1 npm run dev -``` +- If it's from a `.env` file, it gets replaced with the actual value. (static) +- If it's from `process.env`, it gets replaced as `process.env.SECRET`. (dynamic) diff --git a/packages/astro/src/vite-plugin-html/README.md b/packages/astro/src/vite-plugin-html/README.md new file mode 100644 index 000000000..d10d43754 --- /dev/null +++ b/packages/astro/src/vite-plugin-html/README.md @@ -0,0 +1,3 @@ +# vite-plugin-html + +Transforms `.html` files as JS to be rendered by Astro. diff --git a/packages/astro/src/vite-plugin-html/transform/index.ts b/packages/astro/src/vite-plugin-html/transform/index.ts index 2a2c8edc9..ddb4761ce 100644 --- a/packages/astro/src/vite-plugin-html/transform/index.ts +++ b/packages/astro/src/vite-plugin-html/transform/index.ts @@ -6,7 +6,6 @@ import slots, { SLOT_PREFIX } from './slots.js'; export async function transform(code: string, id: string) { const s = new MagicString(code, { filename: id }); - const imports = new Map(); const parser = rehype().data('settings', { fragment: true }).use(escape, { s }).use(slots, { s }); const vfile = new VFile({ value: code, path: id }); @@ -16,14 +15,6 @@ export async function transform(code: string, id: string) { ); s.append('`\n\t}\n}'); - if (imports.size > 0) { - let importText = ''; - for (const [path, importName] of imports.entries()) { - importText += `import ${importName} from "${path}";\n`; - } - s.prepend(importText); - } - return { code: s.toString(), map: s.generateMap(), diff --git a/packages/astro/src/vite-plugin-load-fallback/README.md b/packages/astro/src/vite-plugin-load-fallback/README.md new file mode 100644 index 000000000..6ff8eac5f --- /dev/null +++ b/packages/astro/src/vite-plugin-load-fallback/README.md @@ -0,0 +1,3 @@ +# vite-plugin-load-fallback + +Handle fallback loading using Astro's internal module loader before falling back to Vite's. diff --git a/packages/astro/src/vite-plugin-markdown-legacy/index.ts b/packages/astro/src/vite-plugin-markdown-legacy/index.ts index 3b0e06a08..4e866b54a 100644 --- a/packages/astro/src/vite-plugin-markdown-legacy/index.ts +++ b/packages/astro/src/vite-plugin-markdown-legacy/index.ts @@ -1,5 +1,4 @@ import { renderMarkdown } from '@astrojs/markdown-remark'; -import ancestor from 'common-ancestor-path'; import esbuild from 'esbuild'; import fs from 'fs'; import matter from 'gray-matter'; @@ -12,7 +11,7 @@ import { AstroErrorData, MarkdownError } from '../core/errors/index.js'; import type { LogOptions } from '../core/logger/core.js'; import { isMarkdownFile } from '../core/util.js'; import type { PluginMetadata as AstroPluginMetadata } from '../vite-plugin-astro/types'; -import { getFileInfo } from '../vite-plugin-utils/index.js'; +import { getFileInfo, normalizeFilename } from '../vite-plugin-utils/index.js'; interface AstroPluginOptions { settings: AstroSettings; @@ -50,19 +49,10 @@ function safeMatter(source: string, id: string) { } } -// TODO: Clean up some of the shared logic between this Markdown plugin and the Astro plugin. // Both end up connecting a `load()` hook to the Astro compiler, and share some copy-paste // logic in how that is done. export default function markdown({ settings }: AstroPluginOptions): Plugin { const { config } = settings; - function normalizeFilename(filename: string) { - if (filename.startsWith('/@fs')) { - filename = filename.slice('/@fs'.length); - } else if (filename.startsWith('/') && !ancestor(filename, config.root.pathname)) { - filename = new URL('.' + filename, config.root).pathname; - } - return filename; - } // Weird Vite behavior: Vite seems to use a fake "index.html" importer when you // have `enforce: pre`. This can probably be removed once the vite issue is fixed. @@ -152,7 +142,7 @@ export default function markdown({ settings }: AstroPluginOptions): Plugin { // directly as a page in Vite, or it was a deferred render from a JS module. // This returns the compiled markdown -> astro component that renders to HTML. if (isMarkdownFile(id)) { - const filename = normalizeFilename(id); + const filename = normalizeFilename(id, config); const source = await fs.promises.readFile(filename, 'utf8'); const renderOpts = config.markdown; diff --git a/packages/astro/src/vite-plugin-markdown/README.md b/packages/astro/src/vite-plugin-markdown/README.md index ee7fd0e54..b0c432a42 100644 --- a/packages/astro/src/vite-plugin-markdown/README.md +++ b/packages/astro/src/vite-plugin-markdown/README.md @@ -1,3 +1,3 @@ -# vite-plugin-markdown-legacy +# vite-plugin-markdown -Adds Markdown support to Vite, both at the top level as well as within `.astro` files. +Adds Markdown support to Vite for `.md` files (See `SUPPORTED_MARKDOWN_FILE_EXTENSIONS` for all supported extensions). diff --git a/packages/astro/src/vite-plugin-scripts/README.md b/packages/astro/src/vite-plugin-scripts/README.md new file mode 100644 index 000000000..dcb1cdd35 --- /dev/null +++ b/packages/astro/src/vite-plugin-scripts/README.md @@ -0,0 +1,3 @@ +# vite-plugin-scripts + +Resolves and loads custom scripts by Astro or injected by integrations. diff --git a/packages/astro/src/vite-plugin-scripts/page-ssr.ts b/packages/astro/src/vite-plugin-scripts/page-ssr.ts index d5dc819f8..514382521 100644 --- a/packages/astro/src/vite-plugin-scripts/page-ssr.ts +++ b/packages/astro/src/vite-plugin-scripts/page-ssr.ts @@ -2,24 +2,15 @@ import { Plugin as VitePlugin } from 'vite'; import { AstroSettings } from '../@types/astro.js'; import { PAGE_SSR_SCRIPT_ID } from './index.js'; -import ancestor from 'common-ancestor-path'; import MagicString from 'magic-string'; import { isPage } from '../core/util.js'; +import { normalizeFilename } from '../vite-plugin-utils/index.js'; export default function astroScriptsPostPlugin({ settings, }: { settings: AstroSettings; }): VitePlugin { - function normalizeFilename(filename: string) { - if (filename.startsWith('/@fs')) { - filename = filename.slice('/@fs'.length); - } else if (filename.startsWith('/') && !ancestor(filename, settings.config.root.pathname)) { - filename = new URL('.' + filename, settings.config.root).pathname; - } - return filename; - } - return { name: 'astro:scripts:page-ssr', enforce: 'post', @@ -30,7 +21,7 @@ export default function astroScriptsPostPlugin({ const hasInjectedScript = settings.scripts.some((s) => s.stage === 'page-ssr'); if (!hasInjectedScript) return; - const filename = normalizeFilename(id); + const filename = normalizeFilename(id, settings.config); let fileURL: URL; try { fileURL = new URL(`file://${filename}`); diff --git a/packages/astro/src/vite-plugin-utils/index.ts b/packages/astro/src/vite-plugin-utils/index.ts index 2c09e76d4..bea28877e 100644 --- a/packages/astro/src/vite-plugin-utils/index.ts +++ b/packages/astro/src/vite-plugin-utils/index.ts @@ -1,3 +1,4 @@ +import ancestor from 'common-ancestor-path'; import { Data } from 'vfile'; import type { AstroConfig, MarkdownAstroData } from '../@types/astro'; import { appendExtension, appendForwardSlash } from '../core/path.js'; @@ -48,3 +49,20 @@ export function safelyGetAstroData(vfileData: Data): MarkdownAstroData { return astro; } + +/** + * Normalizes different file names like: + * + * - /@fs/home/user/project/src/pages/index.astro + * - /src/pages/index.astro + * + * as absolute file paths. + */ +export function normalizeFilename(filename: string, config: AstroConfig) { + if (filename.startsWith('/@fs')) { + filename = filename.slice('/@fs'.length); + } else if (filename.startsWith('/') && !ancestor(filename, config.root.pathname)) { + filename = new URL('.' + filename, config.root).pathname; + } + return filename; +}