Export experimental JS API (#7979)
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com> Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
This commit is contained in:
parent
8a5b0c1f3a
commit
dbc97b121f
16 changed files with 139 additions and 29 deletions
35
.changeset/many-pears-explode.md
Normal file
35
.changeset/many-pears-explode.md
Normal file
|
@ -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);
|
||||
```
|
2
packages/astro/index.d.ts
vendored
Normal file
2
packages/astro/index.d.ts
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
export type * from './dist/@types/astro.js';
|
||||
export * from './dist/core/index.js';
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,5 @@ export async function build({ flags }: BuildOptions) {
|
|||
|
||||
const inlineConfig = flagsToAstroInlineConfig(flags);
|
||||
|
||||
await _build(inlineConfig, {
|
||||
teardownCompiler: true,
|
||||
});
|
||||
await _build(inlineConfig);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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([]);
|
||||
|
|
26
packages/astro/src/core/index.ts
Normal file
26
packages/astro/src/core/index.ts
Normal file
|
@ -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);
|
|
@ -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));
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"include": ["src", "index.d.ts"],
|
||||
"include": ["src"],
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"declarationDir": "./dist",
|
||||
|
|
Loading…
Reference in a new issue