Skip to content

Added support for non root (home) deployment of bit-server #4923 #4958

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions scopes/harmony/graphql/render-lifecycle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ export class GraphqlRenderLifecycle implements RenderLifecycle<RenderContext, {
browserInit = ({ state }: { state?: NormalizedCacheObject } = {}) => {
const { location } = window;
const isInsecure = location.protocol === 'http:';
const wsUrl = `${isInsecure ? 'ws:' : 'wss:'}//${location.host}/subscriptions`;
const wsUrl = `${isInsecure ? 'ws:' : 'wss:'}//${location.host}/bit-dev/subscriptions`;

const client = this.graphqlUI.createClient('/graphql', { state, subscriptionUri: wsUrl });
const client = this.graphqlUI.createClient('/bit-dev/graphql', { state, subscriptionUri: wsUrl });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to pass basename from graphql/ui aspect


return { client };
};
Expand Down
3 changes: 2 additions & 1 deletion scopes/preview/ui/component-preview/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function toPreviewUrl(component: ComponentModel, previewName?: string, ad
*/
export function toPreviewServer(component: ComponentModel) {
let explicitUrl = component.server?.url;
// eslint-disable-next-line no-console
// quickfix - preview urls in `start` (without `--dev`) won't work without trailing '/'
if (explicitUrl && !explicitUrl.endsWith('/')) explicitUrl += '/';

Expand All @@ -25,7 +26,7 @@ export function toPreviewServer(component: ComponentModel) {

// fallback url for all components. Includes versions support
// for example - "/api/teambit.base-ui/input/[email protected]/~aspect/preview/"
const defaultServerUrl = `/api/${component.id.toString()}/~aspect/preview/`;
const defaultServerUrl = `/bit-dev/api/${component.id.toString()}/~aspect/preview/`;
Copy link
Contributor

@KutnerUri KutnerUri Oct 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to pass basename (from where..?) as prop.

Where to get the basename prop though?
maybe we can it from react-router context?

worse case we can set a global react-context from the UI aspect, something like:

const { basename, apiPath } = useContext(???);

const defaultServerUrl = `${apiPath}/${component.id.toString()}/~aspect/preview/`;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking of adding basename to our internal routing system, as part of the changes I'm going to do to @teambit/base-ui.routing.routing-provider anyways.

It would be more elegant.

Then again, I'm not sure it will work here, because explicitUrl could have it's own url.


return explicitUrl || /* envBasedUrl || */ defaultServerUrl;
}
Expand Down
33 changes: 27 additions & 6 deletions scopes/ui-foundation/react-router/react-router/route-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type RouterContextProps = {
routing?: Routing;
children: ReactNode;
location?: string;
basename?: string;
};

type RootRouteProps = {
Expand All @@ -23,10 +24,16 @@ type RootRouteProps = {
/**
* Setup context needed for routing.
*/
export function RouteContext({ reactRouterUi, routing = Routing.url, children, location }: RouterContextProps) {
export function RouteContext({
reactRouterUi,
routing = Routing.url,
children,
location,
basename = '/bit-dev/',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default should be undefined (if possible), or / otherwise.

the "bit-dev" should come from the UI aspect

}: RouterContextProps) {
return (
// {/* set up the virtual router (browser, inMemory, etc) */}
<Router type={routing} location={location}>
<Router type={routing} location={location} basename={basename}>
{/* injects History object back to reactRouterUi */}
<HistoryGetter onRouterChange={reactRouterUi.setRouter} />
{/* injects react-router Link into context */}
Expand All @@ -43,21 +50,35 @@ export function RootRoute({ rootRoutes, routeSlot }: RootRouteProps) {
}

/** provides the router engine (browser, inMemory, etc) */
function Router({ type, children, location }: { type: Routing; children: ReactNode; location?: string }) {
function Router({
type,
children,
location,
basename,
}: {
type: Routing;
children: ReactNode;
location?: string;
basename?: string;
}) {
switch (type) {
case Routing.static:
return <StaticRouter location={location}>{children}</StaticRouter>;
return (
<StaticRouter basename={basename} location={location}>
{children}
</StaticRouter>
);
case Routing.inMemory:
return (
<MemoryRouter initialEntries={[location || '/']} initialIndex={1}>
{children}
</MemoryRouter>
);
case Routing.hash:
return <HashRouter>{children}</HashRouter>;
return <HashRouter basename={basename}>{children}</HashRouter>;
case Routing.url:
default:
return <BrowserRouter>{children}</BrowserRouter>;
return <BrowserRouter basename={basename}>{children}</BrowserRouter>;
}
}

Expand Down
19 changes: 17 additions & 2 deletions scopes/ui-foundation/ui/ui.main.runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ export type UIConfig = {
*/
publicDir: string;

/**
* set `publicPath` value for webpack.config to override
* in case server is not accessed using root route.
*/
publicPath: string;

/** the url to display when server is listening. Note that bit does not provide proxying to this url */
publicUrl?: string;
};
Expand Down Expand Up @@ -216,7 +222,13 @@ export class UiMain {
const ssr = uiRoot.buildOptions?.ssr || false;
const mainEntry = await this.generateRoot(await uiRoot.resolveAspects(UIRuntime.name), name);

const browserConfig = createWebpackConfig(uiRoot.path, [mainEntry], uiRoot.name, await this.publicDir(uiRoot));
const browserConfig = createWebpackConfig(
uiRoot.path,
[mainEntry],
uiRoot.name,
await this.publicDir(uiRoot),
this.config.publicPath
);
const ssrConfig = ssr && createSsrWebpackConfig(uiRoot.path, [mainEntry], await this.publicDir(uiRoot));

const config = [browserConfig, ssrConfig].filter((x) => !!x) as webpack.Configuration[];
Expand Down Expand Up @@ -490,7 +502,8 @@ export class UiMain {
uiRoot.path,
[await this.generateRoot(await uiRoot.resolveAspects(UIRuntime.name), name)],
uiRoot.name,
await this.publicDir(uiRoot)
await this.publicDir(uiRoot),
this.config.publicPath
);
if (config.output?.path && fs.pathExistsSync(config.output.path)) return;
const hash = await this.buildUiHash(uiRoot);
Expand All @@ -509,6 +522,8 @@ export class UiMain {

static defaultConfig: UIConfig = {
publicDir: 'public/bit',
// Changing to relative path which should work in all cases
publicPath: process.env.ASSET_PATH || './',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooh this looks interesting, how does it work

portRange: [3000, 3100],
host: 'localhost',
};
Expand Down
9 changes: 5 additions & 4 deletions scopes/ui-foundation/ui/webpack/webpack.browser.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ export default function createWebpackConfig(
workspaceDir: string,
entryFiles: string[],
title: string,
publicDir: string
publicDir: string,
publicPath: string
): Configuration {
const baseConfig = createBaseConfig(workspaceDir, entryFiles);
const browserConfig = createBrowserConfig(workspaceDir, title, publicDir);
const browserConfig = createBrowserConfig(workspaceDir, title, publicDir, publicPath);

const combined = merge(baseConfig, browserConfig);

return combined;
}

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

Expand All @@ -31,7 +32,7 @@ function createBrowserConfig(workspaceDir: string, title: string, publicDir: str
// webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: '/',
publicPath,
},

optimization: {
Expand Down
5 changes: 4 additions & 1 deletion workspace.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
"name": "bit",
"icon": "https://static.bit.dev/bit-logo.svg",
"defaultScope": "teambit.bit",
"defaultDirectory": "components"
"defaultDirectory": "components",
// I would like to see this to be used across all places where
// code changes are done as part of this PR.
"publicPath": "/bit-dev"
},
"teambit.dependencies/dependency-resolver": {
"packageManager": "teambit.dependencies/yarn",
Expand Down