Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/@vue/cli-plugin-babel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare module '*.vue' {
import { defineComponent } from 'vue';
const component: ReturnType<typeof defineComponent>;
export default component;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare module '*.vue' {
import { DefineComponent } from 'vue';
const component: DefineComponent;
export default component;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
jest.autoMockOff()

const { defineTest } = require('jscodeshift/dist/testUtils')

defineTest(__dirname, 'migrateComponentType', null, 'shims-vue', { parser: 'ts' })
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// `shims-vue.d.ts` for Vue 3, generated by CLI 4.5.0-4.5.6, uses the following declaration:
// `component: ReturnType<typeof defineComponent>`

// So needs to update to:
// `component: DefineComponent`

module.exports = function migrateComponentType (file, api) {
const j = api.jscodeshift
const root = j(file.source)

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()
}

module.exports.parser = 'ts'
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
declare module '*.vue' {
import { defineComponent } from 'vue'
const component: ReturnType<typeof defineComponent>
import type { DefineComponent } from 'vue'
const component: DefineComponent
Comment on lines +2 to +3
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pikax @cexbrayat
Just to make sure I get it right.
Is this the recommended way to shim .vue files now in Vue 3 stable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you have something weird with import type, but otherwise yes this is what I've been using:

declare module '*.vue' {
  import { DefineComponent } from 'vue';
  const component: DefineComponent;
  export default component;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "something weird with import type" mean?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry if I wasn't clear: I don't think import type is necessary here, as DefineComponent is just a type, so there is no tree-shaking issue. I'm fine if you prefer to keep it, I was just pointing out that the syntax is a bit more advanced, and might lose some developers not familiar with the latest TS features

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Now that it's only a style issue then I'll keep it. Because now Vue CLI scaffolds with TS 3.9+, which supports this syntax. And the import type syntax is quite self-explaining so that people won't mistakenly take DefineComponent as a value, making the code a little clearer.

export default component
}
7 changes: 6 additions & 1 deletion packages/@vue/cli-plugin-typescript/migrator/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = api => {
module.exports = (api, options, rootOptions) => {
api.extendPackage(
{
devDependencies: {
Expand All @@ -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'))
}
}
1 change: 1 addition & 0 deletions packages/@vue/cli-plugin-typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions packages/@vue/cli-service/generator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
25 changes: 0 additions & 25 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down