@tys/vite-plugin-vue-page-route
Version:
A vite plugin for vue, auto generate route info by page
794 lines (776 loc) • 27.5 kB
JavaScript
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw new Error('Dynamic require of "' + x + '" is not supported');
});
// src/context/index.ts
import chokidar from "chokidar";
// src/shared/constant.ts
var PAGE_DIR = "src/views";
var PAGE_GLOB = ["**/index.{vue,tsx,jsx}", "!**/components/**"];
var ROUTE_DTS = "src/typings/page-route.d.ts";
var ROUTE_MODULE_DIR = "src/router/modules";
var ROUTE_MODULE_EXT = "ts";
var ROUTE_MODULE_TYPE = "AuthRoute.Route";
var ROOT_ROUTE = "root";
var NOT_FOUND_ROUTE = "not-found";
var PAGE_DEGREE_SPLIT_MARK = "_";
var SPLASH_MARK = "/";
var ROUTE_NAME_REG = /^([a-zA-Z]|\$|_|\d|-)+$/;
var INVALID_ROUTE_NAME = "invalid-route-name";
var CAMEL_OR_PASCAL = /[A-Z]/;
// src/shared/option.ts
function createPluginOptions(userOptions, rootDir) {
const IGNORE_UNDERLINE_REG = /^_([a-zA-Z]|[0-9]|$)+_*/;
const BUILTIN_ROUTE_MODULE = "_builtin";
const options = {
pageDir: PAGE_DIR,
pageGlobs: PAGE_GLOB,
routeDts: ROUTE_DTS,
routeModuleDir: ROUTE_MODULE_DIR,
routeModuleExt: ROUTE_MODULE_EXT,
routeModuleType: ROUTE_MODULE_TYPE,
routeNameTansformer: (name) => name.replace(IGNORE_UNDERLINE_REG, ""),
lazyImport: () => true,
onRouteModuleGenerate: (name) => !name.includes(BUILTIN_ROUTE_MODULE),
rootDir
};
Object.assign(options, userOptions);
return options;
}
// src/shared/glob.ts
import fastGlob from "fast-glob";
import { isMatch } from "micromatch";
function getGlobsOfPage(pageGlobs, pageDir) {
const globs = fastGlob.sync(pageGlobs, {
onlyFiles: true,
cwd: pageDir
});
return globs.sort();
}
function getRelativePathOfGlob(glob, pageDir) {
return `${pageDir}/${glob}`;
}
function matchGlob(glob, options) {
const isFile = isMatch(glob, "**/*.*");
const { pageGlobs } = options;
const patterns = isFile ? pageGlobs : pageGlobs.filter((pattern) => !pattern.includes("."));
return patterns.every((pattern) => isMatch(glob, pattern));
}
// src/shared/route.ts
import { writeFile, remove } from "fs-extra";
import { access } from "fs/promises";
import { red, bgRed, green, bgYellow, yellow } from "kolorist";
import { transformFile } from "@swc/core";
function transformRouteName(glob, routeName, pageDir) {
let name = routeName;
const filePath = getRelativePathOfGlob(glob, pageDir);
if (CAMEL_OR_PASCAL.test(routeName)) {
let warning = `${bgYellow("RECOMMEND")} `;
warning += yellow(`the filePath: ${filePath}`);
warning += green(`
it's recommended to use kebab-case name style`);
warning += green(`
example: good: user-info bad: userInfo, UserInfo`);
console.info(warning);
}
if (!ROUTE_NAME_REG.test(name)) {
name = INVALID_ROUTE_NAME;
let error = `${bgRed("ERROR")} `;
error += red(`the path is invalid: ${filePath} !
`);
error += red(`routeName: ${routeName} !`);
error += green(
`
the directory name and file name can only include letter[a-zA-Z], number[0-9], underline[_] and dollar[$]`
);
console.error(error);
}
return name;
}
function getRouteNameByGlob(glob, pageDir) {
const globSplits = glob.split(SPLASH_MARK);
const isFile = glob.includes(".");
const sliceLength = isFile ? globSplits.length - 1 : globSplits.length;
const routeName = globSplits.splice(0, sliceLength).join(PAGE_DEGREE_SPLIT_MARK);
return transformRouteName(glob, routeName, pageDir);
}
function getAllRouteNames(routeName) {
const names = routeName.split(PAGE_DEGREE_SPLIT_MARK);
const namesWithParent = [];
for (let i = 1; i <= names.length; i += 1) {
const parentName = names.slice(0, i).reduce((pre, cur) => pre + PAGE_DEGREE_SPLIT_MARK + cur);
namesWithParent.push(parentName);
}
return namesWithParent;
}
function getRouteFilePathByGlob(glob) {
return `./${glob}`;
}
function getRouteNameByGlobWithTransformer(glob, options) {
const routeName = getRouteNameByGlob(glob, options.pageDir);
return options.routeNameTansformer(routeName);
}
function getRouteConfigByGlobs(globs, options) {
const config = {
names: [],
files: []
};
globs.sort().forEach((glob) => {
const routeName = getRouteNameByGlob(glob, options.pageDir);
const names = getAllRouteNames(routeName);
config.names.push(...names);
const filePath = getRouteFilePathByGlob(glob);
config.files.push({ name: routeName, path: filePath });
});
config.names = Array.from(/* @__PURE__ */ new Set([...config.names])).map((name) => options.routeNameTansformer(name)).filter((name) => Boolean(name) && name !== INVALID_ROUTE_NAME);
config.files = config.files.map(({ name, path }) => ({ name: options.routeNameTansformer(name), path })).filter((item) => item.name !== INVALID_ROUTE_NAME);
return config;
}
function getRouteModuleConfig(index, length) {
const actions = [
[length === 1, { component: "self", hasSingleLayout: true }],
[length === 2 && index === 0, { component: "basic", hasSingleLayout: false }],
[length === 2 && index === 1, { component: "self", hasSingleLayout: false }],
[length >= 3 && index === 0, { component: "basic", hasSingleLayout: false }],
[length >= 3 && index === length - 1, { component: "self", hasSingleLayout: false }],
[true, { component: "multi", hasSingleLayout: false }]
];
const config = {
component: "self",
hasSingleLayout: false
};
const findItem = actions.find(([condition]) => condition);
return findItem?.[1] || config;
}
function getRoutePathFromName(routeName) {
const PATH_SPLIT_MARK = "/";
return PATH_SPLIT_MARK + routeName.replace(new RegExp(`${PAGE_DEGREE_SPLIT_MARK}`, "g"), PATH_SPLIT_MARK);
}
function getRouteModuleNameByRouteName(routeName) {
const routeNames = getAllRouteNames(routeName);
if (!routeNames.length) {
throw new Error(`\u8DEF\u7531\u540D\u79F0\u4E0D\u6B63\u786E!`);
}
return routeNames[0];
}
function getRouteModuleNameByGlob(glob, options) {
const routeName = getRouteNameByGlobWithTransformer(glob, options);
const moduleName = getRouteModuleNameByRouteName(routeName);
return moduleName;
}
function checkIsValidRouteModule(data) {
const isObject = Object.prototype.toString.call(data) === "[object Object]";
return isObject && data.name && data.path && data.component && data.meta;
}
function getSingleRouteModulesFromRouteName(routeName) {
const routeNames = getAllRouteNames(routeName);
const modules = routeNames.map((item, index) => {
const config = getRouteModuleConfig(index, routeNames.length);
const module = {
name: item,
path: getRoutePathFromName(item),
component: config.component,
meta: {
title: item,
icon: "mdi:menu"
}
};
if (config.hasSingleLayout) {
module.meta.singleLayout = "basic";
}
return module;
});
return modules;
}
function getSingleRouteModulesFromGlob(glob, options) {
const routeName = getRouteNameByGlobWithTransformer(glob, options);
const modules = getSingleRouteModulesFromRouteName(routeName);
return modules;
}
function getSingleRouteModulesWithChildren(singleModules) {
const reversedModules = [...singleModules].reverse();
reversedModules.forEach((module, index) => {
if (index < reversedModules.length - 1) {
reversedModules[index + 1].children = [module];
}
});
return reversedModules[reversedModules.length - 1] || null;
}
function recurseMergeModule(modules, singleModules, singleRouteLevel) {
if (!singleModules.length)
return;
const currentLevelRouteModule = singleModules[singleRouteLevel];
const findIndex = modules.findIndex((module) => module.name === currentLevelRouteModule.name);
if (findIndex > -1) {
const findModule = modules[findIndex];
if (!findModule.children) {
findModule.children = [];
}
recurseMergeModule(findModule.children, singleModules, singleRouteLevel + 1);
} else {
const pushModule = getSingleRouteModulesWithChildren(singleModules.slice(singleRouteLevel));
if (pushModule) {
modules.push(pushModule);
}
}
}
function mergeFirstDegreeRouteModule(firstDegreeRouteModule, singleModules) {
if (!firstDegreeRouteModule.children) {
firstDegreeRouteModule.children = [];
}
recurseMergeModule(firstDegreeRouteModule.children, singleModules, 1);
}
function getTotalRouteModuleFromNames(routeNames) {
let module;
routeNames.forEach((routeName, index) => {
const modules = getSingleRouteModulesFromRouteName(routeName);
const [firstModule] = modules;
if (index === 0) {
module = firstModule;
}
if (firstModule.name === module.name && modules.length > 1) {
mergeFirstDegreeRouteModule(module, modules);
}
});
return module;
}
function getRouteModuleFilePath(moduleName, options) {
const { rootDir, routeModuleDir, routeModuleExt } = options;
const filePath = `${rootDir}/${routeModuleDir}/${moduleName}.${routeModuleExt}`;
return filePath;
}
async function getIsRouteModuleFileExist(moduleName, options) {
const filePath = getRouteModuleFilePath(moduleName, options);
let exist = false;
try {
await access(filePath);
exist = true;
} catch {
}
return {
exist,
filePath
};
}
function getTheSmallLengthOfStrArr(arr) {
let name = arr[0];
arr.forEach((item) => {
if (name === null) {
name = item;
} else {
name = item.length < name.length ? item : name;
}
});
return name;
}
async function getRouteModuleWhetherFileExist(params) {
const { moduleName, existModuleName, routeConfig, options, existCallback } = params;
const { exist, filePath } = await getIsRouteModuleFileExist(existModuleName, options);
let module;
try {
if (exist) {
const importModule = await getRouteModuleFromFile(filePath, existModuleName, options);
if (checkIsValidRouteModule(importModule)) {
module = await existCallback(importModule, filePath);
} else {
throw Error("invalid route module!");
}
} else {
throw Error("not exist module file!");
}
} catch (error) {
const routeNames = routeConfig.files.filter((item) => item.name.includes(moduleName)).map((item) => item.name);
module = getTotalRouteModuleFromNames(routeNames);
}
return module;
}
function recurseRemoveModuleByName(module, routeName) {
if (!module.children)
return;
module.children = module.children.filter((item) => item.name !== routeName);
module.children.forEach((item) => {
if (routeName.includes(item.name)) {
recurseRemoveModuleByName(item, routeName);
}
});
}
function recurseRemoveModuleByNames(module, routeNames) {
if (!routeNames.length)
return;
routeNames.forEach((item) => {
recurseRemoveModuleByName(module, item);
});
}
function getRenamedDirConfig(dispatchs, options) {
const unlinkDirs = [];
const addDirs = [];
dispatchs.forEach((dispatch) => {
if (dispatch.event === "unlinkDir") {
unlinkDirs.push(dispatch.path);
}
if (dispatch.event === "addDir") {
addDirs.push(dispatch.path);
}
});
const oldDir = getTheSmallLengthOfStrArr(unlinkDirs);
const newDir = getTheSmallLengthOfStrArr(addDirs);
const oldRouteName = getRouteNameByGlobWithTransformer(oldDir, options);
const oldRouteFilePath = getRouteFilePathByGlob(oldDir);
const newRouteName = getRouteNameByGlobWithTransformer(newDir, options);
const newRouteFilePath = getRouteFilePathByGlob(newDir);
return {
oldRouteName,
newRouteName,
oldRouteFilePath,
newRouteFilePath
};
}
function getDelDirConfig(dispatchs, options) {
const unlinkDirs = [];
dispatchs.forEach((dispatch) => {
if (dispatch.event === "unlinkDir") {
unlinkDirs.push(dispatch.path);
}
});
const delDir = getTheSmallLengthOfStrArr(unlinkDirs);
const delRouteName = getRouteNameByGlobWithTransformer(delDir, options);
return {
delRouteName
};
}
function getAddDirConfig(dispatchs, options) {
const globs = [];
dispatchs.forEach((dispatch) => {
if (dispatch.event === "add") {
globs.push(dispatch.path);
}
});
const config = getRouteConfigByGlobs(globs, options);
return config;
}
function getDelFileConfig(dispatchs, options) {
const delRouteNames = [];
dispatchs.forEach((dispatch) => {
if (dispatch.event === "unlink") {
const name = getRouteNameByGlobWithTransformer(dispatch.path, options);
delRouteNames.push(name);
}
});
return {
delRouteNames
};
}
function getAddFileConfig(dispatchs, options) {
const addRouteNames = [];
const addRouteFiles = [];
dispatchs.forEach((dispatch) => {
if (dispatch.event === "add") {
const name = getRouteNameByGlobWithTransformer(dispatch.path, options);
addRouteNames.push(name);
const path = getRouteFilePathByGlob(dispatch.path);
addRouteFiles.push({ name, path });
}
});
const config = {
names: addRouteNames,
files: addRouteFiles
};
return config;
}
async function getRouteModuleFromFile(filePath, moduleName, options) {
const transformedFilePath = filePath.replace(`${moduleName}.${options.routeModuleExt}`, `${moduleName}-swc.js`);
const { code } = await transformFile(filePath, { filename: transformedFilePath, module: { type: "commonjs" } });
if (code) {
await writeFile(transformedFilePath, code, "utf-8");
}
const { default: importModule } = __require(transformedFilePath);
await remove(transformedFilePath);
return importModule;
}
function transformModuleNameToVariable(name) {
return name.replace(/-(\w)/g, (_, match) => match.toUpperCase());
}
// src/shared/eslint.ts
import { access as access2 } from "fs/promises";
import execa from "execa";
async function handleEslintFormat(filePath) {
const eslintBinPath = `${process.cwd()}/node_modules/eslint/bin/eslint.js`;
try {
await access2(eslintBinPath);
await execa("node", [eslintBinPath, filePath, "--fix"]);
} catch {
}
}
// src/context/declaration.ts
import { writeFile as writeFile2 } from "fs/promises";
function getDeclarationCode(routeConfig) {
let code = `declare namespace PageRoute {
/**
* the root route key
* @translate \u6839\u8DEF\u7531
*/
type RootRouteKey = '${ROOT_ROUTE}';
/**
* the not found route, which catch the invalid route path
* @translate \u672A\u627E\u5230\u8DEF\u7531(\u6355\u83B7\u65E0\u6548\u8DEF\u5F84\u7684\u8DEF\u7531)
*/
type NotFoundRouteKey = '${NOT_FOUND_ROUTE}';
/**
* the route key
* @translate \u9875\u9762\u8DEF\u7531
*/
type RouteKey =`;
routeConfig.names.forEach((name) => {
code += `
| '${name}'`;
});
code += `;
/**
* last degree route key, which has the page file
* @translate \u6700\u540E\u4E00\u7EA7\u8DEF\u7531(\u8BE5\u7EA7\u8DEF\u6709\u5BF9\u5E94\u7684\u9875\u9762\u6587\u4EF6)
*/
type LastDegreeRouteKey = Extract<
RouteKey,`;
routeConfig.files.forEach((item) => {
code += `
| '${item.name}'`;
});
code += `
>;
}
`;
return code;
}
async function generateDeclaration(routeConfig, options) {
const code = getDeclarationCode(routeConfig);
const filePath = `${options.rootDir}/${options.routeDts}`;
await writeFile2(filePath, code, "utf-8");
await handleEslintFormat(filePath);
}
// src/context/views.ts
import { writeFile as writeFile3 } from "fs/promises";
function transformKey(key) {
return key.includes("-") ? `'${key}'` : key;
}
function isPureNumberKey(key) {
const NUM_REG = /^\d+$/;
return NUM_REG.test(key);
}
function transformImportKey(key) {
const tranform = isPureNumberKey(key) ? `_view_${key}` : key;
return tranform;
}
function getViewsCode(routeFiles, options) {
let preCode = `import type { RouteComponent } from 'vue-router';
`;
let code = `
export const views: Record<
PageRoute.LastDegreeRouteKey,
RouteComponent | (() => Promise<{ default: RouteComponent }>)
> = {`;
routeFiles.forEach(({ name, path }, index) => {
const isLazy = options.lazyImport(name);
const key = transformKey(name);
if (isLazy) {
code += `
${key}: () => import('${path}')`;
} else {
const importKey = transformImportKey(name);
preCode += `import ${importKey} from '${path}';
`;
if (key === path && !isPureNumberKey(name)) {
code += `
${key}`;
} else {
code += `
${key}: ${importKey}`;
}
}
if (index < routeFiles.length - 1) {
code += ",";
}
});
code += "\n};\n";
return preCode + code;
}
async function generateViews(routeFiles, options) {
const code = getViewsCode(routeFiles, options);
const filePath = `${options.rootDir}/${options.pageDir}/index.ts`;
await writeFile3(filePath, code, "utf-8");
await handleEslintFormat(filePath);
}
// src/context/fs.ts
import { remove as remove2 } from "fs-extra";
// src/context/module.ts
import { ensureFile, writeFile as writeFile4 } from "fs-extra";
async function generateRouteModuleCode(moduleName, module, options) {
if (moduleName === INVALID_ROUTE_NAME)
return;
const filePath = getRouteModuleFilePath(moduleName, options);
const variable = transformModuleNameToVariable(moduleName);
const code = `const ${variable}: ${options.routeModuleType} = ${JSON.stringify(
module
)};
export default ${variable};`;
await ensureFile(filePath);
await writeFile4(filePath, code, "utf-8");
await handleEslintFormat(filePath);
}
// src/context/fs.ts
async function fileWatcherHandler(dispatchs, hooks) {
const dispatchWithCategory = {
addDir: [],
unlinkDir: [],
add: [],
unlink: []
};
dispatchs.forEach((item) => {
dispatchWithCategory[item.event].push(item.path);
});
const hasAddDir = dispatchWithCategory.addDir.length > 0;
const hasUnlinkDir = dispatchWithCategory.unlinkDir.length > 0;
const hasAdd = dispatchWithCategory.add.length > 0;
const hasUnlink = dispatchWithCategory.unlink.length > 0;
const { onRenameDirWithFile, onDelDirWithFile, onAddDirWithFile, onDelFile, onAddFile } = hooks;
const conditions = [
[hasAddDir && hasUnlinkDir && hasAdd && hasUnlink, onRenameDirWithFile],
[hasUnlinkDir && hasUnlink, onDelDirWithFile],
[hasAddDir && hasAdd, onAddDirWithFile],
[hasUnlink, onDelFile],
[hasAdd, onAddFile]
];
const [, callback] = conditions.find(([condition]) => condition) || [true, async () => {
}];
await callback();
}
function createFWHooksOfGenDeclarationAndViews(dispatchs, routeConfig, options) {
const hooks = {
async onRenameDirWithFile() {
const { oldRouteName, newRouteName, oldRouteFilePath, newRouteFilePath } = getRenamedDirConfig(
dispatchs,
options
);
routeConfig.names = routeConfig.names.map((name) => name.replace(oldRouteName, newRouteName));
routeConfig.files = routeConfig.files.map((item) => {
const name = item.name.replace(oldRouteName, newRouteName);
const path = item.path.replace(oldRouteFilePath, newRouteFilePath);
return {
name,
path
};
});
},
async onDelDirWithFile() {
const { delRouteName } = getDelDirConfig(dispatchs, options);
routeConfig.names = routeConfig.names.filter((name) => !name.includes(delRouteName));
routeConfig.files = routeConfig.files.filter((item) => !item.name.includes(delRouteName));
},
async onAddDirWithFile() {
const config = getAddDirConfig(dispatchs, options);
routeConfig.names = routeConfig.names.concat(config.names).sort();
routeConfig.files = routeConfig.files.concat(config.files).sort((a, b) => a.name > b.name ? 1 : -1);
},
async onDelFile() {
const { delRouteNames } = getDelFileConfig(dispatchs, options);
routeConfig.names = routeConfig.names.filter((name) => delRouteNames.every((item) => !name.includes(item)));
routeConfig.files = routeConfig.files.filter((item) => delRouteNames.every((v) => !item.name.includes(v)));
},
async onAddFile() {
const config = getAddFileConfig(dispatchs, options);
routeConfig.names = routeConfig.names.concat(config.names).sort();
routeConfig.files = routeConfig.files.concat(config.files).sort((a, b) => a.name > b.name ? 1 : -1);
}
};
return hooks;
}
function createFWHooksOfGenModule(dispatchs, routeConfig, options) {
async function getRouteModule(moduleName, existModuleName, existCallback) {
return getRouteModuleWhetherFileExist({ moduleName, existModuleName, routeConfig, options, existCallback });
}
const hooks = {
async onRenameDirWithFile() {
const { oldRouteName, newRouteName } = getRenamedDirConfig(dispatchs, options);
if (!oldRouteName || !newRouteName)
return;
const oldRoutePath = getRoutePathFromName(oldRouteName);
const newRoutePath = getRoutePathFromName(newRouteName);
const oldModuleName = getRouteModuleNameByRouteName(oldRouteName);
const newModuleName = getRouteModuleNameByRouteName(newRouteName);
const module = await getRouteModule(newModuleName, oldModuleName, async (routeModule, filePath) => {
const moduleJson = JSON.stringify(routeModule);
const updateModuleJson = moduleJson.replace(new RegExp(`"${oldRouteName}`, "g"), `"${newRouteName}`).replace(new RegExp(`${oldRoutePath}`, "g"), newRoutePath);
const existModule = JSON.parse(updateModuleJson);
await remove2(filePath);
return existModule;
});
if (module) {
await generateRouteModuleCode(newModuleName, module, options);
}
},
async onDelDirWithFile() {
const { delRouteName } = getDelDirConfig(dispatchs, options);
const moduleName = getRouteModuleNameByRouteName(delRouteName);
const globs = dispatchs.filter((dispatch) => dispatch.event === "unlink").map((dispatch) => dispatch.path);
const routeNames = globs.map((glob) => getRouteNameByGlobWithTransformer(glob, options));
const module = await getRouteModule(moduleName, moduleName, async (routeModule, filePath) => {
if (delRouteName === moduleName) {
await remove2(filePath);
return null;
}
recurseRemoveModuleByNames(routeModule, routeNames);
return routeModule;
});
if (module) {
await generateRouteModuleCode(moduleName, module, options);
}
},
async onAddDirWithFile() {
const globs = dispatchs.filter((dispatch) => dispatch.event === "add").map((dispatch) => dispatch.path);
const moduleName = getRouteModuleNameByGlob(globs[0], options);
const module = await getRouteModule(moduleName, moduleName, async (routeModule) => {
globs.forEach((glob) => {
const modules = getSingleRouteModulesFromGlob(glob, options);
mergeFirstDegreeRouteModule(routeModule, modules);
});
return routeModule;
});
if (module) {
await generateRouteModuleCode(moduleName, module, options);
}
},
async onDelFile() {
const { delRouteNames } = getDelFileConfig(dispatchs, options);
const globs = dispatchs.filter((dispatch) => dispatch.event === "unlink").map((dispatch) => dispatch.path);
delRouteNames.forEach(async (delRouteName) => {
const moduleName = getRouteModuleNameByRouteName(delRouteName);
const routeNames = globs.map((glob) => getRouteNameByGlobWithTransformer(glob, options));
const module = await getRouteModule(moduleName, moduleName, async (routeModule, filePath) => {
if (delRouteName === moduleName) {
await remove2(filePath);
return null;
}
recurseRemoveModuleByNames(routeModule, routeNames);
return routeModule;
});
if (module) {
await generateRouteModuleCode(moduleName, module, options);
}
});
},
async onAddFile() {
await this.onAddDirWithFile();
}
};
return hooks;
}
// src/context/index.ts
var Context = class {
options;
routeConfig;
dispatchId = null;
dispatchStack = [];
constructor(options = {}) {
const rootDir = process.cwd();
this.options = createPluginOptions(options, rootDir);
const globs = getGlobsOfPage(this.options.pageGlobs, this.options.pageDir);
this.routeConfig = getRouteConfigByGlobs(globs, this.options);
this.generate();
}
async generate() {
await generateDeclaration(this.routeConfig, this.options);
await generateViews(this.routeConfig.files, this.options);
}
createFileWatcherHooks(dispatchs) {
const declarationAndViewsHooks = createFWHooksOfGenDeclarationAndViews(dispatchs, this.routeConfig, this.options);
const filteredDispatchs = dispatchs.filter((dispatch) => {
const isFile = dispatch.event === "add" || dispatch.event === "unlink";
if (!isFile)
return true;
const routeName = getRouteNameByGlob(dispatch.path, this.options.pageDir);
const generateRouteModule = this.options.onRouteModuleGenerate(routeName);
return generateRouteModule;
});
const moduleHooks = createFWHooksOfGenModule(filteredDispatchs, this.routeConfig, this.options);
const hooks = {
async onRenameDirWithFile() {
await declarationAndViewsHooks.onRenameDirWithFile();
await moduleHooks.onRenameDirWithFile();
},
async onDelDirWithFile() {
await declarationAndViewsHooks.onDelDirWithFile();
await moduleHooks.onDelDirWithFile();
},
async onAddDirWithFile() {
await declarationAndViewsHooks.onAddDirWithFile();
await moduleHooks.onAddDirWithFile();
},
async onDelFile() {
await declarationAndViewsHooks.onDelFile();
await moduleHooks.onDelFile();
},
async onAddFile() {
await declarationAndViewsHooks.onAddFile();
await moduleHooks.onAddFile();
}
};
return hooks;
}
dispatchFileWatcher(glob, event) {
const isMatch2 = matchGlob(glob, this.options);
if (!isMatch2)
return;
const dispacth = {
event,
path: glob
};
if (this.checkDispatch(dispacth)) {
this.dispatchStack.push(dispacth);
}
if (!this.dispatchId) {
this.dispatchId = setTimeout(async () => {
const hooks = this.createFileWatcherHooks(this.dispatchStack);
await fileWatcherHandler(this.dispatchStack, hooks);
this.generate();
this.dispatchStack = [];
this.dispatchId = null;
}, 100);
}
}
checkDispatch(dispatch) {
const isFile = dispatch.event === "add" || dispatch.event === "unlink";
if (!isFile)
return true;
const routeName = getRouteNameByGlob(dispatch.path, this.options.pageDir);
return routeName !== INVALID_ROUTE_NAME;
}
setupFileWatcher() {
const events = ["addDir", "unlinkDir", "add", "unlink"];
events.forEach((event) => {
chokidar.watch(["."], {
ignoreInitial: true,
cwd: this.options.pageDir
}).on(event, (path) => {
this.dispatchFileWatcher(path, event);
});
});
}
};
// src/index.ts
function pageRoute(options) {
const context = new Context(options);
const plugin = {
name: "vite-plugin-vue-page-route",
enforce: "post",
configureServer() {
context.setupFileWatcher();
}
};
return plugin;
}
var src_default = pageRoute;
export {
src_default as default
};