diff --git a/CLAUDE.md b/CLAUDE.md index 45c82209..c7071df7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -172,13 +172,16 @@ When generating or editing code in this repository, follow these rules to ensure - Maintain accessibility: ARIA roles, keyboard interactions, focus management. - Use data‑attributes and CSS variables for style hooks—no inline animation JS. - Ensure logic runs at 60 FPS; prefer CSS transitions over manual DOM mutations. +6. **Dev‑Only Diagnostics** + - Use `__DEV__` for warnings, debug helpers, and displayName assignments. + - Keep production builds free of dev‑only logging and checks. -6. **Commit Scope** +7. **Commit Scope** - Use semantic commit messages (enforced by `commitlint`). - One focused change per commit—no mixed updates. - Breaking changes use `!`. -7. **Keep AI Documentation Current** — When introducing new patterns, ask the user to run `/claude-update` for guidance. +8. **Keep AI Documentation Current** — When introducing new patterns, ask the user to run `/claude-update` for guidance. ## Code Rules diff --git a/packages/core/package.json b/packages/core/package.json index 8ae3e461..c0cbb07a 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -12,17 +12,19 @@ ], "exports": { ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" + "types": "./dist/dev/index.d.ts", + "development": "./dist/dev/index.js", + "default": "./dist/default/index.js" }, "./dom": { - "types": "./dist/dom.d.ts", - "default": "./dist/dom.js" + "types": "./dist/dev/dom.d.ts", + "development": "./dist/dev/dom.js", + "default": "./dist/default/dom.js" } }, - "main": "dist/index.js", - "module": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/default/index.js", + "module": "dist/default/index.js", + "types": "dist/dev/index.d.ts", "files": [ "dist" ], diff --git a/packages/core/src/dom/globals.d.ts b/packages/core/src/dom/globals.d.ts new file mode 100644 index 00000000..b867229b --- /dev/null +++ b/packages/core/src/dom/globals.d.ts @@ -0,0 +1 @@ +declare const __DEV__: boolean; diff --git a/packages/core/src/dom/utils/log.ts b/packages/core/src/dom/utils/log.ts index 36577f86..c8137e58 100644 --- a/packages/core/src/dom/utils/log.ts +++ b/packages/core/src/dom/utils/log.ts @@ -1,6 +1,7 @@ const warned = new Set(); export function logMissingFeature(displayName: string, featureName: string): void { + if (!__DEV__) return; const key = `${displayName}:${featureName}`; if (warned.has(key)) return; diff --git a/packages/core/src/globals.d.ts b/packages/core/src/globals.d.ts new file mode 100644 index 00000000..b867229b --- /dev/null +++ b/packages/core/src/globals.d.ts @@ -0,0 +1 @@ +declare const __DEV__: boolean; diff --git a/packages/core/tsdown.config.ts b/packages/core/tsdown.config.ts index 83d50398..8b44ee4e 100644 --- a/packages/core/tsdown.config.ts +++ b/packages/core/tsdown.config.ts @@ -1,6 +1,11 @@ +import type { Options } from 'tsdown'; import { defineConfig } from 'tsdown'; -export default defineConfig({ +type BuildMode = 'dev' | 'default'; + +const buildModes: BuildMode[] = ['dev', 'default']; + +const createConfig = (mode: BuildMode): Options => ({ entry: { index: './src/core/index.ts', dom: './src/dom/index.ts', @@ -12,5 +17,11 @@ export default defineConfig({ alias: { '@': new URL('./src/core', import.meta.url).pathname, }, - dts: true, + outDir: `dist/${mode}`, + define: { + __DEV__: mode === 'dev' ? 'true' : 'false', + }, + dts: mode === 'dev', }); + +export default defineConfig(buildModes.map((mode) => createConfig(mode))); diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts index 3b0d0e89..3c8f3f6a 100644 --- a/packages/core/vitest.config.ts +++ b/packages/core/vitest.config.ts @@ -1,6 +1,9 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ + define: { + __DEV__: 'true', + }, test: { projects: [ { diff --git a/packages/html/package.json b/packages/html/package.json index 2cf8a454..f975f93f 100644 --- a/packages/html/package.json +++ b/packages/html/package.json @@ -14,36 +14,42 @@ ], "exports": { ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" + "types": "./dist/dev/index.d.ts", + "development": "./dist/dev/index.js", + "default": "./dist/default/index.js" }, "./player/*": { - "types": "./dist/define/player/*.d.ts", - "default": "./dist/define/player/*.js" + "types": "./dist/dev/define/player/*.d.ts", + "development": "./dist/dev/define/player/*.js", + "default": "./dist/default/define/player/*.js" }, "./ui/*": { - "types": "./dist/define/ui/*.d.ts", - "default": "./dist/define/ui/*.js" + "types": "./dist/dev/define/ui/*.d.ts", + "development": "./dist/dev/define/ui/*.js", + "default": "./dist/default/define/ui/*.js" }, "./skin/*": { - "types": "./dist/define/skin/*.d.ts", - "default": "./dist/define/skin/*.js" + "types": "./dist/dev/define/skin/*.d.ts", + "development": "./dist/dev/define/skin/*.js", + "default": "./dist/default/define/skin/*.js" }, "./feature/*": { - "types": "./dist/define/feature/*.d.ts", - "default": "./dist/define/feature/*.js" + "types": "./dist/dev/define/feature/*.d.ts", + "development": "./dist/dev/define/feature/*.js", + "default": "./dist/default/define/feature/*.js" }, "./media/*": { - "types": "./dist/define/media/*.d.ts", - "default": "./dist/define/media/*.js" + "types": "./dist/dev/define/media/*.d.ts", + "development": "./dist/dev/define/media/*.js", + "default": "./dist/default/define/media/*.js" } }, "sideEffects": [ - "./dist/define/**/*.js" + "./dist/*/define/**/*.js" ], - "main": "dist/index.js", - "module": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/default/index.js", + "module": "dist/default/index.js", + "types": "dist/dev/index.d.ts", "files": [ "dist" ], diff --git a/packages/html/src/globals.d.ts b/packages/html/src/globals.d.ts new file mode 100644 index 00000000..b867229b --- /dev/null +++ b/packages/html/src/globals.d.ts @@ -0,0 +1 @@ +declare const __DEV__: boolean; diff --git a/packages/html/tsdown.config.ts b/packages/html/tsdown.config.ts index 2caaac63..7f2a5db4 100644 --- a/packages/html/tsdown.config.ts +++ b/packages/html/tsdown.config.ts @@ -1,6 +1,11 @@ import { globSync } from 'node:fs'; +import type { Options } from 'tsdown'; import { defineConfig } from 'tsdown'; +type BuildMode = 'dev' | 'default'; + +const buildModes: BuildMode[] = ['dev', 'default']; + const defineEntries = Object.fromEntries( globSync('src/define/**/*.ts').map((file) => { const key = file.replace('src/', '').replace('.ts', ''); @@ -8,7 +13,7 @@ const defineEntries = Object.fromEntries( }) ); -export default defineConfig({ +const createConfig = (mode: BuildMode): Options => ({ entry: { index: 'src/index.ts', ...defineEntries, @@ -20,5 +25,11 @@ export default defineConfig({ alias: { '@': new URL('./src', import.meta.url).pathname, }, - dts: true, + outDir: `dist/${mode}`, + define: { + __DEV__: mode === 'dev' ? 'true' : 'false', + }, + dts: mode === 'dev', }); + +export default defineConfig(buildModes.map((mode) => createConfig(mode))); diff --git a/packages/html/vitest.config.ts b/packages/html/vitest.config.ts index 162fb279..6fc9357e 100644 --- a/packages/html/vitest.config.ts +++ b/packages/html/vitest.config.ts @@ -1,6 +1,9 @@ import { defineConfig } from 'vitest/config'; export default defineConfig({ + define: { + __DEV__: 'true', + }, test: { passWithNoTests: true, onConsoleLog: (log) => !log.includes('Lit is in dev mode'), diff --git a/packages/react/package.json b/packages/react/package.json index aa4de8bb..58f4a910 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -14,13 +14,14 @@ ], "exports": { ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" + "types": "./dist/dev/index.d.ts", + "development": "./dist/dev/index.js", + "default": "./dist/default/index.js" } }, - "main": "dist/index.js", - "module": "dist/index.js", - "types": "dist/index.d.ts", + "main": "dist/default/index.js", + "module": "dist/default/index.js", + "types": "dist/dev/index.d.ts", "files": [ "dist" ], diff --git a/packages/react/src/globals.d.ts b/packages/react/src/globals.d.ts new file mode 100644 index 00000000..b867229b --- /dev/null +++ b/packages/react/src/globals.d.ts @@ -0,0 +1 @@ +declare const __DEV__: boolean; diff --git a/packages/react/src/player/create-player.tsx b/packages/react/src/player/create-player.tsx index 6137390e..30b7de6d 100644 --- a/packages/react/src/player/create-player.tsx +++ b/packages/react/src/player/create-player.tsx @@ -45,7 +45,7 @@ export function createPlayer( return {children}; } - if (config.displayName) { + if (__DEV__ && config.displayName) { Provider.displayName = `${config.displayName}.Provider`; } diff --git a/packages/react/src/ui/hooks/use-button.ts b/packages/react/src/ui/hooks/use-button.ts index f9329717..04d04396 100644 --- a/packages/react/src/ui/hooks/use-button.ts +++ b/packages/react/src/ui/hooks/use-button.ts @@ -39,7 +39,7 @@ export function useButton(params: UseButtonParameters): UseButtonReturnValue { const buttonRef = useCallback( (element: HTMLElement | null) => { - if (element && element.tagName !== 'BUTTON') { + if (__DEV__ && element && element.tagName !== 'BUTTON') { console.warn(`${displayName} should render a