UI: optimize Tailwind CSS Scan

This commit is contained in:
Fuma Nama
2026-02-06 19:34:36 +08:00
parent efa7071ceb
commit 53ad20bbc5
33 changed files with 196 additions and 34 deletions
+7
View File
@@ -0,0 +1,7 @@
---
'fumadocs-ui': patch
'@fumadocs/base-ui': patch
'fumadocs-openapi': patch
---
Pre-scan class names to optimize Tailwind CSS compilation performance
+5 -1
View File
@@ -40,4 +40,8 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
next-env.d.ts
packages/radix-ui/css/generated/*.css
packages/base-ui/css/generated/*.css
packages/openapi/css/generated/*.css
+9 -1
View File
@@ -4,7 +4,7 @@ import { fileURLToPath } from 'node:url';
import * as path from 'node:path';
import { resolveFromRemote } from '@fumadocs/cli/build';
const baseDir = path.join(path.dirname(fileURLToPath(import.meta.url)), '../');
const baseDir = path.join(path.dirname(fileURLToPath(import.meta.url)), '../../');
export const registry: Registry = {
dir: baseDir,
@@ -18,6 +18,14 @@ export const registry: Registry = {
if (filePath.startsWith('lib/source/')) return false;
},
onResolve(ref) {
if (ref.type === 'file') {
const file = path.relative(baseDir, ref.file);
if (file === 'lib/cn.ts') {
return resolveFromRemote(radixUi.registry, 'cn', () => true)!;
}
}
if (ref.type === 'dependency' && ref.dep === 'fumadocs-ui') {
const match = /fumadocs-ui\/components\/ui\/(.*)/.exec(ref.specifier);
if (match) {
-1
View File
@@ -1 +0,0 @@
@source '../../dist/layouts/docs/**/*.js';
-1
View File
@@ -1 +0,0 @@
@source '../../dist/layouts/flux/**/*.js';
-1
View File
@@ -1 +0,0 @@
@source '../../dist/layouts/home/**/*.js';
@@ -1 +0,0 @@
@source '../../dist/layouts/notebook/**/*.js';
+5 -7
View File
@@ -1,11 +1,9 @@
@import './lib/base.css';
/* TODO: remove them on next major */
@import './layouts/flux.css';
@import './layouts/docs.css';
@import './layouts/home.css';
@import './layouts/notebook.css';
@import './generated/flux.css';
@import './generated/docs.css';
@import './generated/home.css';
@import './generated/notebook.css';
@source '../dist/*.js';
@source '../dist/{components,contexts,provider,utils}/**/*.js';
@source '../dist/layouts/shared/**/*.js';
@import './generated/shared.css';
@@ -0,0 +1,3 @@
import { compileInline } from './compile-inline.utils';
void compileInline();
@@ -0,0 +1,44 @@
import { compile } from '@fumadocs/tailwind/compile';
import { mkdir, writeFile } from 'node:fs/promises';
import path from 'node:path';
export async function compileInline() {
await mkdir('css/generated', { recursive: true });
await writeFile(
'css/generated/shared.css',
compile([
{
base: path.resolve('src'),
pattern: '{components,contexts,provider,utils}/**/*.{ts,tsx}',
negated: false,
},
{
base: path.resolve('src'),
pattern: 'layouts/shared/**/*.{ts,tsx}',
negated: false,
},
{
base: path.resolve('src'),
pattern: '*.{ts,tsx}',
negated: false,
},
]),
);
const layouts = ['flux', 'notebook', 'home', 'docs'];
for (const layout of layouts) {
await writeFile(
`css/generated/${layout}.css`,
compile([
{
base: path.resolve('src'),
pattern: `layouts/${layout}/**/*.{ts,tsx}`,
negated: false,
},
]),
);
}
console.log('generated CSS files');
}
+1
View File
@@ -327,6 +327,7 @@ export const registry: Registry = {
dependencies: {
'fumadocs-core': null,
'@fumadocs/base-ui': null,
'fumadocs-ui': 'npm:@fumadocs/base-ui',
react: null,
},
};
+2
View File
@@ -1,5 +1,6 @@
import { defineConfig } from 'tsdown';
import fs from 'node:fs/promises';
import { compileInline } from './scripts/compile-inline.utils';
export default defineConfig({
format: 'esm',
@@ -13,6 +14,7 @@ export default defineConfig({
unbundle: true,
dts: true,
async onSuccess() {
await compileInline();
// wait until https://github.com/rolldown/tsdown/issues/472
let content = (await fs.readFile('dist/components/image-zoom.js')).toString();
content = content.replaceAll(`import "./image-zoom2.js";`, `import "./image-zoom.css";`);
+1 -1
View File
@@ -1 +1 @@
@source '../dist/**/*.js';
@import './generated/shared.css';
+1
View File
@@ -86,6 +86,7 @@
"xml-js": "^1.6.11"
},
"devDependencies": {
"@fumadocs/tailwind": "workspace:*",
"@scalar/api-client-react": "^1.3.82",
"@types/js-yaml": "^4.0.9",
"@types/node": "25.1.0",
@@ -0,0 +1,3 @@
import { compileInline } from './compile-inline.utils';
void compileInline();
@@ -0,0 +1,24 @@
import { compile } from '@fumadocs/tailwind/compile';
import { mkdir, writeFile } from 'node:fs/promises';
import path from 'node:path';
export async function compileInline() {
await mkdir('css/generated', { recursive: true });
await writeFile(
'css/generated/shared.css',
compile([
{
base: path.resolve('src'),
pattern: '{playground,scalar,ui}/**/*.{ts,tsx}',
negated: false,
},
{
base: path.resolve('src'),
pattern: 'server/**/*.tsx',
negated: false,
},
]),
);
console.log('generated CSS files');
}
+4
View File
@@ -1,4 +1,5 @@
import { defineConfig } from 'tsdown';
import { compileInline } from './scripts/compile-inline.utils';
export default defineConfig({
format: 'esm',
@@ -17,5 +18,8 @@ export default defineConfig({
dts: {
sourcemap: false,
},
async onSuccess() {
await compileInline();
},
external: [/json-schema-typed/, 'openapi-types'],
});
-1
View File
@@ -1 +0,0 @@
@source '../../dist/layouts/docs/**/*.js';
-1
View File
@@ -1 +0,0 @@
@source '../../dist/layouts/flux/**/*.js';
-1
View File
@@ -1 +0,0 @@
@source '../../dist/layouts/home/**/*.js';
@@ -1 +0,0 @@
@source '../../dist/layouts/notebook/**/*.js';
+5 -7
View File
@@ -1,14 +1,12 @@
@import './lib/base.css';
/* TODO: remove them on next major */
@import './layouts/docs.css';
@import './layouts/home.css';
@import './layouts/notebook.css';
@import './layouts/flux.css';
@import './generated/docs.css';
@import './generated/home.css';
@import './generated/notebook.css';
@import './generated/flux.css';
@source '../dist/*.js';
@source '../dist/{components,contexts,provider,utils}/**/*.js';
@source '../dist/layouts/shared/**/*.js';
@import './generated/shared.css';
@theme {
--animate-fd-collapsible-down: fd-collapsible-down 150ms cubic-bezier(0.45, 0, 0.55, 1);
@@ -0,0 +1,3 @@
import { compileInline } from './compile-inline.utils';
void compileInline();
@@ -0,0 +1,44 @@
import { compile } from '@fumadocs/tailwind/compile';
import { mkdir, writeFile } from 'node:fs/promises';
import path from 'node:path';
export async function compileInline() {
await mkdir('css/generated', { recursive: true });
await writeFile(
'css/generated/shared.css',
compile([
{
base: path.resolve('src'),
pattern: '{components,contexts,provider,utils}/**/*.{ts,tsx}',
negated: false,
},
{
base: path.resolve('src'),
pattern: 'layouts/shared/**/*.{ts,tsx}',
negated: false,
},
{
base: path.resolve('src'),
pattern: '*.{ts,tsx}',
negated: false,
},
]),
);
const layouts = ['flux', 'notebook', 'home', 'docs'];
for (const layout of layouts) {
await writeFile(
`css/generated/${layout}.css`,
compile([
{
base: path.resolve('src'),
pattern: `layouts/${layout}/**/*.{ts,tsx}`,
negated: false,
},
]),
);
}
console.log('generated CSS files');
}
+2 -1
View File
@@ -1,5 +1,6 @@
import { defineConfig } from 'tsdown';
import fs from 'node:fs/promises';
import { compileInline } from './scripts/compile-inline.utils';
export default defineConfig({
format: 'esm',
@@ -14,8 +15,8 @@ export default defineConfig({
dts: {
sourcemap: false,
},
clean: false,
async onSuccess() {
await compileInline();
// wait until https://github.com/rolldown/tsdown/issues/472
let content = (await fs.readFile('dist/components/image-zoom.js')).toString();
content = content.replaceAll(`import "./image-zoom2.js";`, `import "./image-zoom.css";`);
+1 -1
View File
@@ -1 +1 @@
@source '../dist/**/*.js';
@source '../dist/client/**/*.js';
+1
View File
@@ -8,6 +8,7 @@ export default defineConfig({
'./src/client/{index,with-control}.tsx',
'./src/type-tree/index.ts',
],
unbundle: true,
fixedExtension: false,
dts: {
sourcemap: false,
+5
View File
@@ -15,6 +15,10 @@
],
"type": "module",
"exports": {
"./compile": {
"types": "./dist/compile.d.ts",
"import": "./dist/compile.js"
},
"./typography": {
"types": "./dist/typography/index.d.ts",
"import": "./dist/typography/index.js"
@@ -34,6 +38,7 @@
"postcss-selector-parser": "^7.1.1"
},
"devDependencies": {
"@tailwindcss/oxide": "^4.1.18",
"@types/lodash.merge": "^4.6.9",
"@types/node": "^25.1.0",
"eslint-config-custom": "workspace:*",
+14 -1
View File
@@ -1 +1,14 @@
export function compile() {}
import { Scanner, SourceEntry } from '@tailwindcss/oxide';
export function compile(sources: SourceEntry[]) {
const scanner = new Scanner({
sources,
});
const lines: string[] = [];
const names = scanner.scan();
for (const name of names) {
lines.push(`@source inline(${JSON.stringify(name)});`);
}
return lines.join('\n');
}
+1
View File
@@ -8,4 +8,5 @@ export default defineConfig({
dts: {
sourcemap: false,
},
external: ['@tailwindcss/oxide'],
});
+11 -6
View File
@@ -1003,7 +1003,7 @@ importers:
version: 19.2.3(@types/[email protected])
'@vitejs/plugin-rsc':
specifier: ^0.5.17
version: 0.5.17([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
version: 0.5.17([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected])([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
react-router-devtools:
specifier: ^6.2.0
version: 6.2.0(@types/[email protected](@types/[email protected]))(@types/[email protected])([email protected])([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
@@ -2275,6 +2275,9 @@ importers:
specifier: ^1.6.11
version: 1.6.11
devDependencies:
'@fumadocs/tailwind':
specifier: workspace:*
version: link:../tailwind
'@scalar/api-client-react':
specifier: ^1.3.82
version: 1.3.82([email protected])([email protected])([email protected])([email protected])
@@ -2325,7 +2328,7 @@ importers:
version: 5.1.2([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
'@vitejs/plugin-rsc':
specifier: ^0.5.17
version: 0.5.17([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
version: 0.5.17([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected])([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
commander:
specifier: ^14.0.2
version: 14.0.2
@@ -2635,6 +2638,9 @@ importers:
specifier: ^7.1.1
version: 7.1.1
devDependencies:
'@tailwindcss/oxide':
specifier: ^4.1.18
version: 4.1.18
'@types/lodash.merge':
specifier: ^4.6.9
version: 4.6.9
@@ -7090,7 +7096,6 @@ packages:
[email protected]:
resolution: {integrity: sha512-Tn98GlZVN2WM7+lg/uGn5DzUao37Yc0PUz7yzYHdeF5hd+SmHQGbCUIKE4Sspdgtxn49LunK3mDNBC2Qn6GJjw==}
cpu: [arm64, x64]
os: [darwin, linux, win32]
hasBin: true
@@ -14552,7 +14557,7 @@ snapshots:
vite-node: 3.2.4(@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])
optionalDependencies:
'@react-router/serve': 7.13.0([email protected]([email protected]([email protected]))([email protected]))([email protected])
'@vitejs/plugin-rsc': 0.5.17([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
'@vitejs/plugin-rsc': 0.5.17([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected])([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
react-server-dom-webpack: 19.2.4([email protected]([email protected]))([email protected])([email protected])
typescript: 5.9.3
transitivePeerDependencies:
@@ -16046,7 +16051,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@vitejs/[email protected]([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))':
'@vitejs/[email protected]([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected])([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))':
dependencies:
es-module-lexer: 2.0.0
estree-walker: 3.0.3
@@ -22213,7 +22218,7 @@ snapshots:
dependencies:
'@hono/node-server': 1.19.9([email protected])
'@vitejs/plugin-react': 5.1.2([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
'@vitejs/plugin-rsc': 0.5.17([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
'@vitejs/plugin-rsc': 0.5.17([email protected]([email protected]))([email protected]([email protected]([email protected]))([email protected])([email protected]))([email protected])([email protected](@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected]))
dotenv: 17.2.3
hono: 4.11.7
magic-string: 0.30.21