summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Bjorn Lu <bjornlu.dev@gmail.com> 2023-08-18 16:52:04 +0800
committerGravatar GitHub <noreply@github.com> 2023-08-18 16:52:04 +0800
commitdbc97b121f42583728f1cdfdbf14575fda943f5b (patch)
tree6f6dbbd21362c9aa0b308557a98ca650e1864d64
parent8a5b0c1f3a4be6bb62db66ec70144109ff5b4c59 (diff)
downloadastro-dbc97b121f42583728f1cdfdbf14575fda943f5b.tar.gz
astro-dbc97b121f42583728f1cdfdbf14575fda943f5b.tar.zst
astro-dbc97b121f42583728f1cdfdbf14575fda943f5b.zip
Export experimental JS API (#7979)
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
-rw-r--r--.changeset/many-pears-explode.md35
-rw-r--r--packages/astro/index.d.ts2
-rw-r--r--packages/astro/package.json7
-rw-r--r--packages/astro/src/@types/astro.ts30
-rw-r--r--packages/astro/src/cli/build/index.ts4
-rw-r--r--packages/astro/src/cli/check/index.ts2
-rw-r--r--packages/astro/src/cli/sync/index.ts2
-rw-r--r--packages/astro/src/core/README.md4
-rw-r--r--packages/astro/src/core/build/index.ts14
-rw-r--r--packages/astro/src/core/dev/dev.ts7
-rw-r--r--packages/astro/src/core/index.ts26
-rw-r--r--packages/astro/src/core/preview/index.ts11
-rw-r--r--packages/astro/src/core/sync/index.ts13
-rw-r--r--packages/astro/test/test-utils.js7
-rw-r--r--packages/astro/test/units/dev/collections-mixed-content-errors.test.js2
-rw-r--r--packages/astro/tsconfig.json2
16 files changed, 139 insertions, 29 deletions
diff --git a/.changeset/many-pears-explode.md b/.changeset/many-pears-explode.md
new file mode 100644
index 000000000..1e2a30edc
--- /dev/null
+++ b/.changeset/many-pears-explode.md
@@ -0,0 +1,35 @@
+---
+'astro': major
+---
+
+Export experimental `dev`, `build`, `preview`, and `sync` APIs from `astro`. These APIs allow you to run Astro's commands programmatically, and replaces the previous entry point that runs the Astro CLI.
+
+While these APIs are experimental, the inline config parameter is relatively stable without foreseeable changes. However, the returned results of these APIs are more likely to change in the future.
+
+```ts
+import { dev, build, preview, sync, type AstroInlineConfig } from 'astro';
+
+// Inline Astro config object.
+// Provide a path to a configuration file to load or set options directly inline.
+const inlineConfig: AstroInlineConfig = {
+ // Inline-specific options...
+ configFile: './astro.config.mjs',
+ logLevel: 'info',
+ // Standard Astro config options...
+ site: 'https://example.com',
+};
+
+// Start the Astro dev server
+const devServer = await dev(inlineConfig);
+await devServer.stop();
+
+// Build your Astro project
+await build(inlineConfig);
+
+// Preview your built project
+const previewServer = await preview(inlineConfig);
+await previewServer.stop();
+
+// Generate types for your Astro project
+await sync(inlineConfig);
+```
diff --git a/packages/astro/index.d.ts b/packages/astro/index.d.ts
new file mode 100644
index 000000000..a9e679be1
--- /dev/null
+++ b/packages/astro/index.d.ts
@@ -0,0 +1,2 @@
+export type * from './dist/@types/astro.js';
+export * from './dist/core/index.js';
diff --git a/packages/astro/package.json b/packages/astro/package.json
index 76e67fb92..caf49c64e 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -12,7 +12,7 @@
},
"bugs": "https://github.com/withastro/astro/issues",
"homepage": "https://astro.build",
- "types": "./dist/@types/astro.d.ts",
+ "types": "./index.d.ts",
"typesVersions": {
"*": {
"app": [
@@ -31,8 +31,8 @@
},
"exports": {
".": {
- "types": "./dist/@types/astro.d.ts",
- "default": "./astro.js"
+ "types": "./index.d.ts",
+ "default": "./dist/core/index.js"
},
"./env": "./env.d.ts",
"./types": "./types.d.ts",
@@ -90,6 +90,7 @@
"tsconfigs",
"dist",
"astro.js",
+ "index.d.ts",
"config.d.ts",
"config.mjs",
"zod.d.ts",
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index 422f37bcd..d2475ec7d 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -143,7 +143,7 @@ export interface CLIFlags {
*/
export interface AstroGlobal<
Props extends Record<string, any> = Record<string, any>,
- Self = AstroComponentFactory
+ Self = AstroComponentFactory,
> extends AstroGlobalPartial,
AstroSharedContext<Props> {
/**
@@ -1404,13 +1404,39 @@ export interface AstroConfig extends AstroConfigType {
// TypeScript still confirms zod validation matches this type.
integrations: AstroIntegration[];
}
+/**
+ * An inline Astro config that takes highest priority when merging with the user config,
+ * and includes inline-specific options to configure how Astro runs.
+ */
export interface AstroInlineConfig extends AstroUserConfig, AstroInlineOnlyConfig {}
export interface AstroInlineOnlyConfig {
+ /**
+ * A custom path to the Astro config file. If relative, it'll resolve based on the current working directory.
+ * Set to false to disable loading any config files.
+ *
+ * If this value is undefined or unset, Astro will search for an `astro.config.(js,mjs,ts)` file relative to
+ * the `root` and load the config file if found.
+ *
+ * The inline config passed in this object will take highest priority when merging with the loaded user config.
+ */
configFile?: string | false;
+ /**
+ * The mode used when building your site to generate either "development" or "production" code.
+ */
mode?: RuntimeMode;
+ /**
+ * The logging level to filter messages logged by Astro.
+ * - "debug": Log everything, including noisy debugging diagnostics.
+ * - "info": Log informational messages, warnings, and errors.
+ * - "warn": Log warnings and errors.
+ * - "error": Log errors only.
+ * - "silent": No logging.
+ *
+ * @default "info"
+ */
logLevel?: LoggerLevel;
/**
- * @internal for testing only
+ * @internal for testing only, use `logLevel` instead.
*/
logging?: LogOptions;
}
diff --git a/packages/astro/src/cli/build/index.ts b/packages/astro/src/cli/build/index.ts
index 9e26108a2..dd44823d1 100644
--- a/packages/astro/src/cli/build/index.ts
+++ b/packages/astro/src/cli/build/index.ts
@@ -25,7 +25,5 @@ export async function build({ flags }: BuildOptions) {
const inlineConfig = flagsToAstroInlineConfig(flags);
- await _build(inlineConfig, {
- teardownCompiler: true,
- });
+ await _build(inlineConfig);
}
diff --git a/packages/astro/src/cli/check/index.ts b/packages/astro/src/cli/check/index.ts
index 428027154..6ae11d576 100644
--- a/packages/astro/src/cli/check/index.ts
+++ b/packages/astro/src/cli/check/index.ts
@@ -27,7 +27,7 @@ export async function check(flags: Arguments) {
// Run sync before check to make sure types are generated.
// NOTE: In the future, `@astrojs/check` can expose a `before lint` hook so that this works during `astro check --watch` too.
// For now, we run this once as usually `astro check --watch` is ran alongside `astro dev` which also calls `astro sync`.
- const { sync } = await import('../../core/sync/index.js');
+ const { default: sync } = await import('../../core/sync/index.js');
const inlineConfig = flagsToAstroInlineConfig(flags);
const exitCode = await sync(inlineConfig);
if (exitCode !== 0) {
diff --git a/packages/astro/src/cli/sync/index.ts b/packages/astro/src/cli/sync/index.ts
index 66a277e46..8650bf904 100644
--- a/packages/astro/src/cli/sync/index.ts
+++ b/packages/astro/src/cli/sync/index.ts
@@ -1,6 +1,6 @@
import type yargs from 'yargs-parser';
import { printHelp } from '../../core/messages.js';
-import { sync as _sync } from '../../core/sync/index.js';
+import _sync from '../../core/sync/index.js';
import { flagsToAstroInlineConfig } from '../flags.js';
interface SyncOptions {
diff --git a/packages/astro/src/core/README.md b/packages/astro/src/core/README.md
index 74f55a0bb..ef4dd8750 100644
--- a/packages/astro/src/core/README.md
+++ b/packages/astro/src/core/README.md
@@ -1,6 +1,8 @@
# `core/`
-Code that executes within the top-level Node context. Contains the main Astro logic for the `build` and `dev` commands, and also manages the Vite server and SSR.
+Code that executes within the top-level Node context. Contains the main Astro logic for the `build`, `dev`, `preview`, and `sync` commands, and also manages the Vite server and SSR.
+
+The `core/index.ts` file is the main entry point for the `astro` package.
[See CONTRIBUTING.md](../../../../CONTRIBUTING.md) for a code overview.
diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts
index 07b9b2f7c..894a5e6e2 100644
--- a/packages/astro/src/core/build/index.ts
+++ b/packages/astro/src/core/build/index.ts
@@ -37,14 +37,22 @@ export interface BuildOptions {
/**
* Teardown the compiler WASM instance after build. This can improve performance when
* building once, but may cause a performance hit if building multiple times in a row.
+ *
+ * @internal only used for testing
+ * @default true
*/
teardownCompiler?: boolean;
}
-/** `astro build` */
+/**
+ * Builds your site for deployment. By default, this will generate static files and place them in a dist/ directory.
+ * If SSR is enabled, this will generate the necessary server files to serve your site.
+ *
+ * @experimental The JavaScript API is experimental
+ */
export default async function build(
inlineConfig: AstroInlineConfig,
- options: BuildOptions
+ options?: BuildOptions
): Promise<void> {
applyPolyfill();
const logging = createNodeLogging(inlineConfig);
@@ -82,7 +90,7 @@ class AstroBuilder {
}
this.settings = settings;
this.logging = options.logging;
- this.teardownCompiler = options.teardownCompiler ?? false;
+ this.teardownCompiler = options.teardownCompiler ?? true;
this.routeCache = new RouteCache(this.logging);
this.origin = settings.config.site
? new URL(settings.config.site).origin
diff --git a/packages/astro/src/core/dev/dev.ts b/packages/astro/src/core/dev/dev.ts
index b14656d26..115cbe825 100644
--- a/packages/astro/src/core/dev/dev.ts
+++ b/packages/astro/src/core/dev/dev.ts
@@ -18,7 +18,12 @@ export interface DevServer {
stop(): Promise<void>;
}
-/** `astro dev` */
+/**
+ * Runs Astro’s development server. This is a local HTTP server that doesn’t bundle assets.
+ * It uses Hot Module Replacement (HMR) to update your browser as you save changes in your editor.
+ *
+ * @experimental The JavaScript API is experimental
+ */
export default async function dev(inlineConfig: AstroInlineConfig): Promise<DevServer> {
const devStart = performance.now();
await telemetry.record([]);
diff --git a/packages/astro/src/core/index.ts b/packages/astro/src/core/index.ts
new file mode 100644
index 000000000..31d868311
--- /dev/null
+++ b/packages/astro/src/core/index.ts
@@ -0,0 +1,26 @@
+// This is the main entrypoint when importing the `astro` package.
+
+import type { AstroInlineConfig } from '../@types/astro.js';
+import { default as _build } from './build/index.js';
+import { default as _sync } from './sync/index.js';
+
+export { default as dev } from './dev/index.js';
+export { default as preview } from './preview/index.js';
+
+/**
+ * Builds your site for deployment. By default, this will generate static files and place them in a dist/ directory.
+ * If SSR is enabled, this will generate the necessary server files to serve your site.
+ *
+ * @experimental The JavaScript API is experimental
+ */
+// Wrap `_build` to prevent exposing the second internal options parameter
+export const build = (inlineConfig: AstroInlineConfig) => _build(inlineConfig);
+
+/**
+ * Generates TypeScript types for all Astro modules. This sets up a `src/env.d.ts` file for type inferencing,
+ * and defines the `astro:content` module for the Content Collections API.
+ *
+ * @experimental The JavaScript API is experimental
+ */
+// Wrap `_sync` to prevent exposing the second internal options parameter
+export const sync = (inlineConfig: AstroInlineConfig) => _sync(inlineConfig);
diff --git a/packages/astro/src/core/preview/index.ts b/packages/astro/src/core/preview/index.ts
index fdd5d6fe7..d5b2b2db7 100644
--- a/packages/astro/src/core/preview/index.ts
+++ b/packages/astro/src/core/preview/index.ts
@@ -10,10 +10,13 @@ import { createSettings } from '../config/settings.js';
import createStaticPreviewServer from './static-preview-server.js';
import { getResolvedHostForHttpServer } from './util.js';
-/** The primary dev action */
-export default async function preview(
- inlineConfig: AstroInlineConfig
-): Promise<PreviewServer | undefined> {
+/**
+ * Starts a local server to serve your static dist/ directory. This command is useful for previewing
+ * your build locally, before deploying it. It is not designed to be run in production.
+ *
+ * @experimental The JavaScript API is experimental
+ */
+export default async function preview(inlineConfig: AstroInlineConfig): Promise<PreviewServer> {
const logging = createNodeLogging(inlineConfig);
const { userConfig, astroConfig } = await resolveConfig(inlineConfig ?? {}, 'preview');
telemetry.record(eventCliSession('preview', userConfig));
diff --git a/packages/astro/src/core/sync/index.ts b/packages/astro/src/core/sync/index.ts
index be51f0039..e1d432465 100644
--- a/packages/astro/src/core/sync/index.ts
+++ b/packages/astro/src/core/sync/index.ts
@@ -22,8 +22,7 @@ export type ProcessExit = 0 | 1;
export type SyncOptions = {
/**
- * Only used for testing
- * @internal
+ * @internal only used for testing
*/
fs?: typeof fsMod;
};
@@ -32,7 +31,13 @@ export type SyncInternalOptions = SyncOptions & {
logging: LogOptions;
};
-export async function sync(
+/**
+ * Generates TypeScript types for all Astro modules. This sets up a `src/env.d.ts` file for type inferencing,
+ * and defines the `astro:content` module for the Content Collections API.
+ *
+ * @experimental The JavaScript API is experimental
+ */
+export default async function sync(
inlineConfig: AstroInlineConfig,
options?: SyncOptions
): Promise<ProcessExit> {
@@ -48,7 +53,7 @@ export async function sync(
command: 'build',
});
- return await syncInternal(settings, { logging, fs: options?.fs });
+ return await syncInternal(settings, { ...options, logging });
}
/**
diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js
index 0b336698f..fafd3046c 100644
--- a/packages/astro/test/test-utils.js
+++ b/packages/astro/test/test-utils.js
@@ -6,15 +6,14 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url';
import stripAnsi from 'strip-ansi';
import { check } from '../dist/cli/check/index.js';
+import { dev, preview } from '../dist/core/index.js';
import build from '../dist/core/build/index.js';
+import sync from '../dist/core/sync/index.js';
import { RESOLVED_SPLIT_MODULE_ID } from '../dist/core/build/plugins/plugin-ssr.js';
import { getVirtualModulePageNameFromPath } from '../dist/core/build/plugins/util.js';
import { makeSplitEntryPointFileName } from '../dist/core/build/static-build.js';
import { mergeConfig, resolveConfig } from '../dist/core/config/index.js';
-import dev from '../dist/core/dev/index.js';
import { nodeLogDestination } from '../dist/core/logger/node.js';
-import preview from '../dist/core/preview/index.js';
-import { sync } from '../dist/core/sync/index.js';
// Disable telemetry when running tests
process.env.ASTRO_TELEMETRY_DISABLED = true;
@@ -148,7 +147,7 @@ export async function loadFixture(inlineConfig) {
return {
build: async (extraInlineConfig = {}) => {
process.env.NODE_ENV = 'production';
- return build(mergeConfig(inlineConfig, extraInlineConfig));
+ return build(mergeConfig(inlineConfig, extraInlineConfig), { teardownCompiler: false });
},
sync: async (extraInlineConfig = {}, opts) => {
return sync(mergeConfig(inlineConfig, extraInlineConfig), opts);
diff --git a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js b/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
index 344615346..a8e282a88 100644
--- a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
+++ b/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
@@ -1,6 +1,6 @@
import { expect } from 'chai';
import { fileURLToPath } from 'node:url';
-import { sync as _sync } from '../../../dist/core/sync/index.js';
+import _sync from '../../../dist/core/sync/index.js';
import { createFsWithFallback } from '../test-utils.js';
const root = new URL('../../fixtures/content-mixed-errors/', import.meta.url);
diff --git a/packages/astro/tsconfig.json b/packages/astro/tsconfig.json
index 63854a31d..d8bd9b197 100644
--- a/packages/astro/tsconfig.json
+++ b/packages/astro/tsconfig.json
@@ -1,6 +1,6 @@
{
"extends": "../../tsconfig.base.json",
- "include": ["src", "index.d.ts"],
+ "include": ["src"],
"compilerOptions": {
"allowJs": true,
"declarationDir": "./dist",