Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom mode #12150

Open
wants to merge 1 commit into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .changeset/sixty-coins-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
'astro': minor
---

Adds support for passing values other than `"production"` or `"development"` to the `--mode` flag, e.g. `"staging"`, `"testing"`, or any value. This allows to change the value of `import.meta.env.MODE` or the loaded `.env` file, and take advantage of Vite's [mode](https://vite.dev/guide/env-and-mode#modes) feature.

Note that changing the `mode` does not change the kind of code transform handled by Vite and Astro:

- In `astro dev`, Astro will transform code with debug information.
- In `astro build`, Astro will transform code with the most optimized output and removes debug information.
- In `astro build --dev` (new flag), Astro will transform code with debug information like in `astro dev`.

This enables various usecases like:

```bash
# Run the dev server connected to a "staging" API
astro dev --mode staging

# Build a site that connects to a "staging" API
astro build --mode staging

# Build a site that connects to a "production" API with additional debug information
astro build --dev

# Build a site that connects to a "testing" API
astro build --mode testing
```

The different modes can be used to load different `.env` files, e.g. `.env.staging` or `.env.production`, which can have different `API_URL` environment variable values (for example).
16 changes: 7 additions & 9 deletions packages/astro/src/assets/vite-plugin-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
removeBase,
removeQueryString,
} from '../core/path.js';
import type { AstroPluginOptions, AstroSettings } from '../types/astro.js';
import type { AstroSettings } from '../types/astro.js';
import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from './consts.js';
import type { ImageTransform } from './types.js';
import { getAssetsPrefix } from './utils/getAssetsPrefix.js';
Expand Down Expand Up @@ -89,12 +89,10 @@ const addStaticImageFactory = (
};
};

export default function assets({
settings,
mode,
}: AstroPluginOptions & { mode: string }): vite.Plugin[] {
export default function assets({ settings }: { settings: AstroSettings }): vite.Plugin[] {
let resolvedConfig: vite.ResolvedConfig;
let shouldEmitFile = false;
let isBuild = false;

globalThis.astroAsset = {
referencedImages: new Set(),
Expand All @@ -104,6 +102,9 @@ export default function assets({
// Expose the components and different utilities from `astro:assets`
{
name: 'astro:assets',
config(_, env) {
isBuild = env.command === 'build';
},
async resolveId(id) {
if (id === VIRTUAL_SERVICE_ID) {
return await this.resolve(settings.config.image.service.entrypoint);
Expand Down Expand Up @@ -143,10 +144,7 @@ export default function assets({
}
},
buildStart() {
if (mode != 'build') {
return;
}

if (!isBuild) return;
globalThis.astroAsset.addStaticImage = addStaticImageFactory(settings);
},
// In build, rewrite paths to ESM imported images in code to their final location
Expand Down
3 changes: 2 additions & 1 deletion packages/astro/src/cli/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export async function build({ flags }: BuildOptions) {
'--force',
'Clear the content layer and content collection cache, forcing a full rebuild.',
],
['--dev', 'Create a development build, similar to code transformed in `astro dev`.'],
['--help (-h)', 'See all available flags.'],
],
},
Expand All @@ -28,5 +29,5 @@ export async function build({ flags }: BuildOptions) {

const inlineConfig = flagsToAstroInlineConfig(flags);

await _build(inlineConfig);
await _build(inlineConfig, { dev: !!flags.dev });
}
2 changes: 1 addition & 1 deletion packages/astro/src/cli/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function flagsToAstroInlineConfig(flags: Flags): AstroInlineConfig {
return {
// Inline-only configs
configFile: typeof flags.config === 'string' ? flags.config : undefined,
mode: typeof flags.mode === 'string' ? (flags.mode as AstroInlineConfig['mode']) : undefined,
mode: typeof flags.mode === 'string' ? flags.mode : undefined,
logLevel: flags.verbose ? 'debug' : flags.silent ? 'silent' : undefined,
force: flags.force ? true : undefined,

Expand Down
11 changes: 5 additions & 6 deletions packages/astro/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { UserConfig as ViteUserConfig } from 'vite';
import type { UserConfig as ViteUserConfig, UserConfigFn as ViteUserConfigFn } from 'vite';
import { Logger } from '../core/logger/core.js';
import { createRouteManifest } from '../core/routing/index.js';
import type { AstroInlineConfig, AstroUserConfig } from '../types/public/config.js';
Expand All @@ -11,11 +11,11 @@ export function defineConfig(config: AstroUserConfig) {
export function getViteConfig(
userViteConfig: ViteUserConfig,
inlineAstroConfig: AstroInlineConfig = {},
) {
): ViteUserConfigFn {
// Return an async Vite config getter which exposes a resolved `mode` and `command`
return async ({ mode, command }: { mode: 'dev'; command: 'serve' | 'build' }) => {
return async ({ mode, command }) => {
// Vite `command` is `serve | build`, but Astro uses `dev | build`
const cmd = command === 'serve' ? 'dev' : command;
const cmd = command === 'serve' ? 'dev' : 'build';

// Use dynamic import to avoid pulling in deps unless used
const [
Expand Down Expand Up @@ -46,13 +46,12 @@ export function getViteConfig(
const devSSRManifest = createDevelopmentManifest(settings);
const viteConfig = await createVite(
{
mode,
plugins: [
// Initialize the content listener
astroContentListenPlugin({ settings, logger, fs }),
],
},
{ settings, logger, mode, sync: false, manifest, ssrManifest: devSSRManifest },
{ settings, command: cmd, logger, mode, sync: false, manifest, ssrManifest: devSSRManifest },
);
await runHookConfigDone({ settings, logger });
return mergeConfig(viteConfig, userViteConfig);
Expand Down
6 changes: 1 addition & 5 deletions packages/astro/src/content/vite-plugin-content-assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ import {
import { hasContentFlag } from './utils.js';

export function astroContentAssetPropagationPlugin({
mode,
settings,
}: {
mode: string;
settings: AstroSettings;
}): Plugin {
let devModuleLoader: ModuleLoader;
Expand Down Expand Up @@ -67,9 +65,7 @@ export function astroContentAssetPropagationPlugin({
}
},
configureServer(server) {
if (mode === 'dev') {
devModuleLoader = createViteLoader(server);
}
devModuleLoader = createViteLoader(server);
},
async transform(_, id, options) {
if (hasContentFlag(id, PROPAGATED_ASSET_FLAG)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export function astroContentVirtualModPlugin({
name: 'astro-content-virtual-mod-plugin',
enforce: 'pre',
configResolved(config) {
IS_DEV = config.mode === 'development';
IS_DEV = !config.isProduction;
dataStoreFile = getDataStoreFile(settings, IS_DEV);
},
async resolveId(id) {
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export class App {
return AppPipeline.create(manifestData, {
logger: this.#logger,
manifest: this.#manifest,
mode: 'production',
runtimeMode: 'production',
renderers: this.#manifest.renderers,
defaultRoutes: createDefaultRoutes(this.#manifest),
resolve: async (specifier: string) => {
Expand Down
6 changes: 3 additions & 3 deletions packages/astro/src/core/app/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class AppPipeline extends Pipeline {
{
logger,
manifest,
mode,
runtimeMode,
renderers,
resolve,
serverLike,
Expand All @@ -25,7 +25,7 @@ export class AppPipeline extends Pipeline {
AppPipeline,
| 'logger'
| 'manifest'
| 'mode'
| 'runtimeMode'
| 'renderers'
| 'resolve'
| 'serverLike'
Expand All @@ -36,7 +36,7 @@ export class AppPipeline extends Pipeline {
const pipeline = new AppPipeline(
logger,
manifest,
mode,
runtimeMode,
renderers,
resolve,
serverLike,
Expand Down
6 changes: 3 additions & 3 deletions packages/astro/src/core/base-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ export abstract class Pipeline {
readonly logger: Logger,
readonly manifest: SSRManifest,
/**
* "development" or "production"
* "development" or "production" only
*/
readonly mode: RuntimeMode,
readonly runtimeMode: RuntimeMode,
readonly renderers: SSRLoadedRenderer[],
readonly resolve: (s: string) => Promise<string>,
/**
Expand All @@ -51,7 +51,7 @@ export abstract class Pipeline {
readonly compressHTML = manifest.compressHTML,
readonly i18n = manifest.i18n,
readonly middleware = manifest.middleware,
readonly routeCache = new RouteCache(logger, mode),
readonly routeCache = new RouteCache(logger, runtimeMode),
/**
* Used for `Astro.site`.
*/
Expand Down
29 changes: 19 additions & 10 deletions packages/astro/src/core/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ import { collectPagesData } from './page-data.js';
import { staticBuild, viteBuild } from './static-build.js';
import type { StaticBuildOptions } from './types.js';
import { getTimeStat } from './util.js';

export interface BuildOptions {
/**
* Create a development build, similar to code transformed in `astro dev`.
*
* @default false
*/
dev?: boolean;
/**
* 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.
Expand All @@ -52,7 +59,7 @@ export default async function build(
inlineConfig: AstroInlineConfig,
options: BuildOptions = {},
): Promise<void> {
ensureProcessNodeEnv('production');
ensureProcessNodeEnv(options.dev ? 'development' : 'production');
applyPolyfill();
const logger = createNodeLogger(inlineConfig);
const { userConfig, astroConfig } = await resolveConfig(inlineConfig, 'build');
Expand All @@ -67,29 +74,31 @@ export default async function build(
const builder = new AstroBuilder(settings, {
...options,
logger,
mode: inlineConfig.mode,
mode: inlineConfig.mode ?? 'production',
runtimeMode: options.dev ? 'development' : 'production',
});
await builder.run();
}

interface AstroBuilderOptions extends BuildOptions {
logger: Logger;
mode?: RuntimeMode;
mode: string;
runtimeMode: RuntimeMode;
}

class AstroBuilder {
private settings: AstroSettings;
private logger: Logger;
private mode: RuntimeMode = 'production';
private mode: string;
private runtimeMode: RuntimeMode;
private origin: string;
private manifest: ManifestData;
private timer: Record<string, number>;
private teardownCompiler: boolean;

constructor(settings: AstroSettings, options: AstroBuilderOptions) {
if (options.mode) {
this.mode = options.mode;
}
this.mode = options.mode;
this.runtimeMode = options.runtimeMode;
this.settings = settings;
this.logger = options.logger;
this.teardownCompiler = options.teardownCompiler ?? true;
Expand Down Expand Up @@ -127,7 +136,6 @@ class AstroBuilder {

const viteConfig = await createVite(
{
mode: this.mode,
server: {
hmr: false,
middlewareMode: true,
Expand All @@ -136,7 +144,7 @@ class AstroBuilder {
{
settings: this.settings,
logger: this.logger,
mode: 'build',
mode: this.mode,
command: 'build',
sync: false,
manifest: this.manifest,
Expand All @@ -145,6 +153,7 @@ class AstroBuilder {

const { syncInternal } = await import('../sync/index.js');
await syncInternal({
mode: this.mode,
settings: this.settings,
logger,
fs,
Expand Down Expand Up @@ -193,7 +202,7 @@ class AstroBuilder {
settings: this.settings,
logger: this.logger,
manifest: this.manifest,
mode: this.mode,
runtimeMode: this.runtimeMode,
origin: this.origin,
pageNames,
teardownCompiler: this.teardownCompiler,
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/build/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class BuildPipeline extends Pipeline {
super(
options.logger,
manifest,
options.mode,
options.runtimeMode,
manifest.renderers,
resolve,
serverLike,
Expand Down
2 changes: 0 additions & 2 deletions packages/astro/src/core/build/static-build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ async function ssrBuild(
const { lastVitePlugins, vitePlugins } = await container.runBeforeHook('server', input);
const viteBuildConfig: vite.InlineConfig = {
...viteConfig,
mode: viteConfig.mode || 'production',
logLevel: viteConfig.logLevel ?? 'error',
build: {
target: 'esnext',
Expand Down Expand Up @@ -269,7 +268,6 @@ async function clientBuild(

const viteBuildConfig: vite.InlineConfig = {
...viteConfig,
mode: viteConfig.mode || 'production',
build: {
target: 'esnext',
...viteConfig.build,
Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/core/build/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export interface StaticBuildOptions {
settings: AstroSettings;
logger: Logger;
manifest: ManifestData;
mode: RuntimeMode;
runtimeMode: RuntimeMode;
origin: string;
pageNames: string[];
viteConfig: InlineConfig;
Expand Down
Loading
Loading