legacy-modernizer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +290 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +534 -0
- package/dist/index.mjs +497 -0
- package/dist/reporters/analysis.d.ts +8 -0
- package/dist/reporters/analysis.test.d.ts +1 -0
- package/dist/reporters/locale.d.ts +2 -0
- package/dist/scanners/legacy-scanner.d.ts +16 -0
- package/dist/scanners/legacy-scanner.test.d.ts +1 -0
- package/dist/scanners/rules/eslint-modernize.d.ts +3 -0
- package/dist/scanners/rules/index.d.ts +3 -0
- package/dist/scanners/rules/jest-to-vitest.d.ts +2 -0
- package/dist/scanners/rules/js-to-ts.d.ts +3 -0
- package/dist/scanners/rules/vue2-to-vue3.d.ts +2 -0
- package/dist/scanners/rules/vuex-to-pinia.d.ts +2 -0
- package/dist/scanners/rules/webpack-to-vite.d.ts +2 -0
- package/dist/types.d.ts +140 -0
- package/dist/utils/config.d.ts +8 -0
- package/dist/utils/format.d.ts +13 -0
- package/package.json +73 -0
package/README.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# ๐๏ธ Legacy Modernizer
|
|
2
|
+
|
|
3
|
+
> AI-powered legacy code modernization for frontend projects โ Vue 2โ3, JSโTS, WebpackโVite โ with semantic understanding, not just regex replacement.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/legacy-modernizer)
|
|
6
|
+
[](https://github.com/saqqdy/legacy-modernizer/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
[ไธญๆๆๆกฃ](README_CN.md)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## ๐ฏ The Problem It Solves
|
|
13
|
+
|
|
14
|
+
| Scenario | Traditional Tools (codemod) | Legacy Modernizer |
|
|
15
|
+
|----------|---------------------------|-------------------|
|
|
16
|
+
| `this.$refs.input` โ ? | Rule: `this.$refs.xxx โ ???` โ can't decide ref vs useTemplateRef | AI understands: "this ref is used in mounted for focus()" โ `useTemplateRef('input')` + `onMounted` |
|
|
17
|
+
| Mixin โ Composable | Rule matching only โ can't merge overlapping state | AI understands business logic boundaries โ clean composable extraction |
|
|
18
|
+
| `process.env.X` โ ? | Simple find-replace โ `import.meta.env.X` | AI checks what X is and whether it needs `VITE_` prefix |
|
|
19
|
+
|
|
20
|
+
**Core insight**: Migration requires understanding code *intent*, not just syntax patterns.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## โจ Core Features
|
|
25
|
+
|
|
26
|
+
### ๐ Multi-Dimension Scanning
|
|
27
|
+
|
|
28
|
+
Scan your project for legacy patterns across 6 migration dimensions:
|
|
29
|
+
|
|
30
|
+
- **Vue 2โ3**: Options API, $refs, $emit, mixins, filters, etc.
|
|
31
|
+
- **JSโTS**: Untyped files, PropTypes, JSDoc types
|
|
32
|
+
- **WebpackโVite**: Config files, require.context, process.env
|
|
33
|
+
- **JestโVitest**: Global functions, config files
|
|
34
|
+
- **VuexโPinia**: Store instances, map helpers
|
|
35
|
+
- **ESLint Modernization**: Legacy config formats
|
|
36
|
+
|
|
37
|
+
### ๐ Structured Analysis Report
|
|
38
|
+
|
|
39
|
+
Generate a detailed report with risk assessment and recommended migration order:
|
|
40
|
+
|
|
41
|
+
- Pattern breakdown by dimension and severity
|
|
42
|
+
- Risk level (low/medium/high) with reasoning
|
|
43
|
+
- Recommended migration order
|
|
44
|
+
- Effort estimation (person-days)
|
|
45
|
+
|
|
46
|
+
### ๐ง AI Semantic Migration (v0.2.0+)
|
|
47
|
+
|
|
48
|
+
Not just regex โ AI understands your code's intent and produces semantically equivalent modern code:
|
|
49
|
+
|
|
50
|
+
- **Options API โ Composition API**: `data()` โ `ref()`, `computed:{}` โ `computed()`, etc.
|
|
51
|
+
- **Mixin โ Composable**: Understands business logic boundaries
|
|
52
|
+
- **Vue 2 APIs โ Vue 3**: `$refs` โ `useTemplateRef`, `$emit` โ `defineEmits`, etc.
|
|
53
|
+
|
|
54
|
+
### ๐ Interactive Migration Wizard (v0.7.0+)
|
|
55
|
+
|
|
56
|
+
Step-by-step guided migration with diff preview and confirmation at every step.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## ๐ Getting Started
|
|
61
|
+
|
|
62
|
+
### Option 1: Claude Code Skill (Recommended)
|
|
63
|
+
|
|
64
|
+
This is the core usage โ drive migration directly in Claude Code with natural language:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cd your-project
|
|
68
|
+
git clone https://github.com/saqqdy/legacy-modernizer.git .legacy-modernizer
|
|
69
|
+
cp -r .legacy-modernizer/.claude/skills/ .claude/skills/
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Then in Claude Code:
|
|
73
|
+
|
|
74
|
+
| Command | Description |
|
|
75
|
+
|---------|-------------|
|
|
76
|
+
| `/analyze` | Scan current project for legacy patterns, generate migration report |
|
|
77
|
+
| `/modernize` | Launch interactive migration wizard: scan โ select dimensions โ generate plan โ step-by-step migration |
|
|
78
|
+
|
|
79
|
+
**How it works:**
|
|
80
|
+
1. Open Claude Code in a Vue 2 legacy project
|
|
81
|
+
2. Type `/analyze` โ get a full legacy pattern analysis report
|
|
82
|
+
3. Type `/modernize` โ select migration dimension (e.g. Vue 2โ3), confirm diffs file by file
|
|
83
|
+
|
|
84
|
+
### Option 2: Programmatic Usage
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pnpm add legacy-modernizer
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { scanProject, scanFileContent, renderAnalysisReport } from 'legacy-modernizer'
|
|
92
|
+
|
|
93
|
+
// Full project scan
|
|
94
|
+
const report = await scanProject({
|
|
95
|
+
root: process.cwd(),
|
|
96
|
+
include: ['**/*.{vue,js,ts}'],
|
|
97
|
+
exclude: ['node_modules/**', 'dist/**'],
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
console.log(renderAnalysisReport(report))
|
|
101
|
+
// Or access structured data directly
|
|
102
|
+
console.log(`Found ${report.totalPatterns} patterns in ${report.totalFiles} files`)
|
|
103
|
+
console.log(`Risk: ${report.risk.level} โ ${report.risk.reason}`)
|
|
104
|
+
|
|
105
|
+
// Single file scan
|
|
106
|
+
const patterns = scanFileContent(content, 'src/components/Counter.vue')
|
|
107
|
+
patterns.forEach(p => console.log(`[${p.severity}] ${p.name}: ${p.suggestion}`))
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Option 3: Playground
|
|
111
|
+
|
|
112
|
+
Try it online without any installation:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Clone the repo and start Playground
|
|
116
|
+
git clone https://github.com/saqqdy/legacy-modernizer.git
|
|
117
|
+
cd legacy-modernizer
|
|
118
|
+
pnpm install
|
|
119
|
+
pnpm run playground
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The Playground ships with built-in legacy code samples so you can:
|
|
123
|
+
- ๐ Select different sample files to see scan results
|
|
124
|
+
- โ๏ธ Edit code and see real-time legacy pattern detection
|
|
125
|
+
- ๐ View structured analysis reports
|
|
126
|
+
- ๐ Toggle Chinese/English report language
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## ๐ Scan Rules Reference
|
|
131
|
+
|
|
132
|
+
### Vue 2โ3 (15 rules)
|
|
133
|
+
|
|
134
|
+
| Rule ID | Name | Severity | Description |
|
|
135
|
+
|---------|------|----------|-------------|
|
|
136
|
+
| `vue2-options-api` | Options API component | ๐ต info | Rewrite using `<script setup>` + Composition API |
|
|
137
|
+
| `vue2-data-function` | data() option | ๐ต info | Replace with ref() / reactive() |
|
|
138
|
+
| `vue2-computed-option` | computed:{} option | ๐ต info | Replace with computed(() => ...) |
|
|
139
|
+
| `vue2-methods-option` | methods:{} option | ๐ต info | Rewrite as plain functions |
|
|
140
|
+
| `vue2-watch-option` | watch:{} option | ๐ต info | Replace with watch() / watchEffect() |
|
|
141
|
+
| `vue2-this-refs` | this.$refs | ๐ก warning | Replace with useTemplateRef() |
|
|
142
|
+
| `vue2-this-emit` | this.$emit | ๐ก warning | Replace with defineEmits() |
|
|
143
|
+
| `vue2-this-router` | this.$router / this.$route | ๐ก warning | Replace with useRouter() / useRoute() |
|
|
144
|
+
| `vue2-this-store` | this.$store | ๐ก warning | Replace with useStore() or migrate to Pinia |
|
|
145
|
+
| `vue2-filters` | filters:{} option | ๐ด critical | Vue 3 removed filters โ use computed or methods |
|
|
146
|
+
| `vue2-event-bus` | $on / $off / $once | ๐ด critical | Use mitt or tiny-emitter instead |
|
|
147
|
+
| `vue2-destroyed` | destroyed / beforeDestroy | ๐ก warning | Replace with unmounted / beforeUnmount |
|
|
148
|
+
| `vue2-mixins` | mixins:[] option | ๐ก warning | Replace with Composables |
|
|
149
|
+
| `vue2-v-bind-sync` | v-bind.sync modifier | ๐ด critical | Replace with v-model:xxx |
|
|
150
|
+
| `vue2-v-on-native` | v-on.native modifier | ๐ก warning | Declare in emits option instead |
|
|
151
|
+
|
|
152
|
+
### JSโTS (4 rules)
|
|
153
|
+
|
|
154
|
+
| Rule ID | Name | Severity | Description |
|
|
155
|
+
|---------|------|----------|-------------|
|
|
156
|
+
| `js-prop-types` | PropTypes validation | ๐ก warning | Replace with TypeScript interface |
|
|
157
|
+
| `js-jsdoc-types` | JSDoc type annotations | ๐ต info | Migrate JSDoc types to inline TypeScript types |
|
|
158
|
+
| `js-commonjs-export` | CommonJS exports | ๐ต info | Replace with ES module export |
|
|
159
|
+
| `js-require-import` | require() import | ๐ต info | Replace with ES import |
|
|
160
|
+
|
|
161
|
+
### WebpackโVite (3 rules)
|
|
162
|
+
|
|
163
|
+
| Rule ID | Name | Severity | Description |
|
|
164
|
+
|---------|------|----------|-------------|
|
|
165
|
+
| `webpack-config` | webpack.config file | ๐ต info | Migrate to vite.config.ts |
|
|
166
|
+
| `webpack-require-context` | require.context | ๐ก warning | Vite uses import.meta.glob instead |
|
|
167
|
+
| `webpack-process-env` | process.env usage | ๐ต info | Vite uses import.meta.env instead |
|
|
168
|
+
|
|
169
|
+
### JestโVitest (2 rules)
|
|
170
|
+
|
|
171
|
+
| Rule ID | Name | Severity | Description |
|
|
172
|
+
|---------|------|----------|-------------|
|
|
173
|
+
| `jest-config` | Jest config detected | ๐ต info | Migrate to vitest.config.ts |
|
|
174
|
+
| `jest-global` | Jest global functions | ๐ก warning | Replace with vitest imports (vi, describe, it, expect) |
|
|
175
|
+
|
|
176
|
+
### VuexโPinia (2 rules)
|
|
177
|
+
|
|
178
|
+
| Rule ID | Name | Severity | Description |
|
|
179
|
+
|---------|------|----------|-------------|
|
|
180
|
+
| `vuex-store` | Vuex store usage | ๐ต info | Migrate to Pinia defineStore() |
|
|
181
|
+
| `vuex-map-state` | mapState / mapGetters | ๐ก warning | Pinia uses storeToRefs() instead |
|
|
182
|
+
|
|
183
|
+
### ESLint Modernization (2 rules)
|
|
184
|
+
|
|
185
|
+
| Rule ID | Name | Severity | Description |
|
|
186
|
+
|---------|------|----------|-------------|
|
|
187
|
+
| `eslint-legacy-config` | Legacy ESLint config format | ๐ต info | Migrate to ESLint 9 flat config |
|
|
188
|
+
| `eslint-override-array` | ESLint overrides array | ๐ต info | Flat config uses multiple config objects |
|
|
189
|
+
|
|
190
|
+
> **Total**: 6 dimensions, 28 detection rules
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## ๐ Version Roadmap
|
|
195
|
+
|
|
196
|
+
| Version | Codename | Theme | Status |
|
|
197
|
+
|---------|----------|-------|--------|
|
|
198
|
+
| v0.1.0 | Daybreak | Plugin skeleton + `/analyze` scanner | โ
Current |
|
|
199
|
+
| v0.2.0 | Sunrise | Vue 2โ3 single-file migration MVP | ๐ Planned |
|
|
200
|
+
| v0.3.0 | Dawn | Agent-based batch migration + verification | ๐ Planned |
|
|
201
|
+
| v0.4.0 | Ember | JSโTS progressive migration | ๐ Planned |
|
|
202
|
+
| v0.5.0 | Catalyst | WebpackโVite build migration | ๐ Planned |
|
|
203
|
+
| v0.6.0 | Forge | Auxiliary migrations (JestโVitest, VuexโPinia, ESLint) | ๐ Planned |
|
|
204
|
+
| v0.7.0 | Compass | Interactive migration wizard | ๐ Planned |
|
|
205
|
+
| v0.8.0 | Anchor | Migration logging / rollback / documentation | ๐ Planned |
|
|
206
|
+
| v1.0.0 | Lighthouse | Production-ready + marketplace publishing | ๐ Planned |
|
|
207
|
+
| v2.0.0 | Horizon | Universal framework + React driver | ๐ฎ Future |
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## ๐๏ธ Project Structure
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
legacy-modernizer/
|
|
215
|
+
โโโ .claude/skills/legacy-modernizer/ # Skill prompts (core product)
|
|
216
|
+
โ โโโ skill.md # Main entry + command routing
|
|
217
|
+
โ โโโ analyze.md # Scan instructions
|
|
218
|
+
โ โโโ modernize.md # Migration wizard instructions
|
|
219
|
+
โโโ src/ # TypeScript source (programmatic API)
|
|
220
|
+
โ โโโ index.ts # Entry point, public API exports
|
|
221
|
+
โ โโโ types.ts # Core type definitions
|
|
222
|
+
โ โโโ scanners/ # Scanners
|
|
223
|
+
โ โ โโโ legacy-scanner.ts # Legacy pattern detector
|
|
224
|
+
โ โ โโโ rules/ # Per-dimension detection rules
|
|
225
|
+
โ โ โโโ index.ts # Rules aggregation
|
|
226
|
+
โ โ โโโ vue2-to-vue3.ts # 15 Vue 2โ3 rules
|
|
227
|
+
โ โ โโโ js-to-ts.ts # 4 JSโTS rules
|
|
228
|
+
โ โ โโโ webpack-to-vite.ts # 3 WebpackโVite rules
|
|
229
|
+
โ โ โโโ jest-to-vitest.ts # 2 JestโVitest rules
|
|
230
|
+
โ โ โโโ vuex-to-pinia.ts # 2 VuexโPinia rules
|
|
231
|
+
โ โ โโโ eslint-modernize.ts # 2 ESLint modernization rules
|
|
232
|
+
โ โโโ reporters/ # Report rendering
|
|
233
|
+
โ โ โโโ analysis.ts # Markdown report generation
|
|
234
|
+
โ โ โโโ locale.ts # Chinese/English labels
|
|
235
|
+
โ โโโ utils/ # Utility functions
|
|
236
|
+
โ โโโ config.ts # Config merging
|
|
237
|
+
โ โโโ format.ts # Output formatting
|
|
238
|
+
โโโ knowledge/ # Migration knowledge base
|
|
239
|
+
โโโ templates/ # Report templates
|
|
240
|
+
โโโ internal/ # Internal planning docs
|
|
241
|
+
โโโ docs/ # VitePress documentation site
|
|
242
|
+
โโโ playground/ # Interactive Playground
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## ๐ ๏ธ Development
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
pnpm install # Install dependencies
|
|
251
|
+
pnpm run lint # ESLint check + auto-fix
|
|
252
|
+
pnpm run typecheck # TypeScript type check
|
|
253
|
+
pnpm run test # Run tests (vitest)
|
|
254
|
+
pnpm run test:watch # Test watch mode
|
|
255
|
+
pnpm run test:coverage # Test coverage
|
|
256
|
+
pnpm run build # Build (ESM + CJS)
|
|
257
|
+
pnpm run dev # Watch mode development
|
|
258
|
+
pnpm run docs:dev # Start docs dev server
|
|
259
|
+
pnpm run playground # Start Playground
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Tech Stack
|
|
263
|
+
|
|
264
|
+
- **Language**: TypeScript 5.9+, strict mode
|
|
265
|
+
- **Build**: rolldown
|
|
266
|
+
- **Lint**: @eslint-sets/eslint-config (ESLint 9 flat config)
|
|
267
|
+
- **Formatting**: prettier + prettier-config-common
|
|
268
|
+
- **Testing**: vitest
|
|
269
|
+
- **Docs**: VitePress
|
|
270
|
+
- **Package Manager**: pnpm 9
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## ๐ Comparison
|
|
275
|
+
|
|
276
|
+
### vs vue-codemod / gogocode / ast-grep
|
|
277
|
+
|
|
278
|
+
| Dimension | Code Mods | Legacy Modernizer |
|
|
279
|
+
|-----------|-----------|-------------------|
|
|
280
|
+
| Approach | AST rule matching | AI semantic understanding |
|
|
281
|
+
| `this.$refs.xxx` โ ? | Can't decide ref vs useTemplateRef | Understands usage context |
|
|
282
|
+
| Mixin merging | Can only rename, not restructure | Extracts clean composables |
|
|
283
|
+
| Business logic | Ignores it | Recognizes boundaries |
|
|
284
|
+
| Error handling | Rule errors = broken output | Uncertain โ asks for confirmation |
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## ๐ License
|
|
289
|
+
|
|
290
|
+
[MIT](./LICENSE)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy Modernizer โ ้็ไปฃ็ ็ฐไปฃๅ
|
|
3
|
+
*
|
|
4
|
+
* ๅ
ฅๅฃๆจกๅ๏ผๅฏผๅบๆๆๅ
ฌๅผ API
|
|
5
|
+
*/
|
|
6
|
+
export { renderAnalysisReport } from './reporters/analysis';
|
|
7
|
+
export { scanFileContent, scanProject } from './scanners/legacy-scanner';
|
|
8
|
+
export type { ScannerOptions } from './types';
|
|
9
|
+
export type { AnalysisReport, DimensionConfig, DimensionStats, LegacyPattern, MigrationDimension, ModernizerConfig, PatternLine, PatternRule, PatternSeverity, RiskAssessment, RiskLevel, RiskThresholds, } from './types';
|
|
10
|
+
export { createPatternLine, VERSION } from './types';
|
|
11
|
+
export { getDefaultConfig, mergeConfig } from './utils/config';
|
|
12
|
+
export { dimensionLabel, formatDuration, patternToMarkdown, severityBadge, } from './utils/format';
|