Add runtime mode (#48)
This commit is contained in:
parent
7c10d563f2
commit
f6a7ac67be
10 changed files with 48 additions and 32 deletions
|
@ -33,3 +33,5 @@ export interface CompileResult {
|
|||
contents: string;
|
||||
css?: string;
|
||||
}
|
||||
|
||||
export type RuntimeMode = 'development' | 'production';
|
||||
|
|
|
@ -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<string>;
|
||||
astroConfig: AstroConfig;
|
||||
extensions?: Record<string, ValidExtensionPlugins>;
|
||||
mode: RuntimeMode;
|
||||
}
|
||||
|
|
|
@ -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<void>;
|
||||
}
|
||||
|
||||
export interface OptimizeOptions {
|
||||
compileOptions: CompileOptions;
|
||||
filename: string;
|
||||
fileID: string;
|
||||
}
|
||||
|
|
|
@ -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<string>();
|
||||
const statics = new Set<string>();
|
||||
const collectImportsOptions = { astroConfig, logging, resolve };
|
||||
const collectImportsOptions = { astroConfig, logging, resolve, mode };
|
||||
|
||||
for (const pathname of await allPages(pageRoot)) {
|
||||
const filepath = new URL(`file://${pathname}`);
|
||||
|
|
|
@ -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<string>;
|
||||
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<string>();
|
||||
|
||||
// Only astro files
|
||||
|
@ -89,6 +90,7 @@ export async function collectDynamicImports(filename: URL, { astroConfig, loggin
|
|||
astroConfig,
|
||||
resolve,
|
||||
logging,
|
||||
mode,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -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<string>;
|
||||
}
|
||||
|
||||
function internalImport(internalPath: string) {
|
||||
return `/_astro_internal/${internalPath}`;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<string, StyleType> = new Map([
|
|||
['text/scss', 'scss'],
|
||||
]);
|
||||
|
||||
const SASS_OPTIONS: Partial<sass.Options> = {
|
||||
outputStyle: process.env.NODE_ENV === 'production' ? 'compressed' : undefined,
|
||||
};
|
||||
/** HTML tags that should never get scoped classes */
|
||||
const NEVER_SCOPED_TAGS = new Set<string>(['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<string, string>();
|
||||
|
||||
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<StyleTransformResult> {
|
||||
async function transformStyle(code: string, { type, filename, scopedClass, mode }: TransformStyleOptions): Promise<StyleTransformResult> {
|
||||
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[] = []; // <style> tags to be updated
|
||||
const styleTransformPromises: Promise<StyleTransformResult>[] = []; // async style transform results to be finished in finalize();
|
||||
const scopedClass = `astro-${hashFromFilename(fileID)}`; // this *should* generate same hash from fileID every time
|
||||
|
@ -118,6 +129,7 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin
|
|||
type: (langAttr && langAttr.value[0] && langAttr.value[0].data) || undefined,
|
||||
filename,
|
||||
scopedClass,
|
||||
mode: compileOptions.mode,
|
||||
})
|
||||
);
|
||||
return;
|
||||
|
@ -164,6 +176,7 @@ export default function ({ filename, fileID }: { filename: string; fileID: strin
|
|||
type: (langAttr && langAttr.value[0] && langAttr.value[0].data) || undefined,
|
||||
filename,
|
||||
scopedClass,
|
||||
mode: compileOptions.mode,
|
||||
})
|
||||
);
|
||||
},
|
||||
|
|
|
@ -21,7 +21,7 @@ const logging: LogOptions = {
|
|||
export default async function (astroConfig: AstroConfig) {
|
||||
const { projectRoot } = astroConfig;
|
||||
|
||||
const runtime = await createRuntime(astroConfig, { logging });
|
||||
const runtime = await createRuntime(astroConfig, { mode: 'development', logging });
|
||||
|
||||
const server = http.createServer(async (req, res) => {
|
||||
const result = await runtime.load(req.url);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { SnowpackDevServer, ServerRuntime as SnowpackServerRuntime, SnowpackConfig } from 'snowpack';
|
||||
import type { AstroConfig } from './@types/astro';
|
||||
import type { AstroConfig, RuntimeMode } from './@types/astro';
|
||||
import type { LogOptions } from './logger';
|
||||
import type { CompileError } from './parser/utils/error.js';
|
||||
import { debug, info } from './logger.js';
|
||||
|
@ -10,6 +10,7 @@ import { loadConfiguration, logger as snowpackLogger, startServer as startSnowpa
|
|||
interface RuntimeConfig {
|
||||
astroConfig: AstroConfig;
|
||||
logging: LogOptions;
|
||||
mode: RuntimeMode;
|
||||
backendSnowpack: SnowpackDevServer;
|
||||
backendSnowpackRuntime: SnowpackServerRuntime;
|
||||
backendSnowpackConfig: SnowpackConfig;
|
||||
|
@ -129,6 +130,7 @@ export interface AstroRuntime {
|
|||
}
|
||||
|
||||
interface RuntimeOptions {
|
||||
mode: RuntimeMode;
|
||||
logging: LogOptions;
|
||||
}
|
||||
|
||||
|
@ -187,7 +189,7 @@ async function createSnowpack(astroConfig: AstroConfig, env: Record<string, any>
|
|||
return { snowpack, snowpackRuntime, snowpackConfig };
|
||||
}
|
||||
|
||||
export async function createRuntime(astroConfig: AstroConfig, { logging }: RuntimeOptions): Promise<AstroRuntime> {
|
||||
export async function createRuntime(astroConfig: AstroConfig, { mode, logging }: RuntimeOptions): Promise<AstroRuntime> {
|
||||
const { snowpack: backendSnowpack, snowpackRuntime: backendSnowpackRuntime, snowpackConfig: backendSnowpackConfig } = await createSnowpack(astroConfig, {
|
||||
astro: true,
|
||||
});
|
||||
|
@ -199,6 +201,7 @@ export async function createRuntime(astroConfig: AstroConfig, { logging }: Runti
|
|||
const runtimeConfig: RuntimeConfig = {
|
||||
astroConfig,
|
||||
logging,
|
||||
mode,
|
||||
backendSnowpack,
|
||||
backendSnowpackRuntime,
|
||||
backendSnowpackConfig,
|
||||
|
|
Loading…
Reference in a new issue