mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 12:22:34 +03:00
fix(dev): bound webpack and Tailwind scans (#12075)
Boarded with #12082 in one combined worktree: typecheck:core, check:file-size, check:changelog-integrity, check:complexity, check:cognitive-complexity, check:cycles all green; 77/77 focused tests pass. Genuinely conservative as described — dev-only Tailwind/webpack scanning bounds, production chunking untouched. The later phases of #12074 (2/3/4/4b) are being held for a dedicated review given their combined architectural weight (DB init graph, credential refresh, process lifecycle, network dispatch boundary) — flagged separately on those PRs. Thanks for the clean Phase 1 baseline.
This commit is contained in:
@@ -329,11 +329,12 @@ const nextConfig = {
|
||||
// TODO: Re-enable after fixing all sub-component useTranslations scope issues
|
||||
ignoreBuildErrors: true,
|
||||
},
|
||||
webpack(config, { webpack }) {
|
||||
webpack(config, { dev, webpack }) {
|
||||
config.ignoreWarnings = [
|
||||
...(config.ignoreWarnings || []),
|
||||
isNextIntlExtractorDynamicImportWarning,
|
||||
];
|
||||
const nextDefaultSplitChunks = config.optimization?.splitChunks;
|
||||
config.optimization = config.optimization || {};
|
||||
config.optimization.splitChunks = {
|
||||
...config.optimization.splitChunks,
|
||||
@@ -392,6 +393,9 @@ const nextConfig = {
|
||||
},
|
||||
},
|
||||
};
|
||||
// Next's development defaults are tuned for incremental route compilation.
|
||||
// Retain the custom vendor topology for production without imposing it on dev.
|
||||
if (dev) config.optimization.splitChunks = nextDefaultSplitChunks;
|
||||
|
||||
if (isMinimalBuild) {
|
||||
// Mirror the turbopack.resolveAlias entries for webpack-built artifacts.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "tailwindcss";
|
||||
@import "tailwindcss" source(none);
|
||||
@import "fumadocs-ui/css/neutral.css";
|
||||
@import "fumadocs-ui/css/preset.css";
|
||||
/* Self-hosted Material Symbols icon font (#3695): the Google Fonts CDN
|
||||
@@ -10,14 +10,12 @@
|
||||
@import "material-symbols/outlined.css";
|
||||
@source "../../node_modules/fumadocs-ui/css/generated/*.css";
|
||||
|
||||
/* Tailwind v4 auto-detection cannot scan directories with parentheses
|
||||
(e.g. Next.js route groups like "(dashboard)"). Explicit @source
|
||||
directives ensure all utility classes in route groups are included. */
|
||||
@source "../app/(dashboard)";
|
||||
/* Keep Tailwind v4 from scanning the entire repository. The UI lives in the
|
||||
App Router and shared component trees; third-party Fumadocs sources remain
|
||||
explicit because node_modules is ignored by automatic detection. */
|
||||
@source "../app";
|
||||
@source "../shared";
|
||||
@source "../../node_modules/fumadocs-ui/dist/**/*.js";
|
||||
@source not "../../*.sqlite*";
|
||||
@source not "../../.claude*";
|
||||
@source not "../../.claude-memory";
|
||||
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
|
||||
77
tests/unit/dev-bundler-boundaries-12074.test.ts
Normal file
77
tests/unit/dev-bundler-boundaries-12074.test.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
|
||||
const repoRoot = process.cwd();
|
||||
const nextConfigPath = path.join(repoRoot, "next.config.mjs");
|
||||
|
||||
async function loadNextConfig(label: string) {
|
||||
return import(`${pathToFileURL(nextConfigPath).href}?case=${label}-${Date.now()}`);
|
||||
}
|
||||
|
||||
test("Tailwind scans only the UI source roots declared by OmniRoute (#12074 phase 1)", () => {
|
||||
const css = readFileSync(path.join(repoRoot, "src/app/globals.css"), "utf8");
|
||||
|
||||
assert.match(
|
||||
css,
|
||||
/@import\s+"tailwindcss"\s+source\(none\);/,
|
||||
"automatic repository-wide Tailwind source detection must stay disabled"
|
||||
);
|
||||
assert.match(css, /@source\s+"\.\.\/app";/, "App Router components must stay scanned");
|
||||
assert.match(css, /@source\s+"\.\.\/shared";/, "shared UI components must stay scanned");
|
||||
assert.match(
|
||||
css,
|
||||
/@source\s+"\.\.\/\.\.\/node_modules\/fumadocs-ui\/dist\/\*\*\/\*\.js";/,
|
||||
"Fumadocs runtime classes must stay scanned"
|
||||
);
|
||||
});
|
||||
|
||||
test("webpack dev keeps Next defaults instead of production vendor cache groups (#12074 phase 1)", async () => {
|
||||
const { default: nextConfig } = await loadNextConfig("dev-split-chunks");
|
||||
const originalSplitChunks = {
|
||||
chunks: "async",
|
||||
cacheGroups: {
|
||||
framework: { name: "framework" },
|
||||
},
|
||||
};
|
||||
const config = {
|
||||
context: repoRoot,
|
||||
ignoreWarnings: [],
|
||||
optimization: { splitChunks: originalSplitChunks },
|
||||
plugins: [],
|
||||
};
|
||||
|
||||
nextConfig.webpack(config, {
|
||||
dev: true,
|
||||
isServer: false,
|
||||
defaultLoaders: { babel: {} },
|
||||
webpack: {},
|
||||
});
|
||||
|
||||
assert.equal(config.optimization.splitChunks, originalSplitChunks);
|
||||
const cacheGroups = config.optimization.splitChunks.cacheGroups as Record<string, unknown>;
|
||||
assert.equal(cacheGroups.recharts, undefined);
|
||||
assert.equal(cacheGroups.fumadocs, undefined);
|
||||
});
|
||||
|
||||
test("webpack production retains OmniRoute vendor cache groups (#12074 phase 1)", async () => {
|
||||
const { default: nextConfig } = await loadNextConfig("production-split-chunks");
|
||||
const config = {
|
||||
context: repoRoot,
|
||||
ignoreWarnings: [],
|
||||
optimization: { splitChunks: { cacheGroups: {} as Record<string, unknown> } },
|
||||
plugins: [],
|
||||
};
|
||||
|
||||
nextConfig.webpack(config, {
|
||||
dev: false,
|
||||
isServer: false,
|
||||
defaultLoaders: { babel: {} },
|
||||
webpack: {},
|
||||
});
|
||||
|
||||
assert.ok(config.optimization.splitChunks.cacheGroups.recharts);
|
||||
assert.ok(config.optimization.splitChunks.cacheGroups.fumadocs);
|
||||
});
|
||||
Reference in New Issue
Block a user