$ cnpm install vue-codemod
Current status: experimental
This repository contains a collection of codemod scripts for use with JSCodeshift that help update Vue.js APIs.
Inspired by react-codemod.
npx vue-codemod <path> -t <transformation> --params [transformation params] [...additional options]
transformation (required) - name of transformation, see available transformations below; or you can provide a path to a custom transformation module.path (required) - files or directory to transform.--params (optional) - additional transformation specific args.runTransformation(fileInfo, transformation, params)jscodeshift codemods to .vue filesvue-cli-plugin-vue-nextvue-eslint-parser for this)yarn playground and visit http://localhost:3000The migration path (to be integrated in a new version of vue-migration-helper):
vue3-essential category (maybe a few exceptions like vue/no-deprecated-dollar-scopedslots-api)eslint --fix to fix all auto-fixable issues; if there are any remaining errors, fix them manuallyNote: even though most of the migration process can be automated, please be aware there might still be subtle differences between Vue 3 and Vue 2 runtime, and the codemods may have uncovered edge cases. Please double check before deploying your Vue 3 app into production.
Legend of annotations:
| Mark | Description |
|---|---|
| ???? | work not started |
| ???? | needs to or can be implemented in the compat runtime |
v-bind's .sync with a v-model argument
vue/no-deprecated-v-bind-sync ESLint rulekeyCode support in v-on
vue/no-deprecated-v-on-number-modifiers ESLint ruleconfig.keyCode can be supported in the compat build. It is also detectable with the vue/no-deprecated-vue-config-keycodes ESLint ruledata object declaration
vue/no-shared-component-data and the vue/no-deprecated-data-object-declaration ESLint rulesvue/no-deprecated-slot-attribute and vue/no-deprecated-slot-scope-attributethis.$slots, recommending this.$scopedSlots as a replacement.$scopedSlots occurrences with .$slots (should pass the abovementioned ESLint checks before running this codemod) (implemented as scoped-slots-to-slots)new-global-apiimport Vue from 'vue' -> import * as Vue from 'vue' (implemented as vue-as-namespace-import)Vue.extend -> defineComponent (implemented as define-component)new Vue() -> Vue.createApp() (implemented as new-vue-to-create-app)
new Vue({ el }), new Vue().$mount -> Vue.createApp().mountnew HelloWorld({ el }), new HelloWorld().$mount -> createApp(HelloWorld).mountrender(h) -> render() and import { h } from 'vue' (implemented as remove-contextual-h-from-render)Vue.config.productionTip -> removed (implemented as remove-production-tip)global-to-per-app-api)
Vue.config, Vue.use, Vue.mixin, Vue.component, Vue.directive, etc -> app.** (It's possible to provide a runtime compatibility layer for single-root apps)Vue.prototype.customProperty -> app.config.globalProperties.customPropertyVue.config.ignoredElements -> app.config.isCustomElementVue.*, then transform the entry file to export the root instance, import it in other files and transform them with the imported root instance;optionMergeStrategies behavior changevue/no-deprecated-functional-template ESLint rule<template functional> should be converted to normal SFCsh
h calls to use the new VNode data format, since the mapping is pretty mechanical.bind -> beforeMountinserted -> mountedupdate hook and insert a comment to note the user about the changecomponentUpdated -> updatedunbind -> unmountedimport ... from '@vue/composition-api' -> import ... from 'vue' (implemented as import-composition-api-from-vue)inline-template
vue/no-deprecated-inline-template ESLint rule<Teleport> component
vue/no-reserved-component-names ESLint rule<Teleport> components to some other name like <TeleportComp>.import call to .vue filescomponent property being a dynamic import call.resolve/reject instead of returning promises. Manual upgrade will be required for such cases but they should be relatively rare.emits component option
emits options, so we need to scan and warn on such usagesemits option, we can provide a codemod that automatically scans all instances of $emit calls in a component and generate the emits optionnew-global-api and vuex-v4Vue.use(Vuex) & new Vue({ store }) -> app.use(store)new Store() -> createStore()new-global-api and vue-router-v4Vue.use(VueRouter) & new Vue({ router }) -> app.use(router)new VueRouter() -> createRouter()mode: 'history', base: BASE_URL etc. -> history: createWebHistory(BASE_URL) etc.router-linkrouter-linkvue-class-component 7.x to 8
import { Component } from 'vue-class-component' -> import { Options as Component } from 'vue-class-component'import Vue from 'vue' -> import { Vue } from 'vue-class-component' (Need to avoid name collision if there's any reference to Vue besides extends Vue)Component.registerHooks -> Vue.registerHookstransition as root
vue/require-toggle-inside-transition ESLint rulemeta fields from parent to child in RouteLocation
$listeners and .native usage@vue/composition-api and the Vue 3 implementation are listed in the @vue/composition-api READMEv-if and v-for have been flipped when using both on the same element.v-for and ref.$destroy, $childrenNote: there are just rough ideas. Amendments may or may not be proposed, depending on the implementation progress of this repo.
Vue.extend can be supported in a compat runtime as an alias to defineComponentv-model API change
v-model API because both the author and consumer of the components need to change their ways to use this API, according to the current RFC. So we might need a compatibility layer in the runtime.These features are only deprecated but still supported in the compatiblity builds. There will be runtime warnings and ESLint rules to detect their usages. Some of them can be automatically migrated with the help of codemods.
vue/no-deprecated-filter ESLint rule<transition> components with custom enter-class or leave-class:
enter-class -> enter-from-classleave-class -> leave-from-class.v-enter and .v-leave selector in the stylesheets to .v-enter-from and .v-leave-fromenter-from-class="v-enter v-enter-from" leave-from-class="v-leave v-leave-from" to these <transition> components. Users can delete these attributes after they updated the corresponding stylesheetsvue/no-deprecated-events-api ESLint ruleVue.config.ignoredElements -> app.config.isCustomElement<component> tags with is usage ->
<component is> (for SFC templates).v-is (for in-DOM templates).vue/no-deprecated-html-element-is ESLint rule can be used to detect usage for is usage on built-in HTML tags.set and delete instance or global methods will be supported only in IE compat builds.
remove-vue-set-and-deleteAside from migrating Vue 2 apps to Vue 3, this repository also includes some generic transformations that can help clean up your codebase.
remove-trivial-root
{ render: () => h(App) } and use App as the direct rootdefine-component
--param.useCompositionAPI: false by default. When set to true, it will import the defineComponent helper from @vue/composition-api instead of vuedefineComponent() wrapper to .vue file exports, and replaces Vue.extend calls to defineComponentSee https://github.com/facebook/jscodeshift#transform-module
eslint --fix.git diff --ignore-blank-lines | git apply --cached
Copyright 2013 - present © cnpmjs.org | Home |