Skip to content

Commit

Permalink
add basename to graphql endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
KutnerUri committed Nov 8, 2021
1 parent e055759 commit 25dd1a9
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 18 deletions.
4 changes: 3 additions & 1 deletion scopes/harmony/graphql/graphql.main.runtime.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { mergeSchemas } from 'graphql-tools';
import urljoin from 'url-join';
import { GraphQLModule } from '@graphql-modules/core';
import { MainRuntime } from '@teambit/cli';
import { Harmony, Slot, SlotRegistry } from '@teambit/harmony';
Expand Down Expand Up @@ -39,6 +40,7 @@ export type GraphQLServerOptions = {
remoteSchemas?: GraphQLServer[];
subscriptionsPortRange?: number[];
onWsConnect?: Function;
urlBasename?: string;
};

export class GraphqlMain {
Expand Down Expand Up @@ -95,7 +97,7 @@ export class GraphqlMain {
);

app.use(
'/graphql',
urljoin(options.urlBasename || '/', 'graphql'),
// eslint-disable-next-line @typescript-eslint/no-misused-promises
graphqlHTTP((request, res, params) => ({
customFormatErrorFn: (err) => {
Expand Down
23 changes: 14 additions & 9 deletions scopes/ui-foundation/ui/ssr/render-middleware.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Assets } from '@teambit/ui-foundation.ui.rendering.html';
import { Request, Response, NextFunction } from 'express';
import path from 'path';
import urlJoin from 'url-join';
import * as fs from 'fs-extra';
import type { Logger } from '@teambit/logger';
import { requestToObj } from './request-browser';
Expand All @@ -9,19 +10,23 @@ import { SsrContent } from './ssr-content';
const denyList = /^\/favicon.ico$/;

type ssrRenderProps = {
/** root folder for static files (usually '/public') */
root: string;
port: number;
/** html title tag */
title: string;
logger: Logger;
/** site base url */
urlBasename?: string;
};

type ManifestFile = {
files?: Record<string, string>;
entrypoints?: string[];
};

export async function createSsrMiddleware({ root, port, title, logger }: ssrRenderProps) {
const runtime = await loadRuntime(root, { logger });
export async function createSsrMiddleware({ root, port, title, logger, urlBasename }: ssrRenderProps) {
const runtime = await loadRuntime(root, { logger, urlBasename });
if (!runtime) return undefined;

const { render } = runtime;
Expand Down Expand Up @@ -60,7 +65,7 @@ export async function createSsrMiddleware({ root, port, title, logger }: ssrRend
};
}

async function loadRuntime(root: string, { logger }: { logger: Logger }) {
async function loadRuntime(root: string, { logger, urlBasename }: { logger: Logger; urlBasename?: string }) {
let render: (...arg: any[]) => any;
let assets: Assets | undefined;

Expand All @@ -77,7 +82,7 @@ async function loadRuntime(root: string, { logger }: { logger: Logger }) {
return undefined;
}

assets = await parseManifest(manifestFilepath);
assets = await parseManifest(manifestFilepath, logger, urlBasename);
if (!assets) {
logger.warn('[ssr] - Skipping setup (failed parsing assets manifest)');
return undefined;
Expand All @@ -101,14 +106,14 @@ async function loadRuntime(root: string, { logger }: { logger: Logger }) {
};
}

async function parseManifest(filepath: string, logger?: Logger) {
async function parseManifest(filepath: string, logger?: Logger, urlBasename?: string) {
try {
const file = await fs.readFile(filepath);
logger?.debug('[ssr] - ✓ aread manifest file');
const contents = file.toString();
const parsed: ManifestFile = JSON.parse(contents);
logger?.debug('[ssr] - ✓ prased manifest file', parsed);
const assets = getAssets(parsed);
const assets = getAssets(parsed, urlBasename);
logger?.debug('[ssr] - ✓ extracted data from manifest file', assets);

return assets;
Expand All @@ -119,11 +124,11 @@ async function parseManifest(filepath: string, logger?: Logger) {
}
}

function getAssets(manifest: ManifestFile) {
function getAssets(manifest: ManifestFile, urlBasename = '/') {
const assets: Assets = { css: [], js: [] };

assets.css = manifest.entrypoints?.filter((x) => x.endsWith('css')).map((x) => path.join('/', x));
assets.js = manifest.entrypoints?.filter((x) => x.endsWith('js')).map((x) => path.join('/', x));
assets.css = manifest.entrypoints?.filter((x) => x.endsWith('css')).map((x) => urlJoin(urlBasename, x));
assets.js = manifest.entrypoints?.filter((x) => x.endsWith('js')).map((x) => urlJoin(urlBasename, x));

return assets;
}
26 changes: 21 additions & 5 deletions scopes/ui-foundation/ui/ui-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export type StartOptions = {
* port range for the UI server to bind. default is a port range of 4000-4200.
*/
portRange?: number[] | number;

/**
* pathname to start the web server at
*/
urlBasename?: string;
};

export class UIServer {
Expand Down Expand Up @@ -97,11 +102,11 @@ export class UIServer {
/**
* start a UI server.
*/
async start({ portRange }: StartOptions = {}) {
async start({ portRange, urlBasename }: StartOptions = {}) {
const app = this.expressExtension.createApp();
const publicDir = `/${this.publicDir}`;
const root = join(this.uiRoot.path, publicDir);
const server = await this.graphql.createServer({ app });
const server = await this.graphql.createServer({ app, urlBasename });

// set up proxy, for things like preview, e.g. '/preview/teambit.react/react'
await this.configureProxy(app, server);
Expand All @@ -112,7 +117,7 @@ export class UIServer {

const port = await Port.getPortFromRange(portRange || [3100, 3200]);

await this.setupServerSideRendering({ root, port, app });
await this.setupServerSideRendering({ root, port, app, urlBasename });

// in any and all other cases, serve index.html.
// No any other endpoints past this will execute
Expand All @@ -132,14 +137,25 @@ export class UIServer {
return this.plugins.map((plugin) => plugin.render);
}

private async setupServerSideRendering({ root, port, app }: { root: string; port: number; app: Express }) {
private async setupServerSideRendering({
root,
port,
app,
urlBasename,
}: {
root: string;
port: number;
app: Express;
urlBasename?: string;
}) {
if (!this.buildOptions?.ssr) return;

const ssrMiddleware = await createSsrMiddleware({
root,
port,
title: this.uiRoot.name,
logger: this.logger,
urlBasename,
});

if (!ssrMiddleware) {
Expand Down Expand Up @@ -186,7 +202,7 @@ export class UIServer {
const devServerConfig = await this.getDevServerConfig(devServerPort, expressAppPort, config.devServer);
// @ts-ignore in the capsules it throws an error about compatibilities issues between webpack.compiler and webpackDevServer/webpack/compiler
const devServer = new WebpackDevServer(devServerConfig, compiler);

await devServer.start();
this._port = devServerPort;
return devServer;
Expand Down
4 changes: 2 additions & 2 deletions scopes/ui-foundation/ui/ui.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,10 @@ export class UiMain {
// Adding signal listeners to make sure we immediately close the process on sigint / sigterm (otherwise webpack dev server closing will take time)
this.addSignalListener();
if (dev) {
await uiServer.dev({ portRange: port || this.config.portRange });
await uiServer.dev({ portRange: port || this.config.portRange, urlBasename: this.config.urlBasename });
} else {
await this.buildUI(name, uiRoot, rebuild);
await uiServer.start({ portRange: port || this.config.portRange });
await uiServer.start({ portRange: port || this.config.portRange, urlBasename: this.config.urlBasename });
}

this.pubsub.pub(UIAspect.id, this.createUiServerStartedEvent(this.config.host, uiServer.port, uiRoot));
Expand Down
2 changes: 1 addition & 1 deletion scopes/ui-foundation/ui/webpack/webpack.browser.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function createWebpackConfig(
return combined;
}

function createBrowserConfig(workspaceDir: string, title: string, publicDir: string, publicPath: string) {
function createBrowserConfig(workspaceDir: string, title: string, publicDir: string, publicPath?: string) {
const browserConfig: Configuration = {
// target: 'web', // already default

Expand Down

0 comments on commit 25dd1a9

Please sign in to comment.