Skip to content

IcePanel/vue-composition-migrator

Repository files navigation

Vue Composition Migrator

A CLI tool to automatically migrate Vue 2 Class Components to Vue 3 Composition API with <script setup> syntax.

Inspired by the Vue Class Migrator tool.

Features

  • ✅ Converts Vue Class Components to Composition API
  • ✅ Supports <script setup> syntax
  • ✅ Handles props with @Prop decorator
  • ✅ Converts class properties to ref/reactive with smart detection
  • ✅ Transforms @Watch decorators
  • ✅ Converts computed properties (getters/setters)
  • ✅ Transforms methods and lifecycle hooks
  • ✅ Detects and extracts composables (e.g., useRouter, useStore)
  • ✅ Supports Pinia stores
  • ✅ Preserves TypeScript types
  • ✅ Works with both .ts and .vue files
  • ✅ Handles complex reactive object assignments
  • ✅ Extracts emits from $emit calls
  • ✅ Dry-run mode for safe testing
  • ✅ Backup option for original files

Testing Locally

Quick Start

# Clone and build the project
git clone <this-repo>
cd vue-composition-migrator
npm install
npm run build

cd /path/to/your/vue2-project
path/to/vue-composition-migrator/dist migrate -d ./src --dry-run

Alternative: Run directly without installing

# From the vue-composition-migrator directory
cd vue-composition-migrator
npm install
npm run build

# Run on your Vue 2 project
node ./dist/cli.js migrate -d /path/to/your/vue2-project/src --dry-run

Testing on a single file first

# Test on a single component to see how it works
vue-composition-migrator check ./src/components/YourComponent.vue

# Or with the direct method
node /path/to/vue-composition-migrator/dist/cli.js check ./src/components/YourComponent.vue

Usage

Migrate a directory

# Always start with a check to see how certain files will be migrated
vue-composition-migrator check ./src/components/MyComponent.vue

# When ready, run the actual migration
vue-composition-migrator migrate -d ./src

Migrate specific file types

# Only migrate .vue files
vue-composition-migrator migrate -d ./src -p "**/*.vue"

# Only migrate components directory
vue-composition-migrator migrate -d ./src/components

# Migrate a specific pattern
vue-composition-migrator migrate -d ./src -p "**/User*.vue"

Check a single file

# Preview how a single file would be migrated
vue-composition-migrator check ./src/components/MyComponent.vue

Options

  • -d, --directory <path> - Directory to migrate (default: current directory)
  • -p, --pattern <glob> - File pattern to match (default: **/*.{vue,ts})

Example Migration

Before (Class Component)

import { Component, Vue, Prop } from 'vue-property-decorator';

@Component
export default class UserCard extends Vue {
  @Prop({ required: true }) name!: string;
  @Prop({ default: 0 }) age!: number;

  private userStore = useUserStore();
  count = 0;
  user = { name: 'John', email: '[email protected]' };

  get displayName() {
    return `${this.name} (${this.age})`;
  }

  mounted() {
    console.log('Component mounted');
    this.loadUser();
  }

  async loadUser() {
    this.user = await this.userStore.fetchUser();
  }

  increment() {
    this.count++;
  }
}

After (Composition API with <script setup>)

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { useUserStore } from '@/stores'

const props = defineProps<{
  name: string
  age?: number
}>()

const userStore = useUserStore()

const count = ref<number>(0)
const user = reactive({ name: 'John', email: '[email protected]' })

const displayName = computed(() => {
  return `${props.name} (${props.age})`
})

const loadUser = async () => {
  Object.assign(user, await userStore.fetchUser())
}

const increment = () => {
  count.value++
}

onMounted(() => {
  console.log('Component mounted')
  loadUser()
})
</script>

Supported Features

Currently Supported

  • @Component decorator
  • @Prop decorator (with types, defaults, required, validators)
  • @Watch decorator (with options like immediate, deep)
  • ✅ Class properties → smart ref/reactive detection:
    • Primitives, arrays, and nullables → ref
    • Objects → reactive
  • ✅ Computed properties (getters and getter/setter pairs)
  • ✅ Methods transformation with proper this reference handling
  • ✅ Lifecycle hooks → Composition API equivalents
  • ✅ Emit detection from $emit calls → defineEmits
  • ✅ Composables detection and extraction (including Pinia stores)
  • ✅ Complex reactive object assignments → Object.assign
  • ✅ Full TypeScript support with type preservation
  • ✅ Vue SFC (.vue) files with template and style preservation

Coming Soon

  • 🚧 @Emit decorator
  • 🚧 @Model and @PropSync decorators
  • 🚧 Vuex @State, @Getter, @Action decorators
  • 🚧 Mixins support
  • 🚧 Provide/Inject pattern

Troubleshooting

Common Issues

  1. "No Vue class component found in file"

    • Make sure your component uses the @Component decorator
    • The tool only migrates Vue Class Components, not Options API components
  2. Build errors after migration

    • Check that all imports are correctly resolved
    • Some composables might need to be installed separately
    • Reactive object assignments might need manual review
  3. Type errors

    • The tool preserves TypeScript types, but some might need adjustment
    • Check that imported types are still available
  4. Runtime errors

    • Reactive objects can't be reassigned directly; use Object.assign
    • Refs need .value access in script (but not in template)

Best Practices

  1. Test one component at a time with the check command before bulk migration
  2. Run your test suite after migration to catch any issues
  3. Commit your code before running the migration

Limitations

  • The tool uses AST manipulation, so it preserves the exact structure of your code
  • Complex class inheritance patterns may require manual intervention
  • Some edge cases in decorator usage might not be fully supported
  • Mixins are not yet supported and need manual migration

Development

# Install dependencies
npm install

# Run tests
npm test

# Build the project
npm run build

# Run in development mode
npm run dev

License

MIT

About

A CLI tool to help migrate from Vue Class based components to Vue Composition API components

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published