Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: relative declaration extension should match the extension of the code output #272

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 2 additions & 4 deletions src/loaders/js.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { transform } from "esbuild";
import jiti from "jiti";

import type { Loader, LoaderResult } from "../loader";
import { getOutputExtension } from "../utils";

const DECLARATION_RE = /\.d\.[cm]?ts$/;
const CM_LETTER_RE = /(?<=\.)(c|m)(?=[jt]s$)/;
Expand Down Expand Up @@ -55,10 +56,7 @@ export const jsLoader: Loader = async (input, { options }) => {
.replace("module.exports = void 0;", "");
}

let extension = isCjs ? ".js" : ".mjs"; // TODO: Default to .cjs in next major version
if (options.ext) {
extension = options.ext.startsWith(".") ? options.ext : `.${options.ext}`;
}
const extension = getOutputExtension(options);

output.push({
contents,
Expand Down
9 changes: 7 additions & 2 deletions src/utils/dts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { resolve } from "pathe";
import type { TSConfig } from "pkg-types";
import type { MkdistOptions } from "../make";
import { getOutputExtension } from "./index";
import type { CompilerHost, EmitResult } from "typescript";

export async function normalizeCompilerOptions(
Expand Down Expand Up @@ -70,7 +71,10 @@ export function extractDeclarations(
const dtsFilename = filename.replace(JSX_EXT_RE, ".d.$1ts");
let contents = vfs.get(dtsFilename) || "";
if (opts?.addRelativeDeclarationExtensions) {
const ext = filename.match(JS_EXT_RE)?.[0].replace(/ts$/, "js") || ".js";
const srcExt =
filename.match(JS_EXT_RE)?.[0].replace(/ts$/, "js") || ".js";
const ext = getOutputExtension(opts);

const imports = findStaticImports(contents);
const exports = findExports(contents);
const typeExports = findTypeExports(contents);
Expand Down Expand Up @@ -101,7 +105,8 @@ export function extractDeclarations(
continue;
}
const srcPath = resolve(filename, "..", spec.specifier);
const srcDtsPath = srcPath + ext.replace(JS_EXT_RE, ".d.$1ts");
const srcDtsPath = srcPath + srcExt.replace(JS_EXT_RE, ".d.$1ts");

let specifier = spec.specifier;
try {
if (!vfs.get(srcDtsPath)) {
Expand Down
10 changes: 10 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { MkdistOptions } from "../make";

export function getOutputExtension(options: MkdistOptions) {
const isCjs = options.format === "cjs";
let ext = isCjs ? ".js" : ".mjs"; // TODO: Default to .cjs in next major version
if (options.ext) {
ext = options.ext.startsWith(".") ? options.ext : `.${options.ext}`;
}
return ext;
}
187 changes: 166 additions & 21 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,151 @@
"manual declaration",
);

expect(await readFile(resolve(rootDir, "dist/star/index.d.ts"), "utf8"))
.toMatchInlineSnapshot(`
"export * from "./other.mjs";
export type { Other } from "./other.mjs";
export declare function wonder(twinkle: import("./other.mjs").Other): string;
"
`);

expect(await readFile(resolve(rootDir, "dist/dir-export.d.ts"), "utf8"))
.toMatchInlineSnapshot(`
"export { default as bar } from "./bar.mjs";
export * from "./star/index.mjs";
"
`);

expect(
await readFile(resolve(rootDir, "dist/bar/esm.d.mts"), "utf8"),
).toMatch("declare");

expect(
await readFile(resolve(rootDir, "dist/components/index.d.ts"), "utf8"),
).toMatchInlineSnapshot(`
"export * as jsx from "./jsx.jsx.mjs";
export * as tsx from "./tsx.tsx.mjs";
export * as blank from "./blank.vue.mjs";
export * as scriptSetupTS from "./script-setup-ts.vue.mjs";
export * as scriptMultiBlock from "./script-multi-block.vue.mjs";
export * as ts from "./ts.vue.mjs";
"
`);

expect(
await readFile(resolve(rootDir, "dist/components/ts.vue.d.ts"), "utf8"),
).toMatchInlineSnapshot(`
"declare const _default: import("vue").DefineComponent<{}, {}, {
test: string;
str: "test";
}, {}, {}, 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/blank.vue.d.ts"),
"utf8",
),
).toMatchInlineSnapshot(`

Check failure on line 206 in test/index.test.ts

View workflow job for this annotation

GitHub Actions / ci

test/index.test.ts > mkdist > mkdist (emit types)

Error: Snapshot `mkdist > mkdist (emit types) 5` mismatched - Expected + Received - "declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, HTMLDivElement>; + "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; " ❯ test/index.test.ts:206:7
"declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, HTMLDivElement>;
export default _default;
"
`);

expect(
await readFile(
resolve(rootDir, "dist/components/script-multi-block.vue.d.ts"),
"utf8",
),
).toMatchInlineSnapshot(`
"interface MyComponentProps {
msg: string;
}
declare const _default: import("vue").DefineComponent<MyComponentProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<MyComponentProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, HTMLDivElement>;
export default _default;
"
`);

expect(
await readFile(
resolve(rootDir, "dist/components/script-setup-ts.vue.d.ts"),
"utf8",
),
).toMatchInlineSnapshot(`
"import { Color } from "#prop-types";
type __VLS_Props = {
msg: string;
color: Color;
};
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, HTMLDivElement>;
export default _default;
"
`);
}, 50_000);

it("mkdist (emit types) [js]", async () => {
const rootDir = resolve(__dirname, "fixture");
const { writtenFiles } = await mkdist({
rootDir,
declaration: true,
addRelativeDeclarationExtensions: true,
ext: "js",
});
expect(writtenFiles.sort()).toEqual(
[
"dist/README.md",
"dist/bar.d.ts",
"dist/bar.js",
"dist/demo.css",
"dist/dir-export.d.ts",
"dist/dir-export.js",
"dist/foo.js",
"dist/foo.d.ts",
"dist/index.js",
"dist/index.d.ts",
"dist/star/index.js",
"dist/star/index.d.ts",
"dist/star/other.js",
"dist/star/other.d.ts",
"dist/types.d.ts",
"dist/components/index.js",
"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",
"dist/components/script-multi-block.vue.d.ts",
"dist/components/script-setup-ts.vue",
"dist/components/script-setup-ts.vue.d.ts",
"dist/components/ts.vue",
"dist/components/ts.vue.d.ts",
"dist/components/jsx.js",
"dist/components/tsx.js",
"dist/components/jsx.d.ts",
"dist/components/tsx.d.ts",
"dist/bar/index.js",
"dist/bar/index.d.ts",
"dist/bar/esm.js",
"dist/bar/esm.d.mts",
"dist/ts/test1.js",
"dist/ts/test2.js",
"dist/ts/test1.d.mts",
"dist/ts/test2.d.cts",
"dist/nested.css",
"dist/prop-types/index.js",
"dist/prop-types/index.d.ts",
]
.map((f) => resolve(rootDir, f))
.sort(),
);

expect(await readFile(resolve(rootDir, "dist/foo.d.ts"), "utf8")).toMatch(
"manual declaration",
);

expect(await readFile(resolve(rootDir, "dist/star/index.d.ts"), "utf8"))
.toMatchInlineSnapshot(`
"export * from "./other.js";
Expand Down Expand Up @@ -203,8 +348,8 @@
resolve(rootDir, "dist/components/blank.vue.d.ts"),
"utf8",
),
).toMatchInlineSnapshot(`

Check failure on line 351 in test/index.test.ts

View workflow job for this annotation

GitHub Actions / ci

test/index.test.ts > mkdist > mkdist (emit types) [js]

Error: Snapshot `mkdist > mkdist (emit types) [js] 5` mismatched - Expected + Received - "declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, HTMLDivElement>; + "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; " ❯ test/index.test.ts:351:7
"declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
"declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, HTMLDivElement>;
export default _default;
"
`);
Expand All @@ -218,7 +363,7 @@
"interface MyComponentProps {
msg: string;
}
declare const _default: import("vue").DefineComponent<MyComponentProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<MyComponentProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
declare const _default: import("vue").DefineComponent<MyComponentProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<MyComponentProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, HTMLDivElement>;
export default _default;
"
`);
Expand All @@ -234,7 +379,7 @@
msg: string;
color: Color;
};
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, HTMLDivElement>;
export default _default;
"
`);
Expand Down Expand Up @@ -594,9 +739,9 @@

expect(await readFile(resolve(rootDir, "dist/star/index.d.ts"), "utf8"))
.toMatchInlineSnapshot(`
"export * from "./other.js";
export type { Other } from "./other.js";
export declare function wonder(twinkle: import("./other.js").Other): string;
"export * from "./other.mjs";
export type { Other } from "./other.mjs";
export declare function wonder(twinkle: import("./other.mjs").Other): string;
"
`);
expect(
Expand All @@ -606,12 +751,12 @@
expect(
await readFile(resolve(rootDir, "dist/components/index.d.ts"), "utf8"),
).toMatchInlineSnapshot(`
"export * as jsx from "./jsx.jsx.js";
export * as tsx from "./tsx.tsx.js";
export * as blank from "./blank.vue.js";
export * as scriptSetupTS from "./script-setup-ts.vue.js";
export * as scriptMultiBlock from "./script-multi-block.vue.js";
export * as ts from "./ts.vue.js";
"export * as jsx from "./jsx.jsx.mjs";
export * as tsx from "./tsx.tsx.mjs";
export * as blank from "./blank.vue.mjs";
export * as scriptSetupTS from "./script-setup-ts.vue.mjs";
export * as scriptMultiBlock from "./script-multi-block.vue.mjs";
export * as ts from "./ts.vue.mjs";
"
`);

Expand Down Expand Up @@ -852,9 +997,9 @@

expect(await readFile(resolve(rootDir, "dist/star/index.d.ts"), "utf8"))
.toMatchInlineSnapshot(`
"export * from "./other.js";
export type { Other } from "./other.js";
export declare function wonder(twinkle: import("./other.js").Other): string;
"export * from "./other.mjs";
export type { Other } from "./other.mjs";
export declare function wonder(twinkle: import("./other.mjs").Other): string;
"
`);
expect(
Expand All @@ -864,12 +1009,12 @@
expect(
await readFile(resolve(rootDir, "dist/components/index.d.ts"), "utf8"),
).toMatchInlineSnapshot(`
"export * as jsx from "./jsx.jsx.js";
export * as tsx from "./tsx.tsx.js";
export * as blank from "./blank.vue.js";
export * as scriptSetupTS from "./script-setup-ts.vue.js";
export * as scriptMultiBlock from "./script-multi-block.vue.js";
export * as ts from "./ts.vue.js";
"export * as jsx from "./jsx.jsx.mjs";
export * as tsx from "./tsx.tsx.mjs";
export * as blank from "./blank.vue.mjs";
export * as scriptSetupTS from "./script-setup-ts.vue.mjs";
export * as scriptMultiBlock from "./script-multi-block.vue.mjs";
export * as ts from "./ts.vue.mjs";
"
`);

Expand Down
Loading