Remove some more containerisms

This commit is contained in:
Matthew Phillips 2023-02-13 09:47:44 -05:00
parent e12e1e61c1
commit 48efa4beda
2 changed files with 55 additions and 27 deletions

View file

@ -1,5 +1,7 @@
import type { ComponentInstance, ManifestData, RouteData } from '../../@types/astro'; import type { ComponentInstance, ManifestData, RouteData } from '../../@types/astro';
import type { SSRManifest as Manifest } from './types'; import type { SSRManifest as Manifest } from './types';
import { posix } from 'node:path';
import { fileURLToPath } from 'node:url';
import { createContainer, type CreateContainerParams } from '../dev/index.js'; import { createContainer, type CreateContainerParams } from '../dev/index.js';
import { createViteLoader } from '../module-loader/index.js'; import { createViteLoader } from '../module-loader/index.js';
import { createRouteManifest } from '../routing/index.js'; import { createRouteManifest } from '../routing/index.js';
@ -10,10 +12,9 @@ import {
type DevelopmentEnvironment type DevelopmentEnvironment
} from '../render/dev/index.js'; } from '../render/dev/index.js';
import { import {
createRenderContext,
renderPage as coreRenderPage renderPage as coreRenderPage
} from '../render/index.js'; } from '../render/index.js';
import { App, MatchOptions } from './index.js'; import { App } from './index.js';
import { RenderContext, Environment } from '../render'; import { RenderContext, Environment } from '../render';
export type DevAppParams = Partial<CreateContainerParams> & { export type DevAppParams = Partial<CreateContainerParams> & {
@ -53,6 +54,14 @@ export class DevApp extends App {
return !!this.#container; return !!this.#container;
} }
url(pathname: string): string | undefined {
if(!this.loaded) {
return undefined;
}
const { host, port } = this.#container!.settings.config.server
return new URL(pathname, `http://${host}:${port}`).toString();
}
async load() { async load() {
if(this.loaded) { if(this.loaded) {
await this.close(); await this.close();
@ -86,6 +95,19 @@ export class DevApp extends App {
await this.#container?.close(); await this.#container?.close();
} }
fileChanged(path: string) {
const container = this.#container!;
const fs = this.#createContainerParams.fs!;
const root = fileURLToPath(this.#root);
const fullPath = posix.join(root, path);
container.viteServer.watcher.emit('change', fullPath);
if (!fileURLToPath(container.settings.config.root).startsWith('/')) {
const drive = fileURLToPath(container.settings.config.root).slice(0, 2);
container.viteServer.watcher.emit('change', drive + fullPath);
}
}
async render(request: Request, route?: RouteData | undefined): Promise<Response> { async render(request: Request, route?: RouteData | undefined): Promise<Response> {
if(!this.loaded) { if(!this.loaded) {
await this.load(); await this.load();

View file

@ -1,6 +1,7 @@
import { expect } from 'chai'; import { expect } from 'chai';
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
import { DevApp } from '../../../dist/core/app/dev.js';
import { runInContainer } from '../../../dist/core/dev/index.js'; import { runInContainer } from '../../../dist/core/dev/index.js';
import { createFs, createRequestAndResponse, triggerFSEvent } from '../test-utils.js'; import { createFs, createRequestAndResponse, triggerFSEvent } from '../test-utils.js';
@ -25,17 +26,21 @@ describe('dev container', () => {
root root
); );
await runInContainer({ fs, root }, async (container) => { const app = new DevApp({ fs, root });
const { req, res, text } = createRequestAndResponse({ try {
method: 'GET', await app.load();
url: '/', const request = new Request(app.url('/'));
});
container.handle(req, res); const response = await app.render(request);
const html = await text(); expect(response.status).to.equal(200);
const html = await response.text();
const $ = cheerio.load(html); const $ = cheerio.load(html);
expect(res.statusCode).to.equal(200);
expect($('h1')).to.have.a.lengthOf(1); expect($('h1')).to.have.a.lengthOf(1);
}); } finally {
await app.close();
}
}); });
it('HMR only short circuits on previously cached modules', async () => { it('HMR only short circuits on previously cached modules', async () => {
@ -60,13 +65,14 @@ describe('dev container', () => {
root root
); );
await runInContainer({ fs, root }, async (container) => { const app = new DevApp({ fs, root });
let r = createRequestAndResponse({ try {
method: 'GET', await app.load();
url: '/',
}); let request = new Request(app.url('/'));
container.handle(r.req, r.res); let response = await app.render(request);
let html = await r.text();
let html = await response.text();
let $ = cheerio.load(html); let $ = cheerio.load(html);
expect($('body.one')).to.have.a.lengthOf(1); expect($('body.one')).to.have.a.lengthOf(1);
@ -76,7 +82,7 @@ describe('dev container', () => {
<h1>{Astro.props.title}</h1> <h1>{Astro.props.title}</h1>
` `
); );
triggerFSEvent(container, fs, '/src/components/Header.astro', 'change'); app.fileChanged('/src/components/Header.astro');
fs.writeFileFromRootSync( fs.writeFileFromRootSync(
'/src/pages/index.astro', '/src/pages/index.astro',
@ -93,18 +99,18 @@ describe('dev container', () => {
</html> </html>
` `
); );
triggerFSEvent(container, fs, '/src/pages/index.astro', 'change'); app.fileChanged('/src/pages/index.astro');
r = createRequestAndResponse({ request = new Request(app.url('/'));
method: 'GET', response = await app.render(request);
url: '/', html = await response.text();
});
container.handle(r.req, r.res);
html = await r.text();
$ = cheerio.load(html); $ = cheerio.load(html);
expect($('body.one')).to.have.a.lengthOf(0); expect($('body.one')).to.have.a.lengthOf(0);
expect($('body.two')).to.have.a.lengthOf(1); expect($('body.two')).to.have.a.lengthOf(1);
});
} finally {
await app.close();
}
}); });
it('Allows dynamic segments in injected routes', async () => { it('Allows dynamic segments in injected routes', async () => {