cli: add support for frontend-dynamic-container role in yarn start

Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
This commit is contained in:
MT Lewis
2024-07-17 18:01:01 +01:00
parent 70c0ac43cd
commit 7082940121
6 changed files with 65 additions and 27 deletions
@@ -16,11 +16,9 @@
import fs from 'fs-extra';
import { resolve as resolvePath } from 'path';
import { buildBundle } from '../../lib/bundler';
import { buildBundle, getModuleFederationOptions } from '../../lib/bundler';
import { getEnvironmentParallelism } from '../../lib/parallel';
import { loadCliConfig } from '../../lib/config';
import chalk from 'chalk';
import { BuildOptions } from '../../lib/bundler/types';
interface BuildAppOptions {
targetDir: string;
@@ -29,29 +27,6 @@ interface BuildAppOptions {
isModuleFederationRemote?: true;
}
function getModuleFederationOptions(
name: string,
isRemote?: boolean,
): BuildOptions['moduleFederation'] {
if (!isRemote && !process.env.EXPERIMENTAL_MODULE_FEDERATION) {
return undefined;
}
console.log(
chalk.yellow(
`⚠️ WARNING: Module federation is experimental and will receive immediate breaking changes in the future.`,
),
);
return {
mode: isRemote ? 'remote' : 'host',
// The default output mode requires the name to be a usable as a code
// symbol, there might be better options here but for now we need to
// sanitize the name.
name: name.replaceAll('@', '').replaceAll('/', '__').replaceAll('-', '_'),
};
}
export async function buildFrontend(options: BuildAppOptions) {
const { targetDir, writeStats, configPaths } = options;
const { name } = await fs.readJson(resolvePath(targetDir, 'package.json'));
@@ -15,6 +15,7 @@
*/
import { OptionValues } from 'commander';
import { PackageRole } from '@backstage/cli-node';
import { findRoleFromCommand } from '../../lib/role';
import { startBackend, startBackendPlugin } from './startBackend';
import { startFrontend } from './startFrontend';
@@ -47,6 +48,13 @@ export async function command(opts: OptionValues): Promise<void> {
case 'frontend-plugin':
case 'frontend-plugin-module':
return startFrontend({ entry: 'dev/index', ...options });
case 'frontend-dynamic-container' as PackageRole: // experimental
return startFrontend({
entry: 'src/index',
...options,
skipOpenBrowser: true,
isModuleFederationRemote: true,
});
default:
throw new Error(
`Start command is not supported for package role '${role}'`,
@@ -14,7 +14,9 @@
* limitations under the License.
*/
import { serveBundle } from '../../lib/bundler';
import { readJson } from 'fs-extra';
import { getModuleFederationOptions, serveBundle } from '../../lib/bundler';
import { paths } from '../../lib/paths';
interface StartAppOptions {
verifyVersions?: boolean;
@@ -22,14 +24,21 @@ interface StartAppOptions {
checksEnabled: boolean;
configPaths: string[];
isModuleFederationRemote?: boolean;
}
export async function startFrontend(options: StartAppOptions) {
const { name } = await readJson(paths.resolveTarget('package.json'));
const waitForExit = await serveBundle({
entry: options.entry,
checksEnabled: options.checksEnabled,
configPaths: options.configPaths,
verifyVersions: options.verifyVersions,
moduleFederation: getModuleFederationOptions(
name,
options.isModuleFederationRemote,
),
});
await waitForExit();
+1
View File
@@ -16,4 +16,5 @@
export { serveBackend } from './backend';
export { buildBundle } from './bundle';
export { getModuleFederationOptions } from './moduleFederation';
export { serveBundle } from './server';
@@ -0,0 +1,44 @@
/*
* Copyright 2024 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import chalk from 'chalk';
import { ModuleFederationOptions } from './types';
export function getModuleFederationOptions(
name: string,
isModuleFederationRemote?: boolean,
): ModuleFederationOptions | undefined {
if (
!isModuleFederationRemote &&
!process.env.EXPERIMENTAL_MODULE_FEDERATION
) {
return undefined;
}
console.log(
chalk.yellow(
`⚠️ WARNING: Module federation is experimental and will receive immediate breaking changes in the future.`,
),
);
return {
mode: isModuleFederationRemote ? 'remote' : 'host',
// The default output mode requires the name to be a usable as a code
// symbol, there might be better options here but for now we need to
// sanitize the name.
name: name.replaceAll('@', '').replaceAll('/', '__').replaceAll('-', '_'),
};
}
+1
View File
@@ -43,6 +43,7 @@ export type ServeOptions = BundlingPathsOptions & {
checksEnabled: boolean;
configPaths: string[];
verifyVersions?: boolean;
moduleFederation?: ModuleFederationOptions;
};
export type BuildOptions = BundlingPathsOptions & {