vite-plugin-uni-pages2dts
Version:
A Vite plugin to generate TypeScript types for UniApp pages.
147 lines (136 loc) • 4.43 kB
JavaScript
// src/context.ts
import path from "node:path";
import { loadConfig } from "unconfig";
// src/constant.ts
var OUTPUT_NAME = "pages.json";
// src/declaration.ts
import { existsSync } from "node:fs";
import { mkdir, readFile, writeFile as writeFile_ } from "node:fs/promises";
import { dirname } from "node:path";
async function writeDeclaration(ctx, filepath) {
const originalContent = existsSync(filepath) ? await readFile(filepath, "utf-8") : "";
const code = getDeclaration(ctx);
if (!code)
return;
if (code !== originalContent) {
await writeFile(filepath, code);
}
}
function getDeclaration(ctx) {
const subPagesPath = [];
const tabsPagesPath = ctx.pagesGlobConfig?.tabBar?.list?.map((v) => `"/${v.pagePath}"`) ?? [];
const allPagesPath = [...ctx.pageMetaData.filter((page) => !tabsPagesPath.includes(page.path)).map((v) => `"/${v.path}"`), ...subPagesPath];
const code = `/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by vite-plugin-uni-pages
interface NavigateToOptions {
url: ${allPagesPath.join(" |\n ")};
}
interface RedirectToOptions extends NavigateToOptions {}
interface SwitchTabOptions {
${tabsPagesPath.length ? `url: ${tabsPagesPath.join(" | ")}` : ""}
}
type ReLaunchOptions = NavigateToOptions | SwitchTabOptions;
declare interface Uni {
navigateTo(options: UniNamespace.NavigateToOptions & NavigateToOptions): void;
redirectTo(options: UniNamespace.RedirectToOptions & RedirectToOptions): void;
switchTab(options: UniNamespace.SwitchTabOptions & SwitchTabOptions): void;
reLaunch(options: UniNamespace.ReLaunchOptions & ReLaunchOptions): void;
}
`;
return code;
}
async function writeFile(filePath, content) {
await mkdir(dirname(filePath), { recursive: true });
return await writeFile_(filePath, content, "utf-8");
}
// src/options.ts
import { resolve } from "node:path";
function resolveOptions(userOptions, viteRoot) {
const { outDir = "src", configSource = "src/pages", dts = true } = userOptions;
const resolvedConfigSource = [{ files: configSource }];
const resolvedDts = !dts ? false : typeof dts === "string" ? dts : resolve(viteRoot, "uni-pages.d.ts");
const resolvedOptions = {
dts: resolvedDts,
outDir,
configSource: resolvedConfigSource,
root: viteRoot
};
return resolvedOptions;
}
// src/utils.ts
import fs from "node:fs";
function checkPagesJsonFile(path2) {
if (!fs.existsSync(path2)) {
writeFileSync(path2, JSON.stringify({ pages: [{ path: "" }] }, null, 2));
return false;
}
return true;
}
function writeFileSync(path2, content) {
fs.writeFileSync(path2, content, { encoding: "utf-8" });
}
// src/context.ts
var PageContext = class {
pagesGlobConfig;
pagesConfigSourcePaths = [];
pagesPath = [];
subPagesPath = {};
pageMetaData = [];
subPageMetaData = [];
resolvedPagesJSONPath = "";
resolvedPagesJSONIndent = " ";
resolvedPagesJSONNewline = "\n";
resolvedPagesJSONEofNewline = true;
rawOptions;
root;
options;
withUniPlatform = false;
constructor(userOptions, viteRoot) {
this.rawOptions = userOptions;
this.root = viteRoot;
this.options = resolveOptions(userOptions, this.root);
this.resolvedPagesJSONPath = path.join(this.root, this.options.outDir, OUTPUT_NAME);
}
async loadUserPagesConfig() {
const configSource = this.options.configSource;
const { config, sources } = await loadConfig({ cwd: this.root, sources: configSource, defaults: {} });
this.pagesGlobConfig = config;
this.pageMetaData = config.pages || [];
this.pagesConfigSourcePaths = sources;
}
async updatePagesJSON(filepath) {
if (filepath) {
}
if (!checkPagesJsonFile(this.resolvedPagesJSONPath)) {
console.error("pages.json file is not found");
throw new Error("pages.json file is not found");
}
await this.loadUserPagesConfig();
this.generateDeclaration();
}
generateDeclaration() {
if (!this.options.dts)
return;
return writeDeclaration(this, this.options.dts);
}
};
// src/index.ts
function vitePluginTemplate(userOptions = {}) {
let ctx;
return {
name: "vite-plugin-uni-pages2dts",
enforce: "pre",
// post
apply: "serve",
// apply 亦可以是一个函数
async configResolved(config) {
ctx = new PageContext(userOptions, config.root);
await ctx.updatePagesJSON();
}
};
}
export {
vitePluginTemplate as default
};