diff --git a/packages/@vue/cli-plugin-babel/package.json b/packages/@vue/cli-plugin-babel/package.json index 927bc7f860..2575b8cd56 100644 --- a/packages/@vue/cli-plugin-babel/package.json +++ b/packages/@vue/cli-plugin-babel/package.json @@ -32,7 +32,7 @@ "@vue/cli-service": "^3.0.0 || ^4.0.0-0" }, "devDependencies": { - "jscodeshift": "^0.9.0" + "jscodeshift": "^0.10.0" }, "publishConfig": { "access": "public" diff --git a/packages/@vue/cli-plugin-typescript/codemods/__testfixtures__/shims-vue.input.ts b/packages/@vue/cli-plugin-typescript/codemods/__testfixtures__/shims-vue.input.ts new file mode 100644 index 0000000000..798e8fcfac --- /dev/null +++ b/packages/@vue/cli-plugin-typescript/codemods/__testfixtures__/shims-vue.input.ts @@ -0,0 +1,5 @@ +declare module '*.vue' { + import { defineComponent } from 'vue'; + const component: ReturnType; + export default component; +} diff --git a/packages/@vue/cli-plugin-typescript/codemods/__testfixtures__/shims-vue.output.ts b/packages/@vue/cli-plugin-typescript/codemods/__testfixtures__/shims-vue.output.ts new file mode 100644 index 0000000000..40f3f4bdf7 --- /dev/null +++ b/packages/@vue/cli-plugin-typescript/codemods/__testfixtures__/shims-vue.output.ts @@ -0,0 +1,5 @@ +declare module '*.vue' { + import { DefineComponent } from 'vue'; + const component: DefineComponent; + export default component; +} diff --git a/packages/@vue/cli-plugin-typescript/codemods/__tests__/migrateComponentType.spec.js b/packages/@vue/cli-plugin-typescript/codemods/__tests__/migrateComponentType.spec.js new file mode 100644 index 0000000000..ebf0a9297b --- /dev/null +++ b/packages/@vue/cli-plugin-typescript/codemods/__tests__/migrateComponentType.spec.js @@ -0,0 +1,5 @@ +jest.autoMockOff() + +const { defineTest } = require('jscodeshift/dist/testUtils') + +defineTest(__dirname, 'migrateComponentType', null, 'shims-vue', { parser: 'ts' }) diff --git a/packages/@vue/cli-plugin-typescript/codemods/migrateComponentType.js b/packages/@vue/cli-plugin-typescript/codemods/migrateComponentType.js new file mode 100644 index 0000000000..7f892b2de1 --- /dev/null +++ b/packages/@vue/cli-plugin-typescript/codemods/migrateComponentType.js @@ -0,0 +1,93 @@ +// `shims-vue.d.ts` for Vue 3, generated by CLI 4.5.0-4.5.6, uses the following declaration: +// `component: ReturnType` + +// So needs to update to: +// `component: DefineComponent` + +module.exports = function migrateComponentType (file, api) { + const j = api.jscodeshift + const root = j(file.source) + + const useDoubleQuote = root.find(j.StringLiteral).some(({ node }) => node.extra.raw.startsWith('"')) + + const tsmodule = root.find(j.TSModuleDeclaration, { + id: { + value: '*.vue' + } + }) + + const componentDecl = tsmodule.find(j.VariableDeclarator, { + id: { + name: 'component', + typeAnnotation: { + typeAnnotation: { + typeName: { + name: 'ReturnType' + }, + typeParameters: { + params: { + 0: { + exprName: { + name: 'defineComponent' + } + } + } + } + } + } + } + }) + + if (componentDecl.length !== 1) { + return file.source + } + + // update the component type + componentDecl.forEach(({ node }) => { + node.id.typeAnnotation = j.tsTypeAnnotation( + j.tsTypeReference(j.identifier('DefineComponent')) + ) + }) + + // insert DefineComponent type import + const importDeclFromVue = tsmodule.find(j.ImportDeclaration, { + source: { + value: 'vue' + } + }) + importDeclFromVue + .get(0) + .node.specifiers.push(j.importSpecifier(j.identifier('DefineComponent'))) + + // remove defineComponent import if unused + const defineComponentUsages = tsmodule + .find(j.Identifier, { name: 'defineComponent' }) + .filter((identifierPath) => { + const parent = identifierPath.parent.node + + // Ignore the import specifier + if ( + j.ImportDefaultSpecifier.check(parent) || + j.ImportSpecifier.check(parent) || + j.ImportNamespaceSpecifier.check(parent) + ) { + return false + } + }) + if (defineComponentUsages.length === 0) { + tsmodule + .find(j.ImportSpecifier, { + local: { + name: 'defineComponent' + } + }) + .remove() + } + + return root.toSource({ + lineTerminator: '\n', + quote: useDoubleQuote ? 'double' : 'single' + }) +} + +module.exports.parser = 'ts' diff --git a/packages/@vue/cli-plugin-typescript/generator/template-vue3/src/shims-vue.d.ts b/packages/@vue/cli-plugin-typescript/generator/template-vue3/src/shims-vue.d.ts index 32a1b5cd40..a99cf76cc7 100644 --- a/packages/@vue/cli-plugin-typescript/generator/template-vue3/src/shims-vue.d.ts +++ b/packages/@vue/cli-plugin-typescript/generator/template-vue3/src/shims-vue.d.ts @@ -1,5 +1,5 @@ declare module '*.vue' { - import { defineComponent } from 'vue' - const component: ReturnType + import type { DefineComponent } from 'vue' + const component: DefineComponent export default component } diff --git a/packages/@vue/cli-plugin-typescript/migrator/index.js b/packages/@vue/cli-plugin-typescript/migrator/index.js index a28ea4d578..bfe935eabd 100644 --- a/packages/@vue/cli-plugin-typescript/migrator/index.js +++ b/packages/@vue/cli-plugin-typescript/migrator/index.js @@ -1,4 +1,4 @@ -module.exports = api => { +module.exports = (api, options, rootOptions) => { api.extendPackage( { devDependencies: { @@ -7,4 +7,9 @@ module.exports = api => { }, { warnIncompatibleVersions: false } ) + + // update vue 3 typescript shim + if (rootOptions.vueVersion === 3) { + api.transformScript('src/shims-vue.d.ts', require('../codemods/migrateComponentType')) + } } diff --git a/packages/@vue/cli-plugin-typescript/package.json b/packages/@vue/cli-plugin-typescript/package.json index 4552efec77..07ebe6808a 100644 --- a/packages/@vue/cli-plugin-typescript/package.json +++ b/packages/@vue/cli-plugin-typescript/package.json @@ -51,6 +51,7 @@ "@types/chai": "^4.2.11", "@types/jest": "^24.0.19", "@types/mocha": "^5.2.6", + "jscodeshift": "^0.10.0", "typescript": "~3.9.3", "vue-class-component": "^7.2.3", "vue-property-decorator": "^8.4.2" diff --git a/packages/@vue/cli-service/__tests__/generator.spec.js b/packages/@vue/cli-service/__tests__/generator.spec.js index 75b4073b4f..3565cba1c1 100644 --- a/packages/@vue/cli-service/__tests__/generator.spec.js +++ b/packages/@vue/cli-service/__tests__/generator.spec.js @@ -42,7 +42,7 @@ test('Vue 3', async () => { vueVersion: '3' }) - expect(pkg.dependencies.vue).toBe('^3.0.0-0') + expect(pkg.dependencies.vue).toBe('^3.0.0') expect(pkg).toHaveProperty(['devDependencies', '@vue/compiler-sfc']) expect(files['src/main.js']).toMatch(`import { createApp } from 'vue'`) diff --git a/packages/@vue/cli-service/generator/index.js b/packages/@vue/cli-service/generator/index.js index 2b56d228d7..d96a829928 100644 --- a/packages/@vue/cli-service/generator/index.js +++ b/packages/@vue/cli-service/generator/index.js @@ -6,10 +6,10 @@ module.exports = (api, options) => { if (options.vueVersion === '3') { api.extendPackage({ dependencies: { - 'vue': '^3.0.0-0' + 'vue': '^3.0.0' }, devDependencies: { - '@vue/compiler-sfc': '^3.0.0-0' + '@vue/compiler-sfc': '^3.0.0' } }) } else { diff --git a/yarn.lock b/yarn.lock index fbe4c9e0a8..72b1ee78ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12518,31 +12518,6 @@ jscodeshift@^0.10.0: temp "^0.8.1" write-file-atomic "^2.3.0" -jscodeshift@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.9.0.tgz#672025658e868a63e24d6a6f4c44af9edb6e55f3" - integrity sha512-SUeXq8dJzj5LR8uy71axgG3bmiHoC0IdHy7n89SqKzkzBWpAds5F9IIGE+lqUSZX9J0ZfEzN8fXWIqQV0dIp2w== - dependencies: - "@babel/core" "^7.1.6" - "@babel/parser" "^7.1.6" - "@babel/plugin-proposal-class-properties" "^7.1.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.1.0" - "@babel/plugin-proposal-optional-chaining" "^7.1.0" - "@babel/plugin-transform-modules-commonjs" "^7.1.0" - "@babel/preset-flow" "^7.0.0" - "@babel/preset-typescript" "^7.1.0" - "@babel/register" "^7.0.0" - babel-core "^7.0.0-bridge.0" - colors "^1.1.2" - flow-parser "0.*" - graceful-fs "^4.1.11" - micromatch "^3.1.10" - neo-async "^2.5.0" - node-dir "^0.1.17" - recast "^0.18.1" - temp "^0.8.1" - write-file-atomic "^2.3.0" - jsdom-global@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/jsdom-global/-/jsdom-global-3.0.2.tgz#6bd299c13b0c4626b2da2c0393cd4385d606acb9"