diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/@types/optimizer.ts | 2 | ||||
-rw-r--r-- | src/compiler/optimize/doctype.ts | 33 | ||||
-rw-r--r-- | src/compiler/optimize/index.ts | 13 | ||||
-rw-r--r-- | src/frontend/h.ts | 9 | ||||
-rw-r--r-- | src/runtime.ts | 30 |
5 files changed, 71 insertions, 16 deletions
diff --git a/src/@types/optimizer.ts b/src/@types/optimizer.ts index b9e228f3e..22027d2e2 100644 --- a/src/@types/optimizer.ts +++ b/src/@types/optimizer.ts @@ -1,6 +1,6 @@ import type { TemplateNode } from '../parser/interfaces'; -export type VisitorFn = (node: TemplateNode) => void; +export type VisitorFn = (node: TemplateNode, parent: TemplateNode, type: string, index: number) => void; export interface NodeVisitor { enter?: VisitorFn; diff --git a/src/compiler/optimize/doctype.ts b/src/compiler/optimize/doctype.ts new file mode 100644 index 000000000..a666876bf --- /dev/null +++ b/src/compiler/optimize/doctype.ts @@ -0,0 +1,33 @@ +import { Optimizer } from '../../@types/optimizer'; + +export default function (_opts: { filename: string; fileID: string }): Optimizer { + let hasDoctype = false; + + return { + visitors: { + html: { + Element: { + enter(node, parent, _key, index) { + if(node.name === '!doctype') { + hasDoctype = true; + } + if(node.name === 'html' && !hasDoctype) { + const dtNode = { + start: 0, end: 0, + attributes: [{ type: 'Attribute', name: 'html', value: true, start: 0, end: 0 }], + children: [], + name: '!doctype', + type: 'Element' + }; + parent.children!.splice(index, 0, dtNode); + hasDoctype = true; + } + } + } + } + }, + async finalize() { + // Nothing happening here. + } + } +}
\ No newline at end of file diff --git a/src/compiler/optimize/index.ts b/src/compiler/optimize/index.ts index aa5ca58f3..d86ce3c24 100644 --- a/src/compiler/optimize/index.ts +++ b/src/compiler/optimize/index.ts @@ -1,7 +1,10 @@ import { walk } from 'estree-walker'; import type { Ast, TemplateNode } from '../../parser/interfaces'; import { NodeVisitor, Optimizer, VisitorFn } from '../../@types/optimizer'; + +// Optimizers import optimizeStyles from './styles.js'; +import optimizeDoctype from './doctype.js'; interface VisitorCollection { enter: Map<string, VisitorFn[]>; @@ -44,19 +47,19 @@ function createVisitorCollection() { function walkAstWithVisitors(tmpl: TemplateNode, collection: VisitorCollection) { walk(tmpl, { - enter(node) { + enter(node, parent, key, index) { if (collection.enter.has(node.type)) { const fns = collection.enter.get(node.type)!; for (let fn of fns) { - fn(node); + fn(node, parent, key, index); } } }, - leave(node) { + leave(node, parent, key, index) { if (collection.leave.has(node.type)) { const fns = collection.leave.get(node.type)!; for (let fn of fns) { - fn(node); + fn(node, parent, key, index); } } }, @@ -73,7 +76,7 @@ export async function optimize(ast: Ast, opts: OptimizeOptions) { const cssVisitors = createVisitorCollection(); const finalizers: Array<() => Promise<void>> = []; - const optimizers = [optimizeStyles(opts)]; + const optimizers = [optimizeStyles(opts), optimizeDoctype(opts)]; for (const optimizer of optimizers) { collectVisitors(optimizer, htmlVisitors, cssVisitors, finalizers); diff --git a/src/frontend/h.ts b/src/frontend/h.ts index cd94583f8..70965e135 100644 --- a/src/frontend/h.ts +++ b/src/frontend/h.ts @@ -6,6 +6,15 @@ export type HTag = string | AstroComponent; const voidTags = new Set(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']); function* _h(tag: string, attrs: HProps, children: Array<HChild>) { + if(tag === '!doctype') { + yield '<!doctype '; + if(attrs) { + yield Object.keys(attrs).join(' '); + } + yield '>'; + return; + } + yield `<${tag}`; if (attrs) { yield ' '; diff --git a/src/runtime.ts b/src/runtime.ts index ac6d4664a..1b7261dfc 100644 --- a/src/runtime.ts +++ b/src/runtime.ts @@ -2,12 +2,14 @@ import type { SnowpackDevServer, ServerRuntime as SnowpackServerRuntime, LoadRes import type { AstroConfig } from './@types/astro'; import type { LogOptions } from './logger'; import type { CompileError } from './parser/utils/error.js'; -import { info, error, parseError } from './logger.js'; +import { info } from './logger.js'; -import { existsSync, promises as fsPromises } from 'fs'; -import { loadConfiguration, startServer as startSnowpackServer } from 'snowpack'; - -const { readFile } = fsPromises; +import { existsSync } from 'fs'; +import { + loadConfiguration, + logger as snowpackLogger, + startServer as startSnowpackServer +} from 'snowpack'; interface RuntimeConfig { astroConfig: AstroConfig; @@ -27,6 +29,9 @@ type LoadResultError = { statusCode: 500 } & ({ type: 'parse-error'; error: Comp export type LoadResult = LoadResultSuccess | LoadResultNotFound | LoadResultError; +// Disable snowpack from writing to stdout/err. +snowpackLogger.level = 'silent'; + async function load(config: RuntimeConfig, rawPathname: string | undefined): Promise<LoadResult> { const { logging, snowpack, snowpackRuntime } = config; const { astroRoot } = config.astroConfig; @@ -130,13 +135,18 @@ export async function createRuntime(astroConfig: AstroConfig, { logging }: Runti resolve: async (pkgName: string) => snowpack.getUrlForPackage(pkgName), }; + const mountOptions = { + [astroRoot.pathname]: '/_astro', + [internalPath.pathname]: '/_astro_internal' + } + + if(existsSync(astroConfig.public)) { + mountOptions[astroConfig.public.pathname] = '/'; + } + const snowpackConfig = await loadConfiguration({ root: projectRoot.pathname, - mount: { - [astroRoot.pathname]: '/_astro', - [internalPath.pathname]: '/_astro_internal', - public: '/', - }, + mount: mountOptions, plugins: [[new URL('../snowpack-plugin.cjs', import.meta.url).pathname, astroPlugOptions], '@snowpack/plugin-sass', '@snowpack/plugin-svelte', '@snowpack/plugin-vue'], devOptions: { open: 'none', |