diff --git a/src/plugins/mkdist.ts b/src/plugins/mkdist.ts index 33dbe66..c80b70c 100644 --- a/src/plugins/mkdist.ts +++ b/src/plugins/mkdist.ts @@ -1,6 +1,8 @@ import type { LoaderFile } from '../block-loader/types' import type { VueSFCTransformerFileLoader } from '../sfc-transformer' import type { Loader } from '../types/mkdist' +import { readFileSync } from 'node:fs' +import { createRequire } from 'node:module' import { resolve } from 'node:path' import { scriptLoader } from '../block-loader/script' import { styleLoader } from '../block-loader/style' @@ -19,6 +21,27 @@ function importEsbuild(): Promise | typeof import('esb })() } +let _isMkdistSupportDualVueDts: boolean | undefined +function isMkdistSupportDualVueDts(): boolean { + if (typeof _isMkdistSupportDualVueDts === 'boolean') { + return _isMkdistSupportDualVueDts + } + try { + const require = createRequire(import.meta.url) + const mkdistPath = require.resolve('mkdist') + const packageJson = readFileSync(resolve(mkdistPath, '..', '..', 'package.json'), 'utf-8') + const { version = '0.0.0' } = JSON.parse(packageJson) as { version: string } + const [major = 0, minor = 0, patch = 0] = version.split('.').map(n => Number.parseInt(n)) + const normalizedVersion = major * 1_000_000 + minor * 1_000 + patch + + return !Number.isNaN(normalizedVersion) && normalizedVersion > 2_003_000 + } + catch (error) { + console.error(`Error checking mkdist version: ${error}`) + return false + } +} + const vueSFCTransformer = defineVueSFCTransformer({ blockLoaders: { template: templateLoader, @@ -77,6 +100,15 @@ export const vueLoader: Loader = async (input, mkdistContext) => { extension: '.js', getContents: () => 'export default {}', }))?.filter(f => f.declaration) || [] + if (dts.length && isMkdistSupportDualVueDts()) { + dts.push({ + contents: await input.getContents(), + path: input.path, + srcPath: input.srcPath, + extension: '.d.vue.ts', + declaration: true, + }) + } return [ { diff --git a/test/mkdist.test.ts b/test/mkdist.test.ts index ceff026..d5f26a3 100644 --- a/test/mkdist.test.ts +++ b/test/mkdist.test.ts @@ -234,6 +234,15 @@ describe('transform typescript script setup', () => { const msg = 1 ` + expect(await legacyDeclaration(src)).toMatchInlineSnapshot(` + "declare const _default: import("vue").DefineComponent<{ + msg: string; + }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{ + msg: string; + }> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>; + export default _default; + " + `) expect(await declaration(src)).toMatchInlineSnapshot(` "declare const _default: import("vue").DefineComponent<{ msg: string; @@ -245,6 +254,11 @@ describe('transform typescript script setup', () => { `) expect(await fixture(``)).toMatchInlineSnapshot(`""`) + expect(await legacyDeclaration(``)).toMatchInlineSnapshot(` + "declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>; + export default _default; + " + `) expect(await declaration(``)).toMatchInlineSnapshot(` "declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>; export default _default; @@ -424,11 +438,18 @@ describe('transform typescript script setup', () => { return await readFile(join(tmpDir, 'dist/index.vue'), 'utf-8') } - async function declaration(src: string): Promise { + async function legacyDeclaration(src: string): Promise { await rm(tmpDir, { force: true, recursive: true }) await mkdir(join(tmpDir, 'src'), { recursive: true }) await writeFile(join(tmpDir, 'src/index.vue'), src) await mkdist({ declaration: true, loaders: ['js', vueLoader], rootDir: tmpDir }) return await readFile(join(tmpDir, 'dist/index.vue.d.ts'), 'utf-8').catch(() => undefined) } + async function declaration(src: string): Promise { + await rm(tmpDir, { force: true, recursive: true }) + await mkdir(join(tmpDir, 'src'), { recursive: true }) + await writeFile(join(tmpDir, 'src/index.vue'), src) + await mkdist({ declaration: true, loaders: ['js', vueLoader], rootDir: tmpDir }) + return await readFile(join(tmpDir, 'dist/index.d.vue.ts'), 'utf-8').catch(() => undefined) + } })