diff --git a/src/@types/astro.ts b/src/@types/astro.ts index 5790c4b78827..8f6b73d5e317 100644 --- a/src/@types/astro.ts +++ b/src/@types/astro.ts @@ -33,3 +33,5 @@ export interface CompileResult { contents: string; css?: string; } + +export type RuntimeMode = 'development' | 'production'; diff --git a/src/@types/compiler.ts b/src/@types/compiler.ts index 916242c51961..2f104b5c5022 100644 --- a/src/@types/compiler.ts +++ b/src/@types/compiler.ts @@ -1,9 +1,10 @@ import type { LogOptions } from '../logger'; -import type { AstroConfig, ValidExtensionPlugins } from './astro'; +import type { AstroConfig, RuntimeMode, ValidExtensionPlugins } from './astro'; export interface CompileOptions { logging: LogOptions; resolve: (p: string) => Promise; astroConfig: AstroConfig; extensions?: Record; + mode: RuntimeMode; } diff --git a/src/@types/optimizer.ts b/src/@types/optimizer.ts index 22027d2e2a7d..a076ae9b82d8 100644 --- a/src/@types/optimizer.ts +++ b/src/@types/optimizer.ts @@ -1,4 +1,5 @@ import type { TemplateNode } from '../parser/interfaces'; +import type { CompileOptions } from './compiler'; export type VisitorFn = (node: TemplateNode, parent: TemplateNode, type: string, index: number) => void; @@ -14,3 +15,9 @@ export interface Optimizer { }; finalize: () => Promise; } + +export interface OptimizeOptions { + compileOptions: CompileOptions; + filename: string; + fileID: string; +} diff --git a/src/build.ts b/src/build.ts index 7f4fa713cc00..39b778600abd 100644 --- a/src/build.ts +++ b/src/build.ts @@ -1,4 +1,4 @@ -import type { AstroConfig } from './@types/astro'; +import type { AstroConfig, RuntimeMode } from './@types/astro'; import type { LogOptions } from './logger'; import type { LoadResult } from './runtime'; @@ -60,14 +60,15 @@ export async function build(astroConfig: AstroConfig): Promise<0 | 1> { dest: defaultLogDestination, }; - const runtime = await createRuntime(astroConfig, { logging: runtimeLogging }); + const mode: RuntimeMode = 'production'; + const runtime = await createRuntime(astroConfig, { mode, logging: runtimeLogging }); const { runtimeConfig } = runtime; const { backendSnowpack: snowpack } = runtimeConfig; const resolve = (pkgName: string) => snowpack.getUrlForPackage(pkgName); const imports = new Set(); const statics = new Set(); - const collectImportsOptions = { astroConfig, logging, resolve }; + const collectImportsOptions = { astroConfig, logging, resolve, mode }; for (const pathname of await allPages(pageRoot)) { const filepath = new URL(`file://${pathname}`); diff --git a/src/build/bundle.ts b/src/build/bundle.ts index 82b6930d5c58..143be0521827 100644 --- a/src/build/bundle.ts +++ b/src/build/bundle.ts @@ -1,4 +1,4 @@ -import type { AstroConfig, ValidExtensionPlugins } from '../@types/astro'; +import type { AstroConfig, RuntimeMode, ValidExtensionPlugins } from '../@types/astro'; import type { ImportDeclaration } from '@babel/types'; import type { InputOptions, OutputOptions } from 'rollup'; import type { AstroRuntime } from '../runtime'; @@ -62,9 +62,10 @@ interface CollectDynamic { astroConfig: AstroConfig; resolve: (s: string) => Promise; logging: LogOptions; + mode: RuntimeMode; } -export async function collectDynamicImports(filename: URL, { astroConfig, logging, resolve }: CollectDynamic) { +export async function collectDynamicImports(filename: URL, { astroConfig, logging, resolve, mode }: CollectDynamic) { const imports = new Set(); // Only astro files @@ -89,6 +90,7 @@ export async function collectDynamicImports(filename: URL, { astroConfig, loggin astroConfig, resolve, logging, + mode, }, }); diff --git a/src/compiler/index.ts b/src/compiler/index.ts index 0ba5657cde95..88ea5caf9deb 100644 --- a/src/compiler/index.ts +++ b/src/compiler/index.ts @@ -1,5 +1,5 @@ -import type { LogOptions } from '../logger.js'; -import type { AstroConfig, CompileResult, TransformResult } from '../@types/astro'; +import type { CompileResult, TransformResult } from '../@types/astro'; +import type { CompileOptions } from '../@types/compiler.js'; import path from 'path'; import micromark from 'micromark'; @@ -13,12 +13,6 @@ import { encodeMarkdown } from '../micromark-encode.js'; import { optimize } from './optimize/index.js'; import { codegen } from './codegen.js'; -interface CompileOptions { - astroConfig: AstroConfig; - logging: LogOptions; - resolve: (p: string) => Promise; -} - function internalImport(internalPath: string) { return `/_astro_internal/${internalPath}`; } diff --git a/src/compiler/optimize/index.ts b/src/compiler/optimize/index.ts index e73c93c7c9df..53dd3f2d6b52 100644 --- a/src/compiler/optimize/index.ts +++ b/src/compiler/optimize/index.ts @@ -1,6 +1,5 @@ import type { Ast, TemplateNode } from '../../parser/interfaces'; -import type { CompileOptions } from '../../@types/compiler'; -import type { NodeVisitor, Optimizer, VisitorFn } from '../../@types/optimizer'; +import type { NodeVisitor, OptimizeOptions, Optimizer, VisitorFn } from '../../@types/optimizer'; import { walk } from 'estree-walker'; @@ -69,12 +68,6 @@ function walkAstWithVisitors(tmpl: TemplateNode, collection: VisitorCollection) }); } -interface OptimizeOptions { - compileOptions: CompileOptions; - filename: string; - fileID: string; -} - export async function optimize(ast: Ast, opts: OptimizeOptions) { const htmlVisitors = createVisitorCollection(); const cssVisitors = createVisitorCollection(); diff --git a/src/compiler/optimize/styles.ts b/src/compiler/optimize/styles.ts index b833f9e7099e..b613e4845961 100644 --- a/src/compiler/optimize/styles.ts +++ b/src/compiler/optimize/styles.ts @@ -4,7 +4,8 @@ import autoprefixer from 'autoprefixer'; import postcss from 'postcss'; import findUp from 'find-up'; import sass from 'sass'; -import { Optimizer } from '../../@types/optimizer'; +import { RuntimeMode } from '../../@types/astro'; +import { OptimizeOptions, Optimizer } from '../../@types/optimizer'; import type { TemplateNode } from '../../parser/interfaces'; import astroScopedStyles from './postcss-scoped-styles/index.js'; @@ -25,9 +26,6 @@ const getStyleType: Map = new Map([ ['text/scss', 'scss'], ]); -const SASS_OPTIONS: Partial = { - outputStyle: process.env.NODE_ENV === 'production' ? 'compressed' : undefined, -}; /** HTML tags that should never get scoped classes */ const NEVER_SCOPED_TAGS = new Set(['html', 'head', 'body', 'script', 'style', 'link', 'meta']); @@ -50,8 +48,15 @@ export interface StyleTransformResult { // cache node_modules resolutions for each run. saves looking up the same directory over and over again. blown away on exit. const nodeModulesMiniCache = new Map(); +export interface TransformStyleOptions { + type?: string; + filename: string; + scopedClass: string; + mode: RuntimeMode; +} + /** Convert styles to scoped CSS */ -async function transformStyle(code: string, { type, filename, scopedClass }: { type?: string; filename: string; scopedClass: string }): Promise { +async function transformStyle(code: string, { type, filename, scopedClass, mode }: TransformStyleOptions): Promise { let styleType: StyleType = 'css'; // important: assume CSS as default if (type) { styleType = getStyleType.get(type) || styleType; @@ -80,7 +85,13 @@ async function transformStyle(code: string, { type, filename, scopedClass }: { t } case 'sass': case 'scss': { - css = sass.renderSync({ ...SASS_OPTIONS, data: code, includePaths }).css.toString('utf8'); + css = sass + .renderSync({ + outputStyle: mode === 'production' ? 'compressed' : undefined, + data: code, + includePaths, + }) + .css.toString('utf8'); break; } default: { @@ -96,7 +107,7 @@ async function transformStyle(code: string, { type, filename, scopedClass }: { t } /** Style optimizer */ -export default function ({ filename, fileID }: { filename: string; fileID: string }): Optimizer { +export default function optimizeStyles({ compileOptions, filename, fileID }: OptimizeOptions): Optimizer { const styleNodes: TemplateNode[] = []; //