Skip to content

Commit

Permalink
chore(dts): generate dts for vue sfc with no script
Browse files Browse the repository at this point in the history
  • Loading branch information
Teages committed Oct 13, 2024
1 parent 2452db9 commit a0c1c7a
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
23 changes: 19 additions & 4 deletions src/loaders/vue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ export interface DefineVueLoaderOptions {
};
}

export type VueBlock = Pick<SFCBlock, "type" | "content" | "attrs">;

export interface VueBlockLoader {
(
block: Pick<SFCBlock, "type" | "content" | "attrs">,
block: VueBlock,
context: LoaderContext & {
rawInput: InputFile;
addOutput: (...files: OutputFile[]) => void;
},
): Promise<Pick<SFCBlock, "type" | "content" | "attrs"> | undefined>;
): Promise<VueBlock | undefined>;
}

export interface DefaultBlockLoaderOptions {
Expand All @@ -44,10 +46,10 @@ export function defineVueLoader(options?: DefineVueLoaderOptions): Loader {
}

let modified = false;
let fakeScriptBlock = false;

const raw = await input.getContents();
const sfc = parse(raw, { filename: input.path, ignoreEmpty: true });

if (sfc.errors.length > 0) {
for (const error of sfc.errors) {
console.error(error);
Expand All @@ -58,7 +60,7 @@ export function defineVueLoader(options?: DefineVueLoaderOptions): Loader {
const output: LoaderResult = [];
const addOutput = (...files: OutputFile[]) => output.push(...files);

const blocks = [
const blocks: VueBlock[] = [
sfc.descriptor.template,
...sfc.descriptor.styles,
...sfc.descriptor.customBlocks,
Expand All @@ -81,6 +83,14 @@ export function defineVueLoader(options?: DefineVueLoaderOptions): Loader {
].filter((item) => !!item);
blocks.unshift(...scriptBlocks);
}
} else {
// push a fake script block to generate dts
blocks.unshift({
type: "script",
content: "export default {}",
attrs: {},
});
fakeScriptBlock = true;
}

const results = await Promise.all(
Expand All @@ -104,6 +114,10 @@ export function defineVueLoader(options?: DefineVueLoaderOptions): Loader {

const contents = results
.map((block) => {
if (block.type === "script" && fakeScriptBlock) {
return undefined;
}

const attrs = Object.entries(block.attrs)
.map(([key, value]) => {
if (!value) {
Expand All @@ -120,6 +134,7 @@ export function defineVueLoader(options?: DefineVueLoaderOptions): Loader {

return `${header}\n${cleanupBreakLine(block.content)}\n${footer}\n`;
})
.filter((item) => !!item)
.join("\n");
addOutput({
path: input.path,
Expand Down
36 changes: 36 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ describe("mkdist", () => {
"dist/components/index.mjs",
"dist/components/index.d.ts",
"dist/components/blank.vue",
"dist/components/blank.vue.d.ts",
"dist/components/js.vue",
"dist/components/js.vue.d.ts",
"dist/components/script-multi-block.vue",
Expand Down Expand Up @@ -193,6 +194,17 @@ describe("mkdist", () => {
"
`);

expect(
await readFile(
resolve(rootDir, "dist/components/blank.vue.d.ts"),
"utf8",
),
).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 readFile(
resolve(rootDir, "dist/components/script-multi-block.vue.d.ts"),
Expand Down Expand Up @@ -537,6 +549,7 @@ describe("mkdist with vue-tsc v1", () => {
"dist/components/index.mjs",
"dist/components/index.d.ts",
"dist/components/blank.vue",
"dist/components/blank.vue.d.ts",
"dist/components/js.vue",
"dist/components/js.vue.d.ts",
"dist/components/script-multi-block.vue",
Expand Down Expand Up @@ -589,6 +602,17 @@ describe("mkdist with vue-tsc v1", () => {
"
`);

expect(
await readFile(
resolve(rootDir, "dist/components/blank.vue.d.ts"),
"utf8",
),
).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 readFile(resolve(rootDir, "dist/components/ts.vue.d.ts"), "utf8"),
).toMatchInlineSnapshot(`
Expand Down Expand Up @@ -717,6 +741,7 @@ describe("mkdist with vue-tsc ~v2.0.21", () => {
"dist/components/index.mjs",
"dist/components/index.d.ts",
"dist/components/blank.vue",
"dist/components/blank.vue.d.ts",
"dist/components/js.vue",
"dist/components/js.vue.d.ts",
"dist/components/script-multi-block.vue",
Expand Down Expand Up @@ -769,6 +794,17 @@ describe("mkdist with vue-tsc ~v2.0.21", () => {
"
`);

expect(
await readFile(
resolve(rootDir, "dist/components/blank.vue.d.ts"),
"utf8",
),
).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 readFile(resolve(rootDir, "dist/components/ts.vue.d.ts"), "utf8"),
).toMatchInlineSnapshot(`
Expand Down

0 comments on commit a0c1c7a

Please sign in to comment.