Merge pull request #22434 from backstage/rugvip/authentry
cli: add support for a separate /public entry point
This commit is contained in:
@@ -25,7 +25,7 @@ import {
|
||||
import formatWebpackMessages from 'react-dev-utils/formatWebpackMessages';
|
||||
import { createConfig, resolveBaseUrl } from './config';
|
||||
import { BuildOptions } from './types';
|
||||
import { resolveBundlingPaths } from './paths';
|
||||
import { resolveBundlingPaths, resolveOptionalBundlingPaths } from './paths';
|
||||
import chalk from 'chalk';
|
||||
import { createDetectedModulesEntryPoint } from './packageDetection';
|
||||
|
||||
@@ -47,18 +47,44 @@ export async function buildBundle(options: BuildOptions) {
|
||||
targetPath: paths.targetPath,
|
||||
});
|
||||
|
||||
const config = await createConfig(paths, {
|
||||
const commonConfigOptions = {
|
||||
...options,
|
||||
checksEnabled: false,
|
||||
isDev: false,
|
||||
baseUrl: resolveBaseUrl(options.frontendConfig),
|
||||
getFrontendAppConfigs: () => options.frontendAppConfigs,
|
||||
additionalEntryPoints: detectedModulesEntryPoint,
|
||||
};
|
||||
const configs = [
|
||||
await createConfig(paths, {
|
||||
...commonConfigOptions,
|
||||
additionalEntryPoints: detectedModulesEntryPoint,
|
||||
}),
|
||||
];
|
||||
|
||||
const publicPaths = await resolveOptionalBundlingPaths({
|
||||
entry: 'src/index-public-experimental',
|
||||
dist: 'dist/public',
|
||||
});
|
||||
if (publicPaths) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
`⚠️ WARNING: The app /auth entry point is an experimental feature that may receive immediate breaking changes.`,
|
||||
),
|
||||
);
|
||||
configs.push(
|
||||
await createConfig(publicPaths, {
|
||||
...commonConfigOptions,
|
||||
publicSubPath: '/public',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const isCi = yn(process.env.CI, { default: false });
|
||||
|
||||
const previousFileSizes = await measureFileSizesBeforeBuild(paths.targetDist);
|
||||
const previousAuthSizes = publicPaths
|
||||
? await measureFileSizesBeforeBuild(publicPaths.targetDist)
|
||||
: undefined;
|
||||
await fs.emptyDir(paths.targetDist);
|
||||
|
||||
if (paths.targetPublic) {
|
||||
@@ -76,33 +102,43 @@ export async function buildBundle(options: BuildOptions) {
|
||||
);
|
||||
}
|
||||
|
||||
const { stats } = await build(config, isCi);
|
||||
const { stats } = await build(configs, isCi);
|
||||
|
||||
if (!stats) {
|
||||
throw new Error('No stats returned');
|
||||
}
|
||||
const [mainStats, authStats] = stats.stats;
|
||||
|
||||
if (statsJsonEnabled) {
|
||||
// No @types/bfj
|
||||
await require('bfj').write(
|
||||
resolvePath(paths.targetDist, 'bundle-stats.json'),
|
||||
stats.toJson(),
|
||||
mainStats.toJson(),
|
||||
);
|
||||
}
|
||||
|
||||
printFileSizesAfterBuild(
|
||||
stats,
|
||||
mainStats,
|
||||
previousFileSizes,
|
||||
paths.targetDist,
|
||||
WARN_AFTER_BUNDLE_GZIP_SIZE,
|
||||
WARN_AFTER_CHUNK_GZIP_SIZE,
|
||||
);
|
||||
if (publicPaths && previousAuthSizes) {
|
||||
printFileSizesAfterBuild(
|
||||
authStats,
|
||||
previousAuthSizes,
|
||||
publicPaths.targetDist,
|
||||
WARN_AFTER_BUNDLE_GZIP_SIZE,
|
||||
WARN_AFTER_CHUNK_GZIP_SIZE,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function build(config: webpack.Configuration, isCi: boolean) {
|
||||
const stats = await new Promise<webpack.Stats | undefined>(
|
||||
async function build(configs: webpack.Configuration[], isCi: boolean) {
|
||||
const stats = await new Promise<webpack.MultiStats | undefined>(
|
||||
(resolve, reject) => {
|
||||
webpack(config, (err, buildStats) => {
|
||||
webpack(configs, (err, buildStats) => {
|
||||
if (err) {
|
||||
if (err.message) {
|
||||
const { errors } = formatWebpackMessages({
|
||||
|
||||
@@ -92,7 +92,7 @@ export async function createConfig(
|
||||
paths: BundlingPaths,
|
||||
options: BundlingOptions,
|
||||
): Promise<webpack.Configuration> {
|
||||
const { checksEnabled, isDev, frontendConfig } = options;
|
||||
const { checksEnabled, isDev, frontendConfig, publicSubPath = '' } = options;
|
||||
|
||||
const { plugins, loaders } = transforms(options);
|
||||
// Any package that is part of the monorepo but outside the monorepo root dir need
|
||||
@@ -102,7 +102,11 @@ export async function createConfig(
|
||||
|
||||
const baseUrl = frontendConfig.getString('app.baseUrl');
|
||||
const validBaseUrl = new URL(baseUrl);
|
||||
const publicPath = validBaseUrl.pathname.replace(/\/$/, '');
|
||||
let publicPath = validBaseUrl.pathname.replace(/\/$/, '');
|
||||
if (publicSubPath) {
|
||||
publicPath = `${publicPath}${publicSubPath}`.replace('//', '/');
|
||||
}
|
||||
|
||||
if (checksEnabled) {
|
||||
plugins.push(
|
||||
new ForkTsCheckerWebpackPlugin({
|
||||
|
||||
@@ -23,6 +23,8 @@ export type BundlingPathsOptions = {
|
||||
entry: string;
|
||||
// Target directory, defaulting to paths.targetDir
|
||||
targetDir?: string;
|
||||
// Relative dist directory, defaulting to 'dist'
|
||||
dist?: string;
|
||||
};
|
||||
|
||||
export function resolveBundlingPaths(options: BundlingPathsOptions) {
|
||||
@@ -60,7 +62,7 @@ export function resolveBundlingPaths(options: BundlingPathsOptions) {
|
||||
targetPublic,
|
||||
targetPath: resolvePath(targetDir, '.'),
|
||||
targetRunFile: runFileExists ? targetRunFile : undefined,
|
||||
targetDist: resolvePath(targetDir, 'dist'),
|
||||
targetDist: resolvePath(targetDir, options.dist ?? 'dist'),
|
||||
targetAssets: resolvePath(targetDir, 'assets'),
|
||||
targetSrc: resolvePath(targetDir, 'src'),
|
||||
targetDev: resolvePath(targetDir, 'dev'),
|
||||
@@ -72,4 +74,14 @@ export function resolveBundlingPaths(options: BundlingPathsOptions) {
|
||||
};
|
||||
}
|
||||
|
||||
export async function resolveOptionalBundlingPaths(
|
||||
options: BundlingPathsOptions,
|
||||
) {
|
||||
const resolvedPaths = resolveBundlingPaths(options);
|
||||
if (await fs.pathExists(resolvedPaths.targetEntry)) {
|
||||
return resolvedPaths;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export type BundlingPaths = ReturnType<typeof resolveBundlingPaths>;
|
||||
|
||||
@@ -32,7 +32,7 @@ import { loadCliConfig } from '../config';
|
||||
import { Lockfile } from '../versioning';
|
||||
import { createConfig, resolveBaseUrl } from './config';
|
||||
import { createDetectedModulesEntryPoint } from './packageDetection';
|
||||
import { resolveBundlingPaths } from './paths';
|
||||
import { resolveBundlingPaths, resolveOptionalBundlingPaths } from './paths';
|
||||
import { ServeOptions } from './types';
|
||||
import { hasReactDomClient } from './hasReactDomClient';
|
||||
|
||||
@@ -147,7 +147,7 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
|
||||
},
|
||||
});
|
||||
|
||||
const config = await createConfig(paths, {
|
||||
const commonConfigOptions = {
|
||||
...options,
|
||||
checksEnabled: options.checksEnabled,
|
||||
isDev: true,
|
||||
@@ -156,6 +156,10 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
|
||||
getFrontendAppConfigs: () => {
|
||||
return latestFrontendAppConfigs;
|
||||
},
|
||||
};
|
||||
|
||||
const config = await createConfig(paths, {
|
||||
...commonConfigOptions,
|
||||
additionalEntryPoints: detectedModulesEntryPoint,
|
||||
});
|
||||
|
||||
@@ -199,7 +203,26 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
|
||||
root: paths.targetPath,
|
||||
});
|
||||
} else {
|
||||
const compiler = webpack(config);
|
||||
const publicPaths = await resolveOptionalBundlingPaths({
|
||||
entry: 'src/index-public-experimental',
|
||||
dist: 'dist/public',
|
||||
});
|
||||
if (publicPaths) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
`⚠️ WARNING: The app /public entry point is an experimental feature that may receive immediate breaking changes.`,
|
||||
),
|
||||
);
|
||||
}
|
||||
const compiler = publicPaths
|
||||
? webpack([
|
||||
config,
|
||||
await createConfig(publicPaths, {
|
||||
...commonConfigOptions,
|
||||
publicSubPath: '/public',
|
||||
}),
|
||||
])
|
||||
: webpack(config);
|
||||
|
||||
webpackServer = new WebpackDevServer(
|
||||
{
|
||||
|
||||
@@ -26,6 +26,8 @@ export type BundlingOptions = {
|
||||
baseUrl: URL;
|
||||
parallelism?: number;
|
||||
additionalEntryPoints?: string[];
|
||||
// Path to append to the detected public path, e.g. '/public'
|
||||
publicSubPath?: string;
|
||||
};
|
||||
|
||||
export type ServeOptions = BundlingPathsOptions & {
|
||||
|
||||
Reference in New Issue
Block a user