| name | markbind-typescript-migration |
| description | Complete guide for migrating JavaScript files to TypeScript in the MarkBind project, including the two-commit strategy, import/export syntax conversion, and best practices. Use when migrating .js files to .ts in MarkBind's core package, preparing TypeScript migration pull requests, or understanding the Rename+Adapt commit workflow required for preserving git history. |
TypeScript Migration for MarkBind
MarkBind is progressively migrating backend code from JavaScript to TypeScript. This skill provides a complete guide for performing migrations that preserve git file history.
Critical Requirements
Two-Commit Strategy Required: TypeScript migrations MUST use two separate commits:
- "Rename" commit - Rename
.js to .ts only
- "Adapt" commit - Fix TypeScript errors and convert syntax
Update files incrementally: Migrate one component/directory in each commit to keep PRs focused and reviewable.
PR Merge Strategy: Use rebase-merge (not squash-merge) to keep both commits in target branch.
Strict TypeScript Settings: Migrations must adhere to existing strict TypeScript settings (no any types/disable linting without justification, etc.).
Quick Start Checklist
Before starting migration:
if @types/* are not available, assess if stand-in types should be created, or explore alternative packages that are actively maintained as replacements.
Migration Workflow Overview
Phase 0: Planning
- Identify files to migrate
- Determine work scope and order
- Seek approval from team before starting
Phase 1: Preparation
- Install type definitions for external dependencies
- Stash package.json changes
- Stop auto-compilation
Phase 2: "Rename" Commit
- Add compiled
.js paths to .gitignore and .eslintignore
- Rename
.js files to .ts
- Verify files show as "renamed" in git status
- Commit with
--no-verify (code doesn't compile yet)
Phase 3: "Adapt" Commit
- Start auto-compilation (
npm run dev)
- Convert import/export syntax
- Fix TypeScript errors
- Update dependent files
- Update package.json to add tsc compilation step if needed
- Run tests (npm run setup && npm run test && npm run lintfix)
- Commit normally
When to Migrate
Good Candidates
- Files with complex logic that benefit from types
- Files with many internal dependencies
- Core processing files (NodeProcessor, VariableProcessor, etc.)
- Files that are actively maintained
Avoid Migrating
- Files scheduled for deletion/major refactor
- External patches (keep matching upstream)
- Files with minimal logic
- Test files (can migrate later)
Detailed Step-by-Step Guide
For complete instructions with examples and troubleshooting, see:
Planning and Preparation
Rename Commit
Adapt Commit
Import/Export Syntax
Troubleshooting
Import/Export Quick Reference
Exports
| CommonJS | TypeScript Equivalent | ES6 |
|---|
module.exports = X | export = X | Avoid: export default (don't use) |
module.exports = { a, b } | export = { a, b } | Preferred: export { a, b } |
Imports
| CommonJS | TypeScript Equivalent | ES6 |
|---|
const X = require('a') | import X = require('a') | import X from 'a' |
const { a, b } = require('x') | Import whole object | import { a, b } from 'x' |
Rule: Match import syntax with export syntax.
Common Mistakes to Avoid
Don't
- Combine rename and adapt in one commit
- Use
export default during migration
- Skip type definitions installation
- Forget to add compiled files to ignore lists
- Use
any type without justification
- Push "Rename" commit without
--no-verify
Do
- Separate rename from adapt commits
- Install
@types/* packages before starting
- Verify files show as "renamed" in git status
- Document stand-in types with TODOs
- Test thoroughly before committing
- Use rebase-merge for PR
Testing Your Migration
Before Committing "Adapt"
npm run test
cd packages/core && npm run test
cd packages/cli && npm run test
Both must pass: Core tests verify .ts compilation, CLI tests verify compiled .js output.
What to Verify
Example Migrations
Reference these PRs for migration patterns:
Post-Migration
After your migration is merged:
Update Stand-in Types
If you created stand-in types for dependencies still in JavaScript:
- File issues to migrate those dependencies
- Update types when dependencies are migrated
- Remove TODOs
Update Documentation
If you migrated a major component:
- Update architecture docs if needed
- Note TypeScript-specific patterns
- Document any type utilities created
Quick Tips
Finding Files to Migrate
find packages/core/src -name "*.js" -type f
find packages/core/src -name "*.js" | wc -l
find packages/core/src -name "*.ts" | wc -l
Checking Git Similarity
git diff --cached --stat
Batch Renaming
find packages/core/src/html -name "*.js" -exec bash -c 'mv "$0" "${0%.js}.ts"' {} \;
Getting Help
If Stuck
- Read the detailed guides in
references/
- Check example PR #1877
- Search for similar migrations in git history
- Ask in PR comments with specific error messages
Common Questions
- "Do I need to migrate tests?" - No, focus on source files
- "What about external patches?" - Keep as JavaScript to match upstream
- "Can I migrate multiple directories?" - Yes, but keep PRs focused
- "Should I fix bugs while migrating?" - No, separate concerns
Configuration
TypeScript configuration is in root tsconfig.json. Don't modify without team discussion.
Current settings:
- Target: ES2020
- Module: CommonJS
- Strict: true
- Output: In-place compilation
Success Criteria
A successful migration:
- Two commits: "Rename" and "Adapt"
- Files show as renamed in first commit
- All tests pass
- No
any types (or justified)
- Import/export syntax consistent
- Dependent files updated
- Stand-in types documented
Your migration is ready when you can confidently say: "This TypeScript code provides better type safety without changing runtime behavior."