Vue Codemod Scripts
vue-codemod is an experimental utility providing a collection of codemod scripts to assist developers in updating Vue.js APIs, primarily for migrating applications from Vue 2 to Vue 3. It leverages Facebook's JSCodeshift for abstract syntax tree (AST) transformations and offers specific support for `.vue` single-file components. As of version `0.0.5`, it includes transformations like `remove-vue-set-and-delete` and outlines a roadmap for further features, including TypeScript support and broader module system compatibility. Maintained by the Vue.js team, its "experimental" status and low version number indicate a development cadence focused on feature completion rather than rapid, frequent releases, positioning it as a tool for early adopters or those undertaking significant migrations. Its key differentiators include official Vue team backing and direct support for `.vue` file transformations, which are critical for comprehensive Vue application upgrades.
Common errors
-
Error: transformation <name> not found.
cause The specified transformation name does not exist among the built-in codemods, or the path to a custom transformation module is incorrect.fixVerify the transformation name against the list of included transformations in the `vue-codemod` documentation, or ensure the path to your custom transformation is accurate and accessible. -
Error: Path <path> does not exist.
cause The file or directory path provided to the `vue-codemod` CLI does not correspond to an existing location on the filesystem.fixDouble-check the provided `<path>` for typos, incorrect relative/absolute paths, or ensure that the target files/directory are accessible from where the command is executed. -
SyntaxError: Cannot use import statement outside a module
cause You are attempting to use an ES module syntax (`import`) in a CommonJS (`require`) environment, or vice-versa, when using the programmatic API or developing custom transformation scripts.fixFor ES modules, ensure your `package.json` includes `"type": "module"` or use `.mjs` file extensions. For CommonJS, use `require()` statements and `.cjs` file extensions if explicitly needed, or configure your bundler/runtime accordingly.
Warnings
- breaking Node.js versions below 10 are no longer supported since `v0.0.5`. Ensure your development environment uses Node.js 10 or higher.
- gotcha The package is currently in an experimental state (version 0.0.5). While officially maintained, developers should anticipate potential edge cases, subtle differences in migration, or incomplete transformations.
- gotcha The codemods are designed as part of a comprehensive Vue 3 migration strategy. Some issues may require manual fixes or reliance on ESLint rules (e.g., `eslint-plugin-vue@7`) rather than automated codemods.
Install
-
npm install vue-codemod -
yarn add vue-codemod -
pnpm add vue-codemod
Imports
- runTransformation
const { runTransformation } = require('vue-codemod')import { runTransformation } from 'vue-codemod' - CLI Usage (npx)
npx vue-codemod <path> -t <transformation> --params [transformation params]
- Specific Codemod (e.g., remove-vue-set-and-delete)
npx vue-codemod ./src -t remove-vue-set-and-delete
Quickstart
import { runTransformation } from 'vue-codemod';
import path from 'path';
import fs from 'fs';
import os from 'os';
// Create a temporary directory and file for the quickstart to operate on
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'vue-codemod-quickstart-'));
const filePath = path.join(tempDir, 'main.js');
const originalCode = 'import Vue from "vue";\nnew Vue().mount("#app");\nconsole.log("Hello Vue");';
fs.writeFileSync(filePath, originalCode, 'utf8');
const fileInfo = {
path: filePath,
source: fs.readFileSync(filePath, 'utf8')
};
// This dummy transformation replaces 'Vue' with 'App' for demonstration.
// In a real scenario, the 'transformation' argument for 'runTransformation'
// would typically be a loaded module from 'vue-codemod/dist/transformations/<name>'.
// The 'api' object passed to the transformation function contains 'jscodeshift'.
const dummyTransformation = (file: { path: string; source: string }, api: { jscodeshift: any }) => {
const j = api.jscodeshift;
const root = j(file.source);
return root.find(j.Identifier, { name: 'Vue' })
.replaceWith(j.identifier('App'))
.toSource();
};
async function applyCodemod() {
console.log(`Created temporary file at: ${filePath}`);
console.log(`Applying codemod to ${filePath}...`);
try {
const transformedCode = await runTransformation(
fileInfo,
dummyTransformation, // Pass the transformation function
{} // Optional parameters for the transformation
);
console.log('Transformation complete.');
console.log('Original code (first 50 chars):\n' + fileInfo.source.substring(0, 50) + '...');
console.log('Transformed code (first 50 chars):\n' + transformedCode.substring(0, 50) + '...');
// In a real application, you'd write `transformedCode` back to the file
// fs.writeFileSync(filePath, transformedCode, 'utf8');
} catch (error) {
console.error('Error during transformation:', error);
} finally {
// Clean up the temporary directory and file
fs.rmSync(tempDir, { recursive: true, force: true });
console.log(`Cleaned up temporary directory: ${tempDir}`);
}
}
applyCodemod();