This article was submitted by bao Xue, a GoGoCode user

1. Why migrate Vue3.x

What to say? All in all… It’s not my fault!

First, write a case and find an executable solution.

2 Scheme Selection

Refer to the Vue2 Go to 3 official document

V3.cn.vuejs.org/guide/migra…

In the face of their own project hundred and eighty documents, artificial liver is certainly impossible, can not even think! The only solution is to deconstruct the code based on AST (abstract syntax tree), modify the output file in batches according to the modification suggestions of the upgrade document given by Vue official website. It’s just… The AST operation is a bit complicated.

I researched several tools and GitHub found several examples of removing console.log from the code file. Example of removing console.log from the AST using jscodeshift:

export default (fileInfo, api) => {
  const j = api.jscodeshift;
  const root = j(fileInfo.source)
  const callExpressions = root.find(j.CallExpression, {
      callee: {
        type: 'MemberExpression'.object: { type: 'Identifier'.name: 'console',}}}); callExpressions.remove();return root.toSource();
};
Copy the code

2. Use Babel operation AST to remove console.log example: (based on the length of the code omitted, interested students please visit github.com/mattphillip…)

export default function({
  types,
}: typeof BabelCore) :PluginObj<ConsoleTransformState> {
  return {
    name: 'console-transform'.visitor: {
      CallExpression(path, { opts, file }) {
        validateSchema(schema, opts);
        const { env, removeMethods, additionalStyleMethods } = opts;
        const callee = path.get('callee');       
        /* 40+ lines of code are omitted due to space limitations */,}}}; }Copy the code

Based on my strength, these two schemes are really a case of persuasion.

I was worried about the reconstruction of this project, and the volume of hair was rapidly decreasing. When I was looking for a solution in the community, I suddenly found the tool GoGoCode.

Post an official introduction:

GoGoCode is a tool for operating AST, which can lower the threshold of using AST and help developers to free themselves from tedious AST operations and focus more on the development of code analysis transformation logic. Simple substituting doesn’t even involve learning the AST, and after a preliminary study of the AST node structure (see the AST viewer), you can perform more complex analysis transformations.

Gogocode. IO/en /docs/spe…

This is not exactly what I want, meet you is the old saying, sleepy to someone pass a pillow! While GoGoCode operates AST to remove console.log from the code, only one line of code is required!!

$('Section of code to convert').find(`console.log($_$)`).remove()
Copy the code

Familiar $symbol, familiar find, remove and other API, button a question, said zero cost operation AST is not the title of the party!! Scheme selected!!

3 starts

One example: the migration scheme for key modifiers

Vue2 turn 3 official documentation – key modifier migration v3.cn.vuejs.org/guide/migra…

Here’s a brief summary of the changes:

  • Incompatible: The use of numbers (i.e., keycodes) as V-ON modifiers is no longer supported
  • Incompatible: Config. keyCodes are no longer supported

Write a Demo to be converted according to the document

<template> <div> <h1> Migration: key modifier </h1> <p> Migration policy: 1.Vue3 no longer supports the use of numbers (that is, key codes) as v-ON modifier 2. <div class="mt20 text-left"> <div>space:<input type="text" @keyup.space="keys('space')" /></div> <div>space:<input type="text" @keyup.32="keys('keycode 32 space')" /> </div> <div>space:<input type="text" @keyup.customSpace="keys('keycode 32 space')" /> </div> </div> </div> </template> <script> import Vue from 'vue'; Vue.config.keyCodes = { customSpace: 32, customDelete: 46 }; Export default {name: 'key modifier ', methods: {keys(key) {alert(' you're pressing' + key); ,}}}; </script>Copy the code

The task to determine

Analyze the content to be converted according to astExplorer.net

Amway: AstExplorer.net is a tool that allows you to easily view the AST syntax tree structure of a code

There are three things to do here:

1) Extract the customized keyCodes in the code (the content of the blue box vue.config. keyCodes in the figure above) and merge them with the system keyCodes into a map, which will be used in template replacement later;

2) Remove vue.config. keyCodes (no longer supported by Vue3);

3) Go through all the tags and their attributes and replace the tags with the merged keyCodes (in the red boxes xx.32 and xx.customSpace section of the figure above).

Transformation logic writing

  1. Run and install GoGoCode in the project
npm install gogocode
Copy the code
  1. Initialize the AST object of script
const$=require('gogocode');
// Script code to convert $to AST node
let scriptAst = $(` import Vue from 'vue'; Vue.config.keyCodes = { customSpace: 32, customDelete: 46 }; Export default {name: 'key modifier ', methods: {keys(key) {alert(' you're pressing' + key); ,}}}; `)
Copy the code
  1. We are looking for custom keyCodes in script (content section of vue.config.KeyCodes)

Use GoGoCode’s find API and match the wildcard $_$to get all the custom keyCode arrays

// Match to fetch the custom keyCode, the result: Node array
const customKeyCodeList = scriptAst.find(`Vue.config.keyCodes = {$_$}`).match[0]
Copy the code

KeyCodes = {$_$}, which can be obtained according to the AST node specificationastexplorer.netTool to verify



The console prints out customKeyCodeList, which is an array of nodes

  1. CustomKeyCodeList plus the system keyCode to construct a full keyCodeMap
// A full list of keyCode reference tables. Only three are listed based on length
// https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/keyCode
let keyCodeMap = {46: 'delete'.32: 'space'.112: 'f1'}
// Add a custom keyCode construct to summarize all keyCodemaps, which will be used later when replacing the template contents
// Result :{46: 'delete',32: 'space',112: 'f1', customSpace: 'space', customDelete: 'delete'}
for(let i = 0; i< customKeyCodeList.length; i=i+2) {Object.assign(keyCodeMap, {
        [customKeyCodeList[i].value] : keyCodeMap[customKeyCodeList[i+1].value]
    })
}
Copy the code

The console displays the result of the keyCodeMap construct

  1. Vue3 requirement: Vue.config.keyCodes are no longer supported and need to be removed. Find the node and use the Remove API to remove it
scriptAst.find(`Vue.config.keyCodes = $_$`).remove()
Copy the code
  1. To initialize the template node, the HTML template needs to take {parseOptions: {HTML: true}} arguments
let templateAst = $('
      `, { parseOptions: { html: true}})Copy the code
  1. Use the find, each, and attr apis to traverse all tags and their attributes, replacing the attribute names with keyCodeMap
//find+each iterates over all tag items
templateAst.find(['< $_ $> < / $_ $>'.'< $_ $/ >']).each((node) = > {
    // If the node has attributes, then the attributes are traversed
    if (Array.isArray(node.attr('content.attributes'))) {
        node.attr('content.attributes').forEach((attr) = > {
            // Use the summary keyCodeMap constructed above, instead of matching the attribute name such as @keyup.32 -> @keyup.space
            for (let keyItem in keyCodeMap) {
                if (attr.key.content.endsWith(`.${keyItem}`)) {
                    attr.key.content = attr.key.content.replace(`.${keyItem}`.`.${keyCodeMap[keyItem]}`)}}})}})Copy the code

The node.attr(‘content.attributes’) used here is the one just found in the Astexplorer.net tool

  1. Finally output, done, compare the results of the transformation

4 summarizes

There are only about 10 lines of AST-related operations in this code, and the rest is core transformation logic. GoGoCode can operate AST with the same experience as DOM with Jquery. It is easy to get started and easy to use

Starter has batch processing file demo github.com/thx/gogocod…

Github was quick to respond to the issue! Github.com/thx/gogocod…

It is really a code conversion tool

If you have any questions about this article, please feel free to respond.

Thank you. Have a nice day!

GoGoCode related links

GoGoCode Github repository (new projects for star ^_^) github.com/thx/gogocod…

GoGoCode’s official website is gogocode. IO /

Play on the playground for a quick play.gogocode. IO /