Skip to content

Commit 86a2211

Browse files
committed
feat: migrate to @nuxt/module-builder for proper TypeScript support
- Add @nuxt/module-builder dependency - Update tsconfig to extend .nuxt/tsconfig.json - Remove @ts-expect-error comments for virtual modules - Add RuntimeConfig type interface - Fix optional chaining in nitro plugin - Add dev:prepare script for stub generation - Fix type imports to eliminate 'any' usage This migration follows Nuxt ecosystem standards and properly handles virtual module types like #imports without workarounds. Authored by: Aaron Lippold<lippold@gmail.com>
1 parent 68510e0 commit 86a2211

File tree

11 files changed

+237
-128
lines changed

11 files changed

+237
-128
lines changed

CLAUDE.md

Lines changed: 75 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,65 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
66

77
Nuxt SmartScript is a Nuxt 3 module that performs automatic typography transformations in the browser. It transforms patterns like (TM) → ™, ordinals (1st, 2nd), chemical formulas (H2O), and mathematical notation (x^2, x_n) using client-side DOM manipulation.
88

9+
**Current Version**: 0.3.0 (broken) → 0.3.1 (ready for release)
10+
11+
## Critical Implementation Details
12+
13+
### Hybrid Element Approach (v0.3.1+)
14+
- **SPAN elements**: Used for TM/R symbols - allows CSS `position: relative` control
15+
- **SUP/SUB elements**: Used for math/chemicals - semantic HTML
16+
- **Why**: Browser limitation - SUP/SUB elements ignore `position: relative`
17+
18+
## Build System
19+
20+
This module uses **@nuxt/module-builder** - the official Nuxt module build system. This provides:
21+
- **Automatic type generation** for `#imports` and other virtual modules
22+
- **Stub builds** for faster development iteration
23+
- **Proper TypeScript configuration** that extends `.nuxt/tsconfig.json`
24+
- **Compatibility** with the Nuxt ecosystem standards
25+
26+
### Why Module Builder?
27+
Before adopting module-builder, we struggled with TypeScript errors for virtual modules like `#imports`. The module-builder solves this by:
28+
1. Generating proper type definitions in `.nuxt/` directory
29+
2. Providing the `dev:prepare` script that creates stubs and types
30+
3. Ensuring our module follows Nuxt best practices
31+
4. Handling the complex build pipeline automatically
32+
933
## Commands
1034

1135
### Development
1236
```bash
1337
# Install dependencies
1438
pnpm install
1539

40+
# Prepare development environment (IMPORTANT: Run this first!)
41+
# This generates .nuxt/tsconfig.json with proper types
42+
pnpm dev:prepare
43+
1644
# Run development playground
1745
pnpm dev
1846

1947
# Build module for production
2048
pnpm prepack
21-
22-
# Prepare development environment (stub builds)
23-
pnpm dev:prepare
2449
```
2550

2651
### Testing
2752
```bash
28-
# Run all tests
53+
# Run all tests (227 tests across all categories)
2954
pnpm test
3055

3156
# Run tests in watch mode
3257
pnpm test:watch
3358

34-
# Run a specific test file
35-
pnpm test typography
36-
pnpm test edge-cases
37-
pnpm test integration
59+
# Run specific test categories
60+
npx vitest run test/unit
61+
npx vitest run test/integration
62+
npx vitest run test/e2e
63+
npx vitest run test/performance
64+
npx vitest run test/unit/regression
3865

39-
# Check for test failures
40-
pnpm test 2>&1 | grep "×"
66+
# Run specific test file
67+
npx vitest run positioning.test.ts
4168

4269
# Type checking
4370
pnpm test:types
@@ -77,6 +104,20 @@ pnpm release
77104
- **Commit signatures**: Use `Authored by: Aaron Lippold<lippold@gmail.com>`
78105
- **NO Claude signatures** in commits
79106

107+
## Test Structure
108+
109+
```
110+
test/
111+
├── unit/ # Unit tests for individual functions
112+
│ └── regression/ # Regression tests for fixed bugs
113+
├── integration/ # Integration tests (JSDOM)
114+
├── e2e/ # End-to-end tests (Playwright/real browser)
115+
├── performance/ # Performance benchmarks
116+
├── helpers/ # Test utilities and setup
117+
├── fixtures/ # Test fixtures for E2E
118+
└── docs/ # Test documentation
119+
```
120+
80121
## Architecture
81122

82123
### Module Structure
@@ -159,14 +200,20 @@ export default defineNuxtConfig({
159200

160201
## Testing Approach
161202

162-
Tests are organized into:
163-
- `test/typography.test.ts` - Pattern matching tests
164-
- `test/edge-cases.test.ts` - Boundary conditions (41 tests)
165-
- `test/integration.test.ts` - Full pipeline tests
166-
- `test/math-notation.test.ts` - Math pattern specifics
167-
- `test/basic.test.ts` - Module loading test
203+
Tests use Vitest with environment-specific configurations:
204+
- **Unit tests**: JSDOM environment, fast execution
205+
- **Integration tests**: JSDOM with full processing pipeline
206+
- **E2E tests**: Real browser with Playwright, tests actual DOM behavior
207+
- **Performance tests**: Benchmarks for processing speed
208+
- **Regression tests**: Ensure fixed bugs don't reappear
209+
210+
Test helpers in `test/helpers/setup.ts` provide utilities:
211+
- `setupDOM()` / `cleanupDOM()` - JSDOM management
212+
- `createTestElement()` - Test element creation
213+
- `createTestConfig()` - Config generation
214+
- `countTransformedElements()` - Verification helpers
168215

169-
All 91 tests must pass before committing.
216+
All 227 tests must pass before committing.
170217

171218
## Key Technical Considerations
172219

@@ -176,6 +223,8 @@ All 91 tests must pass before committing.
176223
4. **DOM Safety**: Use TreeWalker and document fragments, never innerHTML
177224
5. **Exclusions**: Respect `no-superscript` class and `data-no-superscript` attribute
178225
6. **Content Detection**: Check for actual text changes, not just element type changes
226+
7. **Browser Limitations**: SUP/SUB elements don't respect `position: relative` - use SPAN for positioned elements
227+
8. **CSS Variables**: Applied via plugin at runtime, customizable per project
179228

180229
## Common Issues and Solutions
181230

@@ -216,5 +265,12 @@ The module is configured for npm publishing:
216265
- Entry: `dist/module.mjs`
217266
- Types: `dist/types.d.mts`
218267
- Build: `pnpm prepack`
219-
- Version: 0.1.0 (beta)
220-
- License: Apache-2.0
268+
- Current Version: 0.3.0 (has critical bugs)
269+
- Next Version: 0.3.1 (fixes all v0.3.0 issues)
270+
- License: Apache-2.0
271+
272+
### v0.3.1 Critical Fixes
273+
- Fixed config merging to include all properties (cssVariables were missing)
274+
- Implemented hybrid element approach (SPAN for TM/R, SUP/SUB for others)
275+
- Fixed registered symbol to use superscript
276+
- Updated all tests for new element types

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,19 +124,24 @@ We welcome contributions! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for de
124124

125125
### Development
126126

127+
This module is built using [@nuxt/module-builder](https://github.com/nuxt/module-builder) for proper TypeScript support and Nuxt ecosystem compatibility.
128+
127129
```bash
128130
# Install dependencies
129131
pnpm install
130132

133+
# Prepare development (generates types and stubs)
134+
pnpm dev:prepare
135+
136+
# Run development playground
137+
pnpm dev
138+
131139
# Run tests
132140
pnpm test
133141

134142
# Build module
135143
pnpm prepack
136144

137-
# Run playground
138-
pnpm dev
139-
140145
# Lint code
141146
pnpm lint
142147
```

playground/nuxt.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// @ts-expect-error - defineNuxtConfig is provided by Nuxt at runtime
21
export default defineNuxtConfig({
32
modules: ['../dist/module.mjs'],
43
devtools: { enabled: true },

pnpm-lock.yaml

Lines changed: 24 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { RuntimeConfig } from './runtime/types'
12
import { fileURLToPath } from 'node:url'
23
import { addPlugin, addServerPlugin, createResolver, defineNuxtModule } from '@nuxt/kit'
34

@@ -219,6 +220,6 @@ export default defineNuxtModule<ModuleOptions>({
219220
nuxt.options.css.push(resolver.resolve('./runtime/superscript.css'))
220221

221222
// Pass module options to runtime
222-
nuxt.options.runtimeConfig.public.smartscript = options
223+
nuxt.options.runtimeConfig.public.smartscript = options as unknown as RuntimeConfig
223224
},
224225
})

src/runtime/composables/useSmartScript.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
*/
44

55
import type { SuperscriptConfig } from '../smartscript/types'
6-
// @ts-expect-error - #imports is a virtual module
76
import { useNuxtApp } from '#imports'
87
import { onMounted, ref } from 'vue'
98

0 commit comments

Comments
 (0)