mirror of
https://github.com/withastro/astro.git
synced 2025-03-17 23:11:29 -05:00
Bundle everything, commit 1
This commit is contained in:
parent
8eb9325d3a
commit
09346286e4
29 changed files with 428 additions and 189 deletions
|
@ -1,10 +1,10 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import svelte from '@astrojs/svelte';
|
||||
import nodejs from '@astrojs/node';
|
||||
import deno from '@astrojs/deno';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
adapter: nodejs(),
|
||||
adapter: deno(),
|
||||
integrations: [svelte()],
|
||||
vite: {
|
||||
server: {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/svelte": "^0.0.2-next.0",
|
||||
"@astrojs/node": "^0.0.2-next.0",
|
||||
"@astrojs/deno": "^0.0.2-next.0",
|
||||
"astro": "^0.25.0-next.3",
|
||||
"concurrently": "^7.0.0",
|
||||
"lightcookie": "^1.0.25",
|
||||
|
|
|
@ -3,7 +3,7 @@ import TextDecorationSkip from './TextDecorationSkip.astro';
|
|||
import Cart from './Cart.svelte';
|
||||
import { getCart } from '../api';
|
||||
|
||||
const cart = await getCart();
|
||||
const cart = { items: [] };// await getCart();
|
||||
const cartCount = cart.items.reduce((sum, item) => sum + item.count, 0);
|
||||
---
|
||||
<style>
|
||||
|
|
|
@ -5,7 +5,7 @@ import ProductListing from '../components/ProductListing.astro';
|
|||
import { getProducts } from '../api';
|
||||
import '../styles/common.css';
|
||||
|
||||
const products = await getProducts();
|
||||
const products = [];// await getProducts();
|
||||
---
|
||||
<html>
|
||||
<head>
|
||||
|
|
|
@ -136,6 +136,7 @@
|
|||
"@types/mime": "^2.0.3",
|
||||
"@types/mocha": "^9.1.0",
|
||||
"@types/parse5": "^6.0.3",
|
||||
"@types/readable-stream": "^2.3.13",
|
||||
"@types/resolve": "^1.20.1",
|
||||
"@types/rimraf": "^3.0.2",
|
||||
"@types/send": "^0.17.1",
|
||||
|
@ -145,6 +146,7 @@
|
|||
"cheerio": "^1.0.0-rc.10",
|
||||
"execa": "^6.1.0",
|
||||
"mocha": "^9.2.2",
|
||||
"readable-stream": "^3.6.0",
|
||||
"sass": "^1.49.9"
|
||||
},
|
||||
"engines": {
|
||||
|
|
|
@ -4,6 +4,7 @@ import type * as vite from 'vite';
|
|||
import type { z } from 'zod';
|
||||
import type { AstroConfigSchema } from '../core/config';
|
||||
import type { AstroComponentFactory, Metadata } from '../runtime/server';
|
||||
import type { ViteConfigWithSSR } from '../core/create-vite';
|
||||
export type { SSRManifest } from '../core/app/types';
|
||||
|
||||
export interface AstroBuiltinProps {
|
||||
|
@ -677,6 +678,7 @@ export interface AstroIntegration {
|
|||
'astro:server:start'?: (options: { address: AddressInfo }) => void | Promise<void>;
|
||||
'astro:server:done'?: () => void | Promise<void>;
|
||||
'astro:build:start'?: (options: { buildConfig: BuildConfig }) => void | Promise<void>;
|
||||
'astro:build:server:setup': (options: { vite: ViteConfigWithSSR }) => void;
|
||||
'astro:build:done'?: (options: { pages: { pathname: string }[]; dir: URL; routes: RouteData[] }) => void | Promise<void>;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -81,8 +81,7 @@ export class App {
|
|||
routeCache: this.#routeCache,
|
||||
site: this.#manifest.site,
|
||||
ssr: true,
|
||||
method: info.routeData.type === 'endpoint' ? '' : 'GET',
|
||||
headers: request.headers,
|
||||
request,
|
||||
});
|
||||
|
||||
if (result.type === 'response') {
|
||||
|
|
|
@ -20,6 +20,7 @@ import { vitePluginPages } from './vite-plugin-pages.js';
|
|||
import { generatePages } from './generate.js';
|
||||
import { trackPageData } from './internal.js';
|
||||
import { isBuildingToSSR } from '../util.js';
|
||||
import { runHookBuildServerSetup } from '../../integrations/index.js';
|
||||
import { getTimeStat } from './util.js';
|
||||
|
||||
export async function staticBuild(opts: StaticBuildOptions) {
|
||||
|
@ -114,8 +115,8 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
|
|||
const { astroConfig, viteConfig } = opts;
|
||||
const ssr = astroConfig.buildOptions.experimentalSsr;
|
||||
const out = ssr ? opts.buildConfig.server : astroConfig.dist;
|
||||
// TODO: use vite.mergeConfig() here?
|
||||
return await vite.build({
|
||||
|
||||
const viteBuildConfig = {
|
||||
logLevel: 'error',
|
||||
mode: 'production',
|
||||
css: viteConfig.css,
|
||||
|
@ -124,7 +125,6 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
|
|||
emptyOutDir: false,
|
||||
manifest: false,
|
||||
outDir: fileURLToPath(out),
|
||||
ssr: true,
|
||||
rollupOptions: {
|
||||
input: [],
|
||||
output: {
|
||||
|
@ -135,6 +135,7 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
|
|||
inlineDynamicImports: true,
|
||||
},
|
||||
},
|
||||
ssr: true,
|
||||
// must match an esbuild target
|
||||
target: 'esnext',
|
||||
// improve build performance
|
||||
|
@ -158,7 +159,13 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp
|
|||
server: viteConfig.server,
|
||||
base: astroConfig.buildOptions.site ? new URL(astroConfig.buildOptions.site).pathname : '/',
|
||||
ssr: viteConfig.ssr,
|
||||
} as ViteConfigWithSSR);
|
||||
resolve: viteConfig.resolve
|
||||
} as ViteConfigWithSSR;
|
||||
|
||||
await runHookBuildServerSetup({ config: astroConfig, vite: viteBuildConfig });
|
||||
|
||||
// TODO: use vite.mergeConfig() here?
|
||||
return await vite.build(viteBuildConfig);
|
||||
}
|
||||
|
||||
async function clientBuild(opts: StaticBuildOptions, internals: BuildInternals, input: Set<string>) {
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
import type { AstroConfig } from '../@types/astro';
|
||||
import { bold, cyan, dim, red, yellow, reset } from 'kleur/colors';
|
||||
import { performance } from 'perf_hooks';
|
||||
import { Writable } from 'stream';
|
||||
import stringWidth from 'string-width';
|
||||
import * as readline from 'readline';
|
||||
import debugPackage from 'debug';
|
||||
//import debugPackage from 'debug';
|
||||
import { format as utilFormat } from 'util';
|
||||
import { isBuildingToSSR } from './util.js';
|
||||
|
||||
type ConsoleStream = Writable & {
|
||||
fd: 1 | 2;
|
||||
};
|
||||
|
||||
function getLoggerLocale(): string {
|
||||
const defaultLocale = 'en-US';
|
||||
|
@ -29,14 +21,15 @@ const dt = new Intl.DateTimeFormat(getLoggerLocale(), {
|
|||
second: '2-digit',
|
||||
});
|
||||
|
||||
|
||||
|
||||
let lastMessage: string;
|
||||
let lastMessageCount = 1;
|
||||
export const defaultLogDestination = new Writable({
|
||||
objectMode: true,
|
||||
write(event: LogMessage, _, callback) {
|
||||
let dest: ConsoleStream = process.stderr;
|
||||
export const defaultLogDestination = {
|
||||
write(event: LogMessage) {
|
||||
let dest = console.error;
|
||||
if (levels[event.level] < levels['error']) {
|
||||
dest = process.stdout;
|
||||
dest = console.log;
|
||||
}
|
||||
|
||||
function getPrefix() {
|
||||
|
@ -65,14 +58,14 @@ export const defaultLogDestination = new Writable({
|
|||
if (levels[event.level] < levels['error']) {
|
||||
let lines = 1;
|
||||
let len = stringWidth(`${getPrefix()}${message}`);
|
||||
let cols = (dest as typeof process.stdout).columns;
|
||||
let cols = (dest as unknown as typeof process.stdout).columns;
|
||||
if (len > cols) {
|
||||
lines = Math.ceil(len / cols);
|
||||
}
|
||||
for (let i = 0; i < lines; i++) {
|
||||
readline.clearLine(dest, 0);
|
||||
/*readline.clearLine(dest, 0);
|
||||
readline.cursorTo(dest, 0);
|
||||
readline.moveCursor(dest, 0, -1);
|
||||
readline.moveCursor(dest, 0, -1);*/
|
||||
}
|
||||
}
|
||||
message = `${message} ${yellow(`(x${lastMessageCount})`)}`;
|
||||
|
@ -80,15 +73,14 @@ export const defaultLogDestination = new Writable({
|
|||
lastMessage = message;
|
||||
lastMessageCount = 1;
|
||||
}
|
||||
dest.write(getPrefix());
|
||||
dest.write(message);
|
||||
dest.write('\n');
|
||||
|
||||
callback();
|
||||
dest(getPrefix());
|
||||
dest(message);
|
||||
dest('\n');
|
||||
return true;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
interface LogWritable<T> extends Writable {
|
||||
interface LogWritable<T> {
|
||||
write: (chunk: T) => boolean;
|
||||
}
|
||||
|
||||
|
@ -121,7 +113,7 @@ export const levels: Record<LoggerLevel, number> = {
|
|||
};
|
||||
|
||||
export function enableVerboseLogging() {
|
||||
debugPackage.enable('*,-babel');
|
||||
//debugPackage.enable('*,-babel');
|
||||
debug('cli', '--verbose flag enabled! Enabling: DEBUG="*,-babel"');
|
||||
debug('cli', 'Tip: Set the DEBUG env variable directly for more control. Example: "DEBUG=astro:*,vite:* astro build".');
|
||||
}
|
||||
|
@ -154,7 +146,7 @@ const debuggers: Record<string, debugPackage.Debugger['log']> = {};
|
|||
*/
|
||||
export function debug(type: string, ...messages: Array<any>) {
|
||||
const namespace = `astro:${type}`;
|
||||
debuggers[namespace] = debuggers[namespace] || debugPackage(namespace);
|
||||
debuggers[namespace] = debuggers[namespace] || (() => {});// debugPackage(namespace);
|
||||
return debuggers[namespace](...messages);
|
||||
}
|
||||
|
||||
|
@ -199,17 +191,21 @@ function padStr(str: string, len: number) {
|
|||
}
|
||||
|
||||
export let defaultLogLevel: LoggerLevel;
|
||||
if (process.argv.includes('--verbose')) {
|
||||
defaultLogLevel = 'debug';
|
||||
} else if (process.argv.includes('--silent')) {
|
||||
defaultLogLevel = 'silent';
|
||||
if(typeof process !== 'undefined') {
|
||||
if (process.argv.includes('--verbose')) {
|
||||
defaultLogLevel = 'debug';
|
||||
} else if (process.argv.includes('--silent')) {
|
||||
defaultLogLevel = 'silent';
|
||||
} else {
|
||||
defaultLogLevel = 'info';
|
||||
}
|
||||
} else {
|
||||
defaultLogLevel = 'info';
|
||||
}
|
||||
|
||||
/** Print out a timer message for debug() */
|
||||
export function timerMessage(message: string, startTime: number = performance.now()) {
|
||||
let timeDiff = performance.now() - startTime;
|
||||
export function timerMessage(message: string, startTime: number = Date.now()) {
|
||||
let timeDiff = Date.now() - startTime;
|
||||
let timeDisplay = timeDiff < 750 ? `${Math.round(timeDiff)}ms` : `${(timeDiff / 1000).toFixed(1)}s`;
|
||||
return `${message} ${dim(timeDisplay)}`;
|
||||
}
|
||||
|
@ -218,7 +214,7 @@ export function timerMessage(message: string, startTime: number = performance.no
|
|||
* A warning that SSR is experimental. Remove when we can.
|
||||
*/
|
||||
export function warnIfUsingExperimentalSSR(opts: LogOptions, config: AstroConfig) {
|
||||
if (isBuildingToSSR(config)) {
|
||||
if (config._ctx.adapter?.serverEntrypoint) {
|
||||
warn(
|
||||
opts,
|
||||
'warning',
|
||||
|
|
|
@ -2,7 +2,7 @@ import type { ComponentInstance, EndpointHandler, MarkdownRenderOptions, Params,
|
|||
import type { LogOptions } from '../logger.js';
|
||||
|
||||
import { renderHead, renderPage } from '../../runtime/server/index.js';
|
||||
import { getParams } from '../routing/index.js';
|
||||
import { getParams } from '../routing/params.js';
|
||||
import { createResult } from './result.js';
|
||||
import { findPathItemByKey, RouteCache, callGetStaticPaths } from './route-cache.js';
|
||||
|
||||
|
|
|
@ -2,16 +2,7 @@ import type * as vite from 'vite';
|
|||
|
||||
import path from 'path';
|
||||
import { unwrapId, viteID } from '../../util.js';
|
||||
|
||||
// https://vitejs.dev/guide/features.html#css-pre-processors
|
||||
export const STYLE_EXTENSIONS = new Set(['.css', '.pcss', '.postcss', '.scss', '.sass', '.styl', '.stylus', '.less']);
|
||||
|
||||
const cssRe = new RegExp(
|
||||
`\\.(${Array.from(STYLE_EXTENSIONS)
|
||||
.map((s) => s.slice(1))
|
||||
.join('|')})($|\\?)`
|
||||
);
|
||||
export const isCSSRequest = (request: string): boolean => cssRe.test(request);
|
||||
import { STYLE_EXTENSIONS } from '../util.js';
|
||||
|
||||
/** Given a filePath URL, crawl Vite’s module graph to find all style imports. */
|
||||
export function getStylesForURL(filePath: URL, viteServer: vite.ViteDevServer): Set<string> {
|
||||
|
|
103
packages/astro/src/core/render/pretty-feed.ts
Normal file
103
packages/astro/src/core/render/pretty-feed.ts
Normal file
File diff suppressed because one or more lines are too long
|
@ -2,8 +2,7 @@ import { bold } from 'kleur/colors';
|
|||
import type { AstroGlobal, AstroGlobalPartial, MarkdownParser, MarkdownRenderOptions, Params, SSRElement, SSRLoadedRenderer, SSRResult } from '../../@types/astro';
|
||||
import { renderSlot } from '../../runtime/server/index.js';
|
||||
import { LogOptions, warn } from '../logger.js';
|
||||
import { isCSSRequest } from './dev/css.js';
|
||||
import { canonicalURL as utilCanonicalURL } from '../util.js';
|
||||
import { createCanonicalURL, isCSSRequest } from './util.js';
|
||||
import { isScriptRequest } from './script.js';
|
||||
|
||||
function onlyAvailableInSSR(name: string) {
|
||||
|
@ -71,10 +70,10 @@ class Slots {
|
|||
}
|
||||
|
||||
export function createResult(args: CreateResultArgs): SSRResult {
|
||||
const { legacyBuild, markdownRender, origin, params, pathname, renderers, request, resolve, site } = args;
|
||||
const { legacyBuild, markdownRender, params, pathname, renderers, request, resolve, site } = args;
|
||||
|
||||
const url = new URL(request.url);
|
||||
const canonicalURL = utilCanonicalURL('.' + pathname, site ?? url.origin);
|
||||
const canonicalURL = createCanonicalURL('.' + pathname, site ?? url.origin);
|
||||
|
||||
// Create the result object that will be passed into the render function.
|
||||
// This object starts here as an empty shell (not yet the result) but then
|
||||
|
|
|
@ -2,7 +2,7 @@ import type { ComponentInstance, GetStaticPathsItem, GetStaticPathsResult, GetSt
|
|||
import { LogOptions, warn, debug } from '../logger.js';
|
||||
|
||||
import { generatePaginateFunction } from './paginate.js';
|
||||
import { validateGetStaticPathsModule, validateGetStaticPathsResult } from '../routing/index.js';
|
||||
import { validateGetStaticPathsModule, validateGetStaticPathsResult } from '../routing/validation.js';
|
||||
|
||||
type RSSFn = (...args: any[]) => any;
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import type { RSSFunction, RSS, RSSResult, RouteData } from '../../@types/astro';
|
||||
|
||||
import { XMLValidator } from 'fast-xml-parser';
|
||||
import { canonicalURL, isValidURL, PRETTY_FEED_V3 } from '../util.js';
|
||||
import { PRETTY_FEED_V3 } from './pretty-feed.js';
|
||||
import { createCanonicalURL, isValidURL } from './util.js';
|
||||
|
||||
/** Validates getStaticPaths.rss */
|
||||
export function validateRSS(args: GenerateRSSArgs): void {
|
||||
|
@ -38,7 +39,7 @@ export function generateRSS(args: GenerateRSSArgs): string {
|
|||
// title, description, customData
|
||||
xml += `<title><![CDATA[${rssData.title}]]></title>`;
|
||||
xml += `<description><![CDATA[${rssData.description}]]></description>`;
|
||||
xml += `<link>${canonicalURL(site).href}</link>`;
|
||||
xml += `<link>${createCanonicalURL(site).href}</link>`;
|
||||
if (typeof rssData.customData === 'string') xml += rssData.customData;
|
||||
// items
|
||||
for (const result of rssData.items) {
|
||||
|
@ -49,7 +50,7 @@ export function generateRSS(args: GenerateRSSArgs): string {
|
|||
if (!result.link) throw new Error(`[${srcFile}] rss.items required "link" property is missing. got: "${JSON.stringify(result)}"`);
|
||||
xml += `<title><![CDATA[${result.title}]]></title>`;
|
||||
// If the item's link is already a valid URL, don't mess with it.
|
||||
const itemLink = isValidURL(result.link) ? result.link : canonicalURL(result.link, site).href;
|
||||
const itemLink = isValidURL(result.link) ? result.link : createCanonicalURL(result.link, site).href;
|
||||
xml += `<link>${itemLink}</link>`;
|
||||
xml += `<guid>${itemLink}</guid>`;
|
||||
if (result.description) xml += `<description><![CDATA[${result.description}]]></description>`;
|
||||
|
|
29
packages/astro/src/core/render/util.ts
Normal file
29
packages/astro/src/core/render/util.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import npath from 'path';
|
||||
|
||||
/** Normalize URL to its canonical form */
|
||||
export function createCanonicalURL(url: string, base?: string): URL {
|
||||
let pathname = url.replace(/\/index.html$/, ''); // index.html is not canonical
|
||||
pathname = pathname.replace(/\/1\/?$/, ''); // neither is a trailing /1/ (impl. detail of collections)
|
||||
if (!npath.extname(pathname)) pathname = pathname.replace(/(\/+)?$/, '/'); // add trailing slash if there’s no extension
|
||||
pathname = pathname.replace(/\/+/g, '/'); // remove duplicate slashes (URL() won’t)
|
||||
return new URL(pathname, base);
|
||||
}
|
||||
|
||||
/** Check if a URL is already valid */
|
||||
export function isValidURL(url: string): boolean {
|
||||
try {
|
||||
new URL(url);
|
||||
return true;
|
||||
} catch (e) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://vitejs.dev/guide/features.html#css-pre-processors
|
||||
export const STYLE_EXTENSIONS = new Set(['.css', '.pcss', '.postcss', '.scss', '.sass', '.styl', '.stylus', '.less']);
|
||||
|
||||
const cssRe = new RegExp(
|
||||
`\\.(${Array.from(STYLE_EXTENSIONS)
|
||||
.map((s) => s.slice(1))
|
||||
.join('|')})($|\\?)`
|
||||
);
|
||||
export const isCSSRequest = (request: string): boolean => cssRe.test(request);
|
File diff suppressed because one or more lines are too long
|
@ -3,6 +3,7 @@ import type { ViteDevServer } from 'vite';
|
|||
import { AstroConfig, AstroRenderer, BuildConfig, RouteData } from '../@types/astro.js';
|
||||
import { mergeConfig } from '../core/config.js';
|
||||
import ssgAdapter from '../adapter-ssg/index.js';
|
||||
import type { ViteConfigWithSSR } from '../core/create-vite.js';
|
||||
|
||||
export async function runHookConfigSetup({ config: _config, command }: { config: AstroConfig; command: 'dev' | 'build' }): Promise<AstroConfig> {
|
||||
if (_config.adapter) {
|
||||
|
@ -91,6 +92,14 @@ export async function runHookBuildStart({ config, buildConfig }: { config: Astro
|
|||
}
|
||||
}
|
||||
|
||||
export async function runHookBuildServerSetup({ config, vite }: { config: AstroConfig, vite: ViteConfigWithSSR }) {
|
||||
for (const integration of config.integrations) {
|
||||
if (integration.hooks['astro:build:server:setup']) {
|
||||
await integration.hooks['astro:build:server:setup']({ vite });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function runHookBuildDone({ config, pages, routes }: { config: AstroConfig; pages: string[]; routes: RouteData[] }) {
|
||||
for (const integration of config.integrations) {
|
||||
if (integration.hooks['astro:build:done']) {
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import type { AstroComponentMetadata, SSRLoadedRenderer } from '../../@types/astro';
|
||||
import type { SSRElement, SSRResult } from '../../@types/astro';
|
||||
import { hydrationSpecifier, serializeListValue } from './util.js';
|
||||
import serializeJavaScript from 'serialize-javascript';
|
||||
|
||||
// Serializes props passed into a component so that they can be reused during hydration.
|
||||
// The value is any
|
||||
export function serializeProps(value: any) {
|
||||
return serializeJavaScript(value);
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
|
||||
const HydrationDirectives = ['load', 'idle', 'media', 'visible', 'only'];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import type * as vite from 'vite';
|
||||
|
||||
import { STYLE_EXTENSIONS } from '../core/render/dev/css.js';
|
||||
import { STYLE_EXTENSIONS } from '../core/render/util.js';
|
||||
|
||||
export type TransformHook = (code: string, id: string, ssr?: boolean) => Promise<vite.TransformResult>;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { BuildInternals } from '../core/build/internal';
|
|||
import * as path from 'path';
|
||||
import esbuild from 'esbuild';
|
||||
import { Plugin as VitePlugin } from 'vite';
|
||||
import { isCSSRequest } from '../core/render/dev/css.js';
|
||||
import { isCSSRequest } from '../core/render/util.js';
|
||||
import { getPageDatasByChunk } from '../core/build/internal.js';
|
||||
|
||||
const PLUGIN_NAME = '@astrojs/rollup-plugin-build-css';
|
||||
|
|
7
packages/integrations/deno/CHANGELOG.md
Normal file
7
packages/integrations/deno/CHANGELOG.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# @astrojs/node
|
||||
|
||||
## 0.0.2-next.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#2873](https://github.com/withastro/astro/pull/2873) [`e4025d1f`](https://github.com/withastro/astro/commit/e4025d1f530310d6ab951109f4f53878a307471a) Thanks [@matthewp](https://github.com/matthewp)! - Improves the build by building to a single file for rendering
|
34
packages/integrations/deno/package.json
Normal file
34
packages/integrations/deno/package.json
Normal file
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "@astrojs/deno",
|
||||
"description": "Deploy your site to a Deno server",
|
||||
"version": "0.0.2-next.0",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
"author": "withastro",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/withastro/astro.git",
|
||||
"directory": "packages/integrations/deno"
|
||||
},
|
||||
"bugs": "https://github.com/withastro/astro/issues",
|
||||
"homepage": "https://astro.build",
|
||||
"exports": {
|
||||
".": "./dist/index.js",
|
||||
"./server.js": "./dist/server.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
|
||||
"dev": "astro-scripts dev \"src/**/*.ts\""
|
||||
},
|
||||
"dependencies": {
|
||||
"path-browserify": "^1.0.1",
|
||||
"tty-browserify": "^0.0.1",
|
||||
"events-browserify-mfsu": "^3.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*"
|
||||
}
|
||||
}
|
53
packages/integrations/deno/readme.md
Normal file
53
packages/integrations/deno/readme.md
Normal file
|
@ -0,0 +1,53 @@
|
|||
# @astrojs/node
|
||||
|
||||
An experimental static-side rendering adapter for use with Node.js servers.
|
||||
|
||||
In your astro.config.mjs use:
|
||||
|
||||
```js
|
||||
import nodejs from '@astrojs/node';
|
||||
|
||||
export default {
|
||||
adapter: nodejs()
|
||||
}
|
||||
```
|
||||
|
||||
After performing a build there will be a `dist/server/entry.mjs` module that works like a middleware function. You can use with any framework that supports the Node `request` and `response` objects. For example, with Express you can do:
|
||||
|
||||
```js
|
||||
import express from 'express';
|
||||
import { handler as ssrHandler } from './dist/server/entry.mjs';
|
||||
|
||||
const app = express();
|
||||
app.use(ssrHandler);
|
||||
|
||||
app.listen(8080);
|
||||
```
|
||||
|
||||
# Using `http`
|
||||
|
||||
This adapter does not require you use Express and can work with even the `http` and `https` modules. The adapter does following the Expression convention of calling a function when either
|
||||
|
||||
- A route is not found for the request.
|
||||
- There was an error rendering.
|
||||
|
||||
You can use these to implement your own 404 behavior like so:
|
||||
|
||||
```js
|
||||
import http from 'http';
|
||||
import { handler as ssrHandler } from './dist/server/entry.mjs';
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
ssrHandler(req, res, err => {
|
||||
if(err) {
|
||||
res.writeHead(500);
|
||||
res.end(err.toString());
|
||||
} else {
|
||||
// Serve your static assets here maybe?
|
||||
// 404?
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
}).listen(8080);
|
||||
```
|
43
packages/integrations/deno/src/index.ts
Normal file
43
packages/integrations/deno/src/index.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
import type { AstroAdapter, AstroIntegration } from 'astro';
|
||||
|
||||
|
||||
|
||||
export function getAdapter(): AstroAdapter {
|
||||
return {
|
||||
name: '@astrojs/deno',
|
||||
serverEntrypoint: '@astrojs/deno/server.js',
|
||||
};
|
||||
}
|
||||
|
||||
export default function createIntegration(): AstroIntegration {
|
||||
return {
|
||||
name: '@astrojs/deno',
|
||||
hooks: {
|
||||
'astro:config:setup': ({ config, command }) => {
|
||||
},
|
||||
'astro:config:done': ({ setAdapter }) => {
|
||||
setAdapter(getAdapter());
|
||||
},
|
||||
'astro:build:server:setup': ({ vite }) => {
|
||||
Object.assign(vite, {
|
||||
resolve: {
|
||||
...(vite.resolve ?? {}),
|
||||
alias: {
|
||||
...(vite.resolve?.alias ?? {}),
|
||||
'events': 'events-browserify-mfsu',
|
||||
'path': 'path-browserify',
|
||||
'tty': 'tty-browserify'
|
||||
}
|
||||
},
|
||||
ssr: {
|
||||
...(vite.ssr ?? {})
|
||||
},
|
||||
})
|
||||
vite.ssr = {
|
||||
noExternal: true
|
||||
};
|
||||
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
35
packages/integrations/deno/src/server.ts
Normal file
35
packages/integrations/deno/src/server.ts
Normal file
|
@ -0,0 +1,35 @@
|
|||
import './shim.js';
|
||||
import type { SSRManifest } from 'astro';
|
||||
import { App } from 'astro/app';
|
||||
|
||||
export async function start(manifest: SSRManifest) {
|
||||
const app = new App(manifest);
|
||||
|
||||
// Start listening on port 8080 of localhost.
|
||||
const server = Deno.listen({ port: 8085 });
|
||||
console.log(`HTTP webserver running. Access it at: http://127.0.0.1:8085/`);
|
||||
|
||||
// Connections to the server will be yielded up as an async iterable.
|
||||
for await (const conn of server) {
|
||||
// In order to not be blocking, we need to handle each connection individually
|
||||
// without awaiting the function
|
||||
serveHttp(conn, app);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function render(request: Request, app: App) {
|
||||
const response = await app.render(request);
|
||||
console.log(response)
|
||||
return response;
|
||||
}
|
||||
|
||||
async function serveHttp(conn: Deno.Conn, app: App) {
|
||||
// This "upgrades" a network connection into an HTTP connection.
|
||||
const httpConn = Deno.serveHttp(conn);
|
||||
// Each request sent over the HTTP connection will be yielded as an async
|
||||
// iterator from the HTTP connection.
|
||||
for await (const requestEvent of httpConn) {
|
||||
requestEvent.respondWith(render(requestEvent.request, app))
|
||||
}
|
||||
}
|
5
packages/integrations/deno/src/shim.ts
Normal file
5
packages/integrations/deno/src/shim.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
(globalThis as any).process = {
|
||||
argv: [],
|
||||
env: {}
|
||||
};
|
10
packages/integrations/deno/tsconfig.json
Normal file
10
packages/integrations/deno/tsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"include": ["src"],
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"module": "ES2020",
|
||||
"outDir": "./dist",
|
||||
"target": "ES2020"
|
||||
}
|
||||
}
|
39
pnpm-lock.yaml
generated
39
pnpm-lock.yaml
generated
|
@ -286,7 +286,7 @@ importers:
|
|||
|
||||
examples/ssr:
|
||||
specifiers:
|
||||
'@astrojs/node': ^0.0.2-next.0
|
||||
'@astrojs/deno': ^0.0.2-next.0
|
||||
'@astrojs/svelte': ^0.0.2-next.0
|
||||
astro: ^0.25.0-next.3
|
||||
concurrently: ^7.0.0
|
||||
|
@ -297,7 +297,7 @@ importers:
|
|||
dependencies:
|
||||
svelte: 3.46.4
|
||||
devDependencies:
|
||||
'@astrojs/node': link:../../packages/integrations/node
|
||||
'@astrojs/deno': link:../../packages/integrations/deno
|
||||
'@astrojs/svelte': link:../../packages/integrations/svelte
|
||||
astro: link:../../packages/astro
|
||||
concurrently: 7.0.0
|
||||
|
@ -463,6 +463,7 @@ importers:
|
|||
'@types/mime': ^2.0.3
|
||||
'@types/mocha': ^9.1.0
|
||||
'@types/parse5': ^6.0.3
|
||||
'@types/readable-stream': ^2.3.13
|
||||
'@types/resolve': ^1.20.1
|
||||
'@types/rimraf': ^3.0.2
|
||||
'@types/send': ^0.17.1
|
||||
|
@ -494,6 +495,7 @@ importers:
|
|||
postcss: ^8.4.12
|
||||
postcss-load-config: ^3.1.3
|
||||
prismjs: ^1.27.0
|
||||
readable-stream: ^3.6.0
|
||||
rehype-slug: ^5.0.1
|
||||
resolve: ^1.22.0
|
||||
rollup: ^2.70.1
|
||||
|
@ -576,6 +578,7 @@ importers:
|
|||
'@types/mime': 2.0.3
|
||||
'@types/mocha': 9.1.0
|
||||
'@types/parse5': 6.0.3
|
||||
'@types/readable-stream': 2.3.13
|
||||
'@types/resolve': 1.20.1
|
||||
'@types/rimraf': 3.0.2
|
||||
'@types/send': 0.17.1
|
||||
|
@ -585,6 +588,7 @@ importers:
|
|||
cheerio: 1.0.0-rc.10
|
||||
execa: 6.1.0
|
||||
mocha: 9.2.2
|
||||
readable-stream: 3.6.0
|
||||
sass: 1.49.9
|
||||
|
||||
packages/astro-prism:
|
||||
|
@ -1166,6 +1170,21 @@ importers:
|
|||
astro-scripts: link:../../scripts
|
||||
uvu: 0.5.3
|
||||
|
||||
packages/integrations/deno:
|
||||
specifiers:
|
||||
astro: workspace:*
|
||||
astro-scripts: workspace:*
|
||||
events-browserify-mfsu: ^3.2.0
|
||||
path-browserify: ^1.0.1
|
||||
tty-browserify: ^0.0.1
|
||||
dependencies:
|
||||
events-browserify-mfsu: 3.2.0
|
||||
path-browserify: 1.0.1
|
||||
tty-browserify: 0.0.1
|
||||
devDependencies:
|
||||
astro: link:../../astro
|
||||
astro-scripts: link:../../../scripts
|
||||
|
||||
packages/integrations/lit:
|
||||
specifiers:
|
||||
'@lit-labs/ssr': ^2.0.4
|
||||
|
@ -3962,6 +3981,13 @@ packages:
|
|||
csstype: 3.0.11
|
||||
dev: false
|
||||
|
||||
/@types/readable-stream/2.3.13:
|
||||
resolution: {integrity: sha512-4JSCx8EUzaW9Idevt+9lsRAt1lcSccoQfE+AouM1gk8sFxnnytKNIO3wTl9Dy+4m6jRJ1yXhboLHHT/LXBQiEw==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.23
|
||||
safe-buffer: 5.2.1
|
||||
dev: true
|
||||
|
||||
/@types/resolve/1.17.1:
|
||||
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
|
||||
dependencies:
|
||||
|
@ -6111,6 +6137,11 @@ packages:
|
|||
engines: {node: '>=10.13.0'}
|
||||
dev: true
|
||||
|
||||
/events-browserify-mfsu/3.2.0:
|
||||
resolution: {integrity: sha512-d7B0Bt1LhUXUmWmyhByqE0pbuWKUUp3QVkpfqPs8z3LWNLscd+mnq7PMRYNRVoEm1Yh67JwkYnT6RbDg8VlJdQ==}
|
||||
engines: {node: '>=0.8.x'}
|
||||
dev: false
|
||||
|
||||
/execa/5.1.1:
|
||||
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -9884,6 +9915,10 @@ packages:
|
|||
typescript: 4.6.3
|
||||
dev: true
|
||||
|
||||
/tty-browserify/0.0.1:
|
||||
resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==}
|
||||
dev: false
|
||||
|
||||
/tty-table/2.8.13:
|
||||
resolution: {integrity: sha512-eVV/+kB6fIIdx+iUImhXrO22gl7f6VmmYh0Zbu6C196fe1elcHXd7U6LcLXu0YoVPc2kNesWiukYcdK8ZmJ6aQ==}
|
||||
engines: {node: '>=8.16.0'}
|
||||
|
|
Loading…
Add table
Reference in a new issue