cli: switch app auth entry to be a separate compilation

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-01-13 15:00:55 +01:00
parent 8968cda34f
commit 47c686e4a1
4 changed files with 62 additions and 48 deletions
+35 -9
View File
@@ -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,34 @@ 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 authPaths = await resolveOptionalBundlingPaths({
entry: 'src/auth',
dist: 'dist/auth',
});
if (authPaths) {
configs.push(await createConfig(authPaths, commonConfigOptions));
}
const isCi = yn(process.env.CI, { default: false });
const previousFileSizes = await measureFileSizesBeforeBuild(paths.targetDist);
const previousAuthSizes = authPaths
? await measureFileSizesBeforeBuild(authPaths.targetDist)
: undefined;
await fs.emptyDir(paths.targetDist);
if (paths.targetPublic) {
@@ -76,33 +92,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 (authPaths && previousAuthSizes) {
printFileSizesAfterBuild(
authStats,
previousAuthSizes,
authPaths.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({
+1 -20
View File
@@ -127,8 +127,6 @@ export async function createConfig(
plugins.push(
new HtmlWebpackPlugin({
chunks: ['main'],
filename: 'index.html',
template: paths.targetHtml,
templateParameters: {
publicPath,
@@ -137,20 +135,6 @@ export async function createConfig(
}),
);
if (paths.targetAuthEntry) {
plugins.push(
new HtmlWebpackPlugin({
chunks: ['auth'],
filename: 'auth/index.html',
template: paths.targetHtml,
templateParameters: {
publicPath,
config: frontendConfig,
},
}),
);
}
const buildInfo = await readBuildInfo();
plugins.push(
new webpack.DefinePlugin({
@@ -188,10 +172,7 @@ export async function createConfig(
},
devtool: isDev ? 'eval-cheap-module-source-map' : 'source-map',
context: paths.targetPath,
entry: {
main: [...(options.additionalEntryPoints ?? []), paths.targetEntry],
...(paths.targetAuthEntry ? { auth: paths.targetAuthEntry } : {}),
},
entry: [...(options.additionalEntryPoints ?? []), paths.targetEntry],
resolve: {
extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx', '.json', '.wasm'],
mainFields: ['browser', 'module', 'main'],
+13 -16
View File
@@ -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) {
@@ -38,14 +40,6 @@ export function resolveBundlingPaths(options: BundlingPathsOptions) {
return resolvePath(targetDir, `${pathString}.js`);
};
const resolveTargetOptionalModule = (pathString: string) => {
try {
return resolveTargetModule(pathString);
} catch {
return undefined;
}
};
let targetPublic = undefined;
let targetHtml = resolvePath(targetDir, 'public/index.html');
@@ -59,27 +53,20 @@ export function resolveBundlingPaths(options: BundlingPathsOptions) {
}
}
let targetAuthHtml = targetHtml;
if (fs.pathExistsSync(resolvePath(targetDir, 'public/auth.html'))) {
targetAuthHtml = resolvePath(targetDir, 'public/auth.html');
}
// Backend plugin dev run file
const targetRunFile = resolvePath(targetDir, 'src/run.ts');
const runFileExists = fs.pathExistsSync(targetRunFile);
return {
targetHtml,
targetAuthHtml,
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'),
targetEntry: resolveTargetModule(entry),
targetAuthEntry: resolveTargetOptionalModule('src/auth'),
targetTsConfig: paths.resolveTargetRoot('tsconfig.json'),
targetPackageJson: resolvePath(targetDir, 'package.json'),
rootNodeModules: paths.resolveTargetRoot('node_modules'),
@@ -87,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>;
+13 -3
View File
@@ -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,13 @@ DEPRECATION WARNING: React Router Beta is deprecated and support for it will be
root: paths.targetPath,
});
} else {
const compiler = webpack(config);
const authPaths = await resolveOptionalBundlingPaths({
entry: 'src/auth',
dist: 'dist/auth',
});
const compiler = authPaths
? webpack([config, await createConfig(authPaths, commonConfigOptions)])
: webpack(config);
webpackServer = new WebpackDevServer(
{