Skip to content

Commit 262cde0

Browse files
Search for <ThemeInit /> in the project and warn if it's not found (#1605)
* Search for `<ThemeInit />` in the project and warn if it's not found * update changeset * chore: exclude test coverage for `src/cli` and `src/helpers` * update changeset
1 parent da4df03 commit 262cde0

30 files changed

+334
-75
lines changed

.changeset/dull-ducks-give.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"flowbite-react": patch
3+
---
4+
5+
Search for `<ThemeInit />` in the project and warn if it's not found instead of warning all the time
6+
7+
### Changes
8+
9+
- during commands `build` and `dev` check files content for custom configuration and display a warning if `<ThemeInit />` is not found
10+
- switch tests in `src/cli` and `src/helpers` from `vitest` -> `bun:test`

packages/ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@
257257
"prepack": "clean-package",
258258
"prepare": "bun run generate-metadata",
259259
"prepublishOnly": "bun run build",
260-
"test": "bun test scripts && vitest",
260+
"test": "bun test scripts src/cli src/helpers && vitest",
261261
"test:coverage": "vitest run --coverage",
262262
"typecheck": "tsc --noEmit"
263263
},

packages/ui/scripts/generate-metadata.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from "vitest";
1+
import { describe, expect, it } from "bun:test";
22
import { extractClassList, extractDependencyList } from "./generate-metadata";
33

44
describe("extractClassList", () => {

packages/ui/src/cli/commands/build.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import fs from "fs/promises";
22
import { allowedExtensions, automaticClassGenerationMessage, classListFilePath, excludeDirs } from "../consts";
33
import { buildClassList } from "../utils/build-class-list";
4+
import { createInitLogger } from "../utils/create-init-logger";
45
import { extractComponentImports } from "../utils/extract-component-imports";
56
import { findFiles } from "../utils/find-files";
67
import { getConfig } from "../utils/get-config";
@@ -13,11 +14,24 @@ export async function build() {
1314
try {
1415
const config = await getConfig();
1516
await setupInit(config);
17+
const initLogger = createInitLogger(config);
1618

1719
const importedComponents: string[] = [];
1820

1921
if (config.components.length) {
2022
console.warn(automaticClassGenerationMessage);
23+
24+
if (initLogger.isCustomConfig) {
25+
const files = await findFiles({
26+
patterns: allowedExtensions.map((ext) => `**/*${ext}`),
27+
excludeDirs,
28+
});
29+
30+
for (const file of files) {
31+
const content = await fs.readFile(file, "utf-8");
32+
initLogger.check(file, content);
33+
}
34+
}
2135
} else {
2236
const files = await findFiles({
2337
patterns: allowedExtensions.map((ext) => `**/*${ext}`),
@@ -27,13 +41,16 @@ export async function build() {
2741
for (const file of files) {
2842
const content = await fs.readFile(file, "utf-8");
2943
const components = extractComponentImports(content);
44+
initLogger.check(file, content);
3045

3146
if (components.length) {
3247
importedComponents.push(...components);
3348
}
3449
}
3550
}
3651

52+
initLogger.log();
53+
3754
const classList = buildClassList({
3855
components: config.components.length ? config.components : [...new Set(importedComponents)],
3956
dark: config.dark,

packages/ui/src/cli/commands/dev.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
initJsxFilePath,
1414
} from "../consts";
1515
import { buildClassList } from "../utils/build-class-list";
16+
import { createInitLogger } from "../utils/create-init-logger";
1617
import { extractComponentImports } from "../utils/extract-component-imports";
1718
import { findFiles } from "../utils/find-files";
1819
import { getClassList } from "../utils/get-class-list";
@@ -25,6 +26,7 @@ export async function dev() {
2526
await setupOutputDirectory();
2627
let config = await getConfig();
2728
await setupInit(config);
29+
const initLogger = createInitLogger(config);
2830

2931
if (config.components.length) {
3032
console.warn(automaticClassGenerationMessage);
@@ -42,12 +44,15 @@ export async function dev() {
4244
for (const file of files) {
4345
const content = await fs.readFile(file, "utf-8");
4446
const componentImports = extractComponentImports(content);
47+
initLogger.check(file, content);
4548

4649
if (componentImports.length) {
4750
importedComponentsMap[file] = componentImports;
4851
}
4952
}
5053

54+
initLogger.log();
55+
5156
const newImportedComponents = [...new Set(Object.values(importedComponentsMap).flat())];
5257
const newClassList = buildClassList({
5358
components: config.components.length ? config.components : newImportedComponents,
@@ -63,9 +68,19 @@ export async function dev() {
6368

6469
// watch for changes
6570
async function handleChange(path: string, eventName: "change" | "unlink") {
71+
if ([configFilePath, initFilePath, initJsxFilePath].includes(path)) {
72+
config = await getConfig();
73+
await setupInit(config);
74+
initLogger.config = config;
75+
}
76+
if (path === gitIgnoreFilePath) {
77+
await setupGitIgnore();
78+
}
79+
6680
if (eventName === "change") {
6781
const content = await fs.readFile(path, "utf-8");
6882
const componentImports = extractComponentImports(content);
83+
initLogger.check(path, content);
6984

7085
if (componentImports.length) {
7186
importedComponentsMap[path] = componentImports;
@@ -75,17 +90,12 @@ export async function dev() {
7590
}
7691
if (eventName === "unlink") {
7792
delete importedComponentsMap[path];
93+
initLogger.checkedMap.delete(path);
7894
}
7995

80-
const newImportedComponents = [...new Set(Object.values(importedComponentsMap).flat())];
96+
initLogger.log();
8197

82-
if ([configFilePath, initFilePath, initJsxFilePath].includes(path)) {
83-
config = await getConfig();
84-
await setupInit(config);
85-
}
86-
if (path === gitIgnoreFilePath) {
87-
await setupGitIgnore();
88-
}
98+
const newImportedComponents = [...new Set(Object.values(importedComponentsMap).flat())];
8999

90100
const newClassList = buildClassList({
91101
components: config.components.length ? config.components : newImportedComponents,

packages/ui/src/cli/commands/setup-config.ts

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,18 @@ import { klona } from "klona/json";
33
import { isEqual } from "../../helpers/is-equal";
44
import { COMPONENT_TO_CLASS_LIST_MAP } from "../../metadata/class-list";
55
import { configFilePath } from "../consts";
6+
import { createConfig, type Config } from "../utils/create-config";
67
import { getTailwindVersion } from "../utils/get-tailwind-version";
78

8-
export interface Config {
9-
$schema: string;
10-
components: string[];
11-
dark: boolean;
12-
path: string;
13-
prefix: string;
14-
rsc: boolean;
15-
tsx: boolean;
16-
version: 3 | 4;
17-
}
18-
199
/**
2010
* Sets up the `.flowbite-react/config.json` file in the project.
2111
*
2212
* This function creates or updates the configuration file with default values and validates existing configurations.
2313
*/
2414
export async function setupConfig(): Promise<Config> {
25-
const defaultConfig: Config = {
26-
$schema: "https://unpkg.com/flowbite-react/schema.json",
27-
components: [],
28-
dark: true,
29-
path: "src/components",
30-
// TODO: infer from project
31-
prefix: "",
32-
rsc: true,
33-
tsx: true,
15+
const defaultConfig = createConfig({
3416
version: await getTailwindVersion(),
35-
};
17+
});
3618
const writeTimeout = 10;
3719

3820
try {
@@ -102,19 +84,6 @@ export async function setupConfig(): Promise<Config> {
10284
setTimeout(() => fs.writeFile(configFilePath, JSON.stringify(newConfig, null, 2)), writeTimeout);
10385
}
10486

105-
if (
106-
newConfig.dark !== defaultConfig.dark ||
107-
newConfig.prefix !== defaultConfig.prefix ||
108-
newConfig.version !== defaultConfig.version
109-
) {
110-
// TODO: search for <ThemeInit /> in the project and warn if it's not found
111-
console.info(
112-
`\n[!] Custom values detected in ${configFilePath}, render <ThemeInit /> at root level of your app to sync runtime with node config values.`,
113-
`\n[!] Otherwise, your app will use the default values instead of your custom configuration.`,
114-
`\n[!] Example: In case of custom 'prefix' or 'version', the app will not display the correct class names.`,
115-
);
116-
}
117-
11887
return newConfig;
11988
} catch (error) {
12089
if (error instanceof Error && error.message.includes("ENOENT")) {

packages/ui/src/cli/commands/setup-init.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { namedTypes } from "ast-types";
33
import { parse } from "recast";
44
import { initFilePath, initJsxFilePath } from "../consts";
55
import { compareNodes } from "../utils/compare-nodes";
6-
import type { Config } from "./setup-config";
6+
import type { Config } from "../utils/create-config";
77

88
/**
99
* Sets up the `.flowbite-react/init.tsx` file in the project.

packages/ui/src/cli/utils/add-import.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from "vitest";
1+
import { describe, expect, it } from "bun:test";
22
import { addImport } from "./add-import";
33

44
describe("addImport", () => {

packages/ui/src/cli/utils/add-plugin.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it } from "vitest";
1+
import { describe, expect, it } from "bun:test";
22
import { addPlugin } from "./add-plugin";
33

44
describe("addPlugin", () => {

packages/ui/src/cli/utils/add-to-config.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { describe, expect, it } from "bun:test";
12
import * as recast from "recast";
2-
import { describe, expect, it } from "vitest";
33
import { addToConfig } from "./add-to-config";
44

55
describe("addToConfig", () => {

0 commit comments

Comments
 (0)