cli: switch app auth entry to be a separate compilation
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
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,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({
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user