diff --git a/README.md b/README.md index 2f067bde..4d5083fd 100644 --- a/README.md +++ b/README.md @@ -357,6 +357,10 @@ Components({ // filters for transforming targets include: [/\.vue$/, /\.vue\?vue/], exclude: [/[\\/]node_modules[\\/]/, /[\\/]\.git[\\/]/, /[\\/]\.nuxt[\\/]/], + + // Vue version of project. It will detect automatically if not specified. + // Acceptable value: 2 | 2.7 | 3 + version: 2.7 }) ``` diff --git a/src/core/declaration.ts b/src/core/declaration.ts index 809a2939..bf44ab1b 100644 --- a/src/core/declaration.ts +++ b/src/core/declaration.ts @@ -114,15 +114,21 @@ export function getDeclaration(ctx: Context, filepath: string, originalImports?: directive: stringifyDeclarationImports({ ...originalImports?.directive, ...imports.directive }), } - let code = `// generated by unplugin-vue-components -// We suggest you to commit this file into source control -// Read more: https://github.com/vuejs/core/pull/3399 -import '@vue/runtime-core' + const head = ctx.options.version === 2.7 + ? `export {} + +declare module 'vue' {` + : `import '@vue/runtime-core' export {} declare module '@vue/runtime-core' {` + let code = `// generated by unplugin-vue-components +// We suggest you to commit this file into source control +// Read more: https://github.com/vuejs/core/pull/3399 +${head}` + if (Object.keys(declarations.component).length > 0) { code += ` export interface GlobalComponents { diff --git a/src/core/options.ts b/src/core/options.ts index 5eb5babd..bce8e5de 100644 --- a/src/core/options.ts +++ b/src/core/options.ts @@ -4,7 +4,7 @@ import { getPackageInfoSync, isPackageExists } from 'local-pkg' import type { ComponentResolver, ComponentResolverObject, Options, ResolvedOptions } from '../types' import { detectTypeImports } from './type-imports/detect' -export const defaultOptions: Omit, 'include' | 'exclude' | 'transformer' | 'globs' | 'directives' | 'types'> = { +export const defaultOptions: Omit, 'include' | 'exclude' | 'transformer' | 'globs' | 'directives' | 'types' | 'version'> = { dirs: 'src/components', extensions: 'vue', deep: true, @@ -65,16 +65,25 @@ export function resolveOptions(options: Options, root: string): ResolvedOptions resolved.types = resolved.types || [] resolved.root = root - resolved.transformer = options.transformer || getVueVersion(root) || 'vue3' + resolved.version = resolved.version ?? getVueVersion(root) + if (resolved.version < 2 || resolved.version >= 4) + throw new Error(`[unplugin-vue-components] unsupported version: ${resolved.version}`) + + resolved.transformer = options.transformer || `vue${Math.trunc(resolved.version) as 2 | 3}` resolved.directives = (typeof options.directives === 'boolean') ? options.directives : !resolved.resolvers.some(i => i.type === 'directive') ? false - : getVueVersion(root) === 'vue3' + : resolved.version >= 3 return resolved } -function getVueVersion(root: string) { - const version = getPackageInfoSync('vue', { paths: [root] })?.version || '3' - return version.startsWith('2.') ? 'vue2' : 'vue3' +function getVueVersion(root: string): 2 | 2.7 | 3 { + const raw = getPackageInfoSync('vue', { paths: [root] })?.version || '3' + const version = +(raw.split('.').slice(0, 2).join('.')) + if (version === 2.7) + return 2.7 + else if (version < 2.7) + return 2 + return 3 } diff --git a/src/types.ts b/src/types.ts index 476688a0..f8d52c0e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -171,6 +171,11 @@ export interface Options { * Only provide types of components in library (registered globally) **/ types?: TypeImport[] + + /** + * Vue version of project. It will detect automatically if not specified. + */ + version?: 2 | 2.7 | 3 } export type ResolvedOptions = Omit< diff --git a/test/__snapshots__/dts.test.ts.snap b/test/__snapshots__/dts.test.ts.snap index 2b8a00a5..4c9c13d9 100644 --- a/test/__snapshots__/dts.test.ts.snap +++ b/test/__snapshots__/dts.test.ts.snap @@ -18,6 +18,22 @@ declare module '@vue/runtime-core' { " `; +exports[`dts > components only vue2.7 1`] = ` +"// generated by unplugin-vue-components +// We suggest you to commit this file into source control +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +declare module 'vue' { + export interface GlobalComponents { + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + TestComp: typeof import('test/component/TestComp')['default'] + } +} +" +`; + exports[`dts > directive only 1`] = ` "// generated by unplugin-vue-components // We suggest you to commit this file into source control @@ -92,6 +108,22 @@ exports[`dts > parseDeclaration 1`] = ` } `; +exports[`dts > vue 2.7 components only 1`] = ` +"// generated by unplugin-vue-components +// We suggest you to commit this file into source control +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +declare module 'vue' { + export interface GlobalComponents { + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + TestComp: typeof import('test/component/TestComp')['default'] + } +} +" +`; + exports[`dts > writeDeclaration - keep unused 1`] = ` "// generated by unplugin-vue-components // We suggest you to commit this file into source control diff --git a/test/dts.test.ts b/test/dts.test.ts index 7a47515a..6e13b616 100644 --- a/test/dts.test.ts +++ b/test/dts.test.ts @@ -95,6 +95,19 @@ const _directive_loading = _resolveDirective("loading")` expect(declarations).toMatchSnapshot() }) + test('vue 2.7 components only', async () => { + const ctx = new Context({ + resolvers: resolver, + directives: true, + version: 2.7, + }) + const code = 'const _component_test_comp = _c("test-comp")' + await ctx.transform(code, '') + + const declarations = getDeclaration(ctx, 'test.d.ts') + expect(declarations).toMatchSnapshot() + }) + test('directive only', async () => { const ctx = new Context({ resolvers: resolver,