|
| 1 | +# vue-codemod |
| 2 | + |
| 3 | +> ⚠️注意: 该仓库 fork 自 [https://github.com/vuejs/vue-codemod](https://github.com/vuejs/vue-codemod) |
| 4 | +
|
| 5 | +`vue-codemod` 是一个 `Vue2` 升级 `Vue3` 的语法转换工具,能将绝大多数 `Vue2` 语法直接升级成 `Vue3` 语法,然后通过少量的手动修改完成 `Vue2` 到 `Vue3` 的平滑迁移。 |
| 6 | + |
| 7 | +## 转化率 |
| 8 | + |
| 9 | +> 转换率 = 自动修改 / (需手动修改 + 自动修改) |
| 10 | +> |
| 11 | +> **需手动修改** 为工具识别到的手动修改数 |
| 12 | +> |
| 13 | +> **自动修改数** 为工具识别并自动处理的数量 |
| 14 | +
|
| 15 | +| 序号 | 项目 | 需手动修改 | 自动修改 | 转换率 | |
| 16 | +| :--: | :----------------------------------------------------------- | :--------- | -------- | :------ | |
| 17 | +| 1 | [vue2-element-touzi-admin](https://github.com/wdlhao/vue2-element-touzi-admin) | 8 | 63 | 88.73% | |
| 18 | +| 2 | [vue-web-os](https://github.com/a241978181/vue-web-os) | 19 | 19 | 50.00% | |
| 19 | +| 3 | [amKnow](https://github.com/Arlisol/amKnow) | 10 | 30 | 75.00% | |
| 20 | +| 4 | [vue-template](https://github.com/Ashyoo/vue-template) | 61 | 28 | 31.46% | |
| 21 | +| 5 | [coreui-free-vue-admin-template](https://github.com/coreui/coreui-free-vue-admin-template) | 4 | 63 | 94.03% | |
| 22 | +| 6 | [vue-weixin](https://github.com/bailichen/vue-weixin) | 1 | 54 | 98.19% | |
| 23 | +| 7 | [vue-WeChat](https://github.com/zhaohaodang/vue-WeChat) | 9 | 35 | 79.55% | |
| 24 | +| 8 | [vue2-management-platform](https://github.com/suweiteng/vue2-management-platform) | 2 | 11 | 84.62% | |
| 25 | +| 9 | [vue-netease-music](https://github.com/sl1673495/vue-netease-music) | 18 | 37 | 67.27% | |
| 26 | +| 10 | [Mall-Vue](https://github.com/PowerDos/Mall-Vue) | 2 | 26 | 92.86% | |
| 27 | +| 11 | [vue-demo-kugou](https://github.com/lavyun/vue-demo-kugou) | 4 | 13 | 76.47% | |
| 28 | +| 12 | [codemod-demo(codemod演示项目)](https://github.com/2kjiejie/codemod-demo/tree/master) | 0 | 24 | 100% | |
| 29 | + |
| 30 | +## 使用指引 |
| 31 | + |
| 32 | +### 安装 |
| 33 | + |
| 34 | +> 正式版本发布时更推荐使用 `npm/yarn` 方式,如果你更想尝鲜,可以使用 `clone` 本地安装方式 |
| 35 | +
|
| 36 | +#### `npm/yarn` 方式 |
| 37 | + |
| 38 | +``` bash |
| 39 | +npm install @originjs/vue-codemod -g |
| 40 | +//or |
| 41 | +yarn global add @originjs/vue-codemod |
| 42 | +``` |
| 43 | + |
| 44 | +#### `clone` 安装方式 |
| 45 | + |
| 46 | +1. 从 `github clone` 代码 |
| 47 | + |
| 48 | +```bash |
| 49 | +git clone https://github.com/originjs/vue-codemod |
| 50 | +``` |
| 51 | + |
| 52 | +2. 安装依赖 |
| 53 | + |
| 54 | +```bash |
| 55 | +cd vue-codemod |
| 56 | + |
| 57 | +npm install |
| 58 | +//or |
| 59 | +yarn install |
| 60 | +``` |
| 61 | + |
| 62 | +3. 全局安装 |
| 63 | + |
| 64 | +```bash |
| 65 | +npm run build |
| 66 | +npm install . -g |
| 67 | +//or |
| 68 | +yarn run build |
| 69 | +yarn global add . |
| 70 | +``` |
| 71 | + |
| 72 | +### 使用 |
| 73 | + |
| 74 | +`vue-codemod` 是由一条条转换规则组成,这些转换规则位于 `transformation/index.ts` 和 `vue-transformation/index.ts` 下。 |
| 75 | + |
| 76 | +``` bash |
| 77 | +npx vue-codemod <path> -t/-a [transformation params][...additional options] |
| 78 | +``` |
| 79 | + |
| 80 | +1. `<path>` 表示执行的路径,可以是文件和文件夹 |
| 81 | +2. `-t` 表示具体的规则,使用 `-t` 时 `transformation param` 不可省略,`-a` 表示所有规则 |
| 82 | + |
| 83 | +#### 执行所有规则 |
| 84 | + |
| 85 | +``` bash |
| 86 | +npx vue-codemod src -a |
| 87 | +``` |
| 88 | + |
| 89 | +`src` 指定的是扫描的文件路径,`-a` 表示执行所有的规则转换 |
| 90 | + |
| 91 | +#### 执行单条规则 |
| 92 | + |
| 93 | +```bash |
| 94 | +npx vue-codemod src -t new-global-api |
| 95 | +``` |
| 96 | + |
| 97 | +`src` 指定的是扫描的文件路径,`-t new-global-api` 表示只执行 `new-global-api` 这条规则。 |
| 98 | + |
| 99 | +详细的规则列表请 [点击此处](#规则清单) |
| 100 | + |
| 101 | +#### 规定输出格式 |
| 102 | + |
| 103 | +```bash |
| 104 | +npx vue-codemod src -a -f log |
| 105 | +``` |
| 106 | + |
| 107 | +`-f` 命令用于规定统计输出格式,可选参数为为 `table`、`detail` 、`log`,在没有指定参数的情况下默认为 `table`。 |
| 108 | + |
| 109 | +选择 `table` 时则会以表格的形式输出修改的规则,选择 `detail` 时会以对象形式输出具体修改的文件与规则,而选择 `log` 则会将统计报告以 log 文件的形式输出。 |
| 110 | + |
| 111 | +以下是`-f table`的输出样例: |
| 112 | + |
| 113 | +```bash |
| 114 | +╔═══════════════════════════════╤═══════╗ |
| 115 | +║ Rule Names │ Count ║ |
| 116 | +╟───────────────────────────────┼───────╢ |
| 117 | +║ new-component-api │ 1 ║ |
| 118 | +║ new-global-api │ 1 ║ |
| 119 | +║ vue-router-v4 │ 1 ║ |
| 120 | +║ vuex-v4 │ 1 ║ |
| 121 | +║ new-directive-api │ 1 ║ |
| 122 | +║ remove-vue-set-and-delete │ 2 ║ |
| 123 | +║ rename-lifecycle │ 2 ║ |
| 124 | +║ add-emit-declarations │ 1 ║ |
| 125 | +║ tree-shaking │ 1 ║ |
| 126 | +║ slot-attribute │ 1 ║ |
| 127 | +║ slot-default │ 1 ║ |
| 128 | +║ slot-scope-attribute │ 1 ║ |
| 129 | +║ v-for-template-key │ 2 ║ |
| 130 | +║ v-else-if-key │ 3 ║ |
| 131 | +║ transition-group-root │ 1 ║ |
| 132 | +║ v-for-v-if-precedence-changed │ 1 ║ |
| 133 | +║ remove-listeners │ 1 ║ |
| 134 | +║ remove-v-on-native │ 1 ║ |
| 135 | +╚═══════════════════════════════╧═══════╝ |
| 136 | +``` |
| 137 | + |
| 138 | +#### 手动迁移指导 |
| 139 | + |
| 140 | +在`vue-codemod`的运行过程中,会识别到需要手动修改的部分,并以对象的形式打印到控制台(如果有`-f log`命令,则会输出到log文件中),样例如下: |
| 141 | + |
| 142 | +```null |
| 143 | +The list that you need to migrate your codes mannually: |
| 144 | +index: 1 |
| 145 | +{ |
| 146 | + path: 'src/main.js', |
| 147 | + position: '[33,0]', |
| 148 | + name: 'remove Vue(global api)', |
| 149 | + suggest: "The rule of thumb is any APIs that globally mutate Vue's behavior are now moved to the app instance.", |
| 150 | + website: 'https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp' |
| 151 | +} |
| 152 | +``` |
| 153 | + |
| 154 | +#### 帮助 |
| 155 | + |
| 156 | +```bash |
| 157 | +npx vue-codemod --help |
| 158 | +``` |
| 159 | + |
| 160 | +结果如下所示 |
| 161 | + |
| 162 | +``` bash |
| 163 | +npx vue-codemod --help |
| 164 | +Usage: vue-codemod [file pattern] |
| 165 | + |
| 166 | +Options: |
| 167 | + -t, --transformation Name or path of the transformation module [string] |
| 168 | + -p, --params Custom params to the transformation |
| 169 | + -a, --runAllTransformation run all transformation module [boolean] |
| 170 | + -f, --reportFormatter Specify an output report formatter |
| 171 | + [string] [default: "detail"] |
| 172 | + -h, --help Show help [boolean] |
| 173 | + -v, --version Show version number [boolean] |
| 174 | + |
| 175 | +Examples: |
| 176 | + npx vue-codemod ./src -a Run all rules to convert all |
| 177 | + relevant files in the ./src folder |
| 178 | + npx vue-codemod Run slot-attribute rule to convert |
| 179 | + ./src/components/HelloWorld.vue -t HelloWorld.vue |
| 180 | + slot-attribute |
| 181 | +``` |
| 182 | + |
| 183 | +### 迁移步骤 |
| 184 | + |
| 185 | +1. 运行 `vue-codemod` 的 `-a` 命令: `npx vue-codemod <path> -a` |
| 186 | +2. 手动迁移 `vue-codemod` 没有覆盖到的特殊场景, 请参考 [手动迁移指南](./docs/zh/manual-guide.md). |
| 187 | +3. 确保使用 [@vue/compat](https://github.com/vuejs/vue-next/tree/master/packages/vue-compat) 兼容包运行 |
| 188 | +4. 在开发模式下启动项目,修复运行时告警 |
| 189 | + |
| 190 | +> 注意: 尽管大部分的迁移过程可以通过工具自动实现,但是 Vue 3 和 Vue 2 仍然有一些运行时的差异,并且有一些边缘场景 vue-codemod 也没有覆盖到。因此在部署生产环境之前,务必仔细检查迁移的正确性。 |
| 191 | +
|
| 192 | +### 典型迁移案例 |
| 193 | + |
| 194 | +我们 forked 了 [vue2-element-touzi-admin](https://github.com/wdlhao/vue2-element-touzi-admin),并尝试使用 `vue-codemod` 将该项目从 Vue 2 升级到 Vue 3,我们记录了升级过程中的每一步操作,如果您感兴趣,请参考[典型迁移案例](./docs/typical-case.md)。 |
| 195 | + |
| 196 | +## 规则清单 |
| 197 | + |
| 198 | +| 规则名称 | 描述或链接 | |
| 199 | +| --------------------------------- | ------------------------------------------------------------ | |
| 200 | +| new-component-api | https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp | |
| 201 | +| vue-class-component-v8 | https://github.com/vuejs/vue-class-component/issues/406 | |
| 202 | +| new-global-api | https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp | |
| 203 | +| vue-router-v4 | https://next.router.vuejs.org/guide/migration/index.html#new-router-becomes-createrouter<br>https://next.router.vuejs.org/guide/migration/index.html#new-history-option-to-replace-mode<br>https://next.router.vuejs.org/guide/migration/index.html#replaced-onready-with-isready | |
| 204 | +| vuex-v4 | new Store (...) => createStore (...) | |
| 205 | +| define-component | Vue.extend (...) => defineComponent (...) | |
| 206 | +| new-vue-to-create-app | https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp | |
| 207 | +| scoped-slots-to-slots | https://v3.vuejs.org/guide/migration/slots-unification.html#overview | |
| 208 | +| new-directive-api | https://v3.vuejs.org/guide/migration/custom-directives.html#overview | |
| 209 | +| remove-vue-set-and-delete | https://v3.vuejs.org/guide/migration/introduction.html#removed-apis | |
| 210 | +| rename-lifecycle | https://v3.vuejs.org/guide/migration/introduction.html#other-minor-changes | |
| 211 | +| add-emit-declaration | https://v3.vuejs.org/guide/migration/emits-option.html#overview | |
| 212 | +| tree-shaking | https://v3.vuejs.org/guide/migration/global-api-treeshaking.html | |
| 213 | +| v-model | https://v3.vuejs.org/guide/migration/v-model.html#overview | |
| 214 | +| render-to-resolveComponent | https://v3.vuejs.org/guide/migration/render-function-api.html#registered-component | |
| 215 | +| remove-contextual-h-from-render | https://v3.vuejs.org/guide/migration/render-function-api.html#render-function-argument | |
| 216 | +| remove-production-tip | https://v3.vuejs.org/guide/migration/global-api.html#a-new-global-api-createapp | |
| 217 | +| remove-trivial-root | createApp ({ render: () => h (App) }) => createApp (App) | |
| 218 | +| vue-as-namespace-import | import Vue from "vue" => import * as Vue from "vue" | |
| 219 | +| slot-attribute | https://vuejs.org/v2/guide/components-slots.html#Deprecated-Syntax | |
| 220 | +| slot-default | If component tag did not contain a `<slot>` element, any content provided between its opening and closing tag would be discarded. | |
| 221 | +| slot-scope-attribute | https://vuejs.org/v2/guide/components-slots.html#Scoped-Slots-with-the-slot-scope-Attribute | |
| 222 | +| v-for-template-key | https://v3.vuejs.org/guide/migration/key-attribute.html#overview | |
| 223 | +| v-else-if-key | https://v3.vuejs.org/guide/migration/key-attribute.html#overview | |
| 224 | +| transition-group-root | https://v3.vuejs.org/guide/migration/transition-group.html#overview | |
| 225 | +| v-bind-order-sensitive | https://v3.vuejs.org/guide/migration/v-bind.html#overview | |
| 226 | +| v-for-v-if-precedence-changed | https://v3.vuejs.org/guide/migration/v-if-v-for.html#overview | |
| 227 | +| remove-listeners | https://v3.vuejs.org/guide/migration/listeners-removed.html#overview | |
| 228 | +| v-bind-sync | https://v3.vuejs.org/guide/migration/v-model.html#overview | |
| 229 | +| remove-v-on-native | https://v3.vuejs.org/guide/migration/v-on-native-modifier-removed.html#overview | |
| 230 | +| router-link-event-tag | https://next.router.vuejs.org/guide/migration/index.html#removal-of-event-and-tag-props-in-router-link | |
| 231 | +| router-link-exact | https://next.router.vuejs.org/guide/migration/index.html#removal-of-the-exact-prop-in-router-link | |
| 232 | +| router-view-keep-alive-transition | https://next.router.vuejs.org/guide/migration/index.html#router-view-keep-alive-and-transition | |
0 commit comments