npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

zerg-cmiot-vite-plugin-auto-routes

v1.0.1

Published

vite插件,自动生成routes

Downloads

6

Readme

介绍

本插件会根据在vue文件中的自定义标签(默认为router标签)来自动生成路由routes

您只需要在需要生成路由的vue文件中设置好路由的元数据,即可自动生成路由,无需再去书写路由的path、name、component

使用

插件引入:

import { customRouterPlugin } from 'zerg-cmiot-vite-plugin-auto-routes';

export default defineConfig({
    plugins: [vue(), customRouterPlugin()],
})

自定义标签(默认为router标签):

<router lang="ts">
export default {
  isLayout: true,
  meta: {
    name: 'xxx',
    ignoreLogin: true,
  },
};
</router>

customRouterPlugin(option):可选项option

type OptionType = {
    /** views文件夹相对vite.config.ts路径,默认为"src/views" */
    pagesDir: string;
    /** 生成的自动路由的文件相对vite.config.ts路径,默认为"src/router" */
    routesFileDir: string;
    /** 生成的自动路由的文件名,默认为"autoRoutes.ts" */
    routesFileName: string;
    /** 生产环境(打包)时是否需要执行该插件,默认为"false" */
    executeInProduction: boolean;
    /** vue文件中作为route的自定义标签名称,默认为"router" */
    tagName: string;
    /** layoutEmpty的路径,默认为"@/layouts/empty/index.vue" */
    layoutPath: string;
};

自定义标签的类型:

type RouteType = {
    /** 支持手动赋值,以覆盖自动生成的path */
    path?: string;
    /** 支持手动赋值,以覆盖自动生成的name */
    name?: string;
    redirect?: string;
    meta?: Record<string, any>;
    /** 路由在最终的routes中的顺序 */
    order?: number;
    /** 路由是否为layout */
    isLayout?: boolean;
};

注:如果自定义标签内为空对象,或没有自定义标签,则不会将对该vue文件生成路由

例子:

目录:

src/
├── layouts/
│   ├── empty/
│   │   └── index.vue
├── views/
│   ├── Home/
│   │   ├── HomeLayout.vue
│   │   └── components/
│   │       ├── HomeComponent1.vue
│   │       └── HomeComponent2.vue
│   ├── About/
│   │   ├── About.vue
│   │   └── components/
│   │       ├── AboutComponent1.vue
│   │       └── AboutComponent2.vue
│   └── NotFound.vue
└── router/
    ├── index.ts
    └── autoRoutes.ts

其中只有HomeLayout.vue、HomeComponent1.vue、HomeComponent2.vue、AboutComponent2.vue设置了router标签

HomeLayout.vue:

<template></template>
<script lang="ts" setup></script>
<style scoped></style>

<router lang="ts">
export default {
	isLayout: true,
	meta: {
		name: '一级菜单',
		type: 'sideMenu',
	},
};
</router>

HomeComponent1.vue:

<router lang="ts">
export default {
    name: 'HomeComponent1',
    order: 2,
    meta: {
        type: 'sideMenu',
    },
};
</router>

HomeComponent2.vue:

<router lang="ts">
export default {
    order: 1,
    meta: {
        type: 'sideMenu',
    },
};
</router>

AboutComponent2.vue:

<router lang="ts">
export default {
    order: 1,
    meta: {
        name: 'about',
        type: 'sideMenu',
    },
};
</router>

autoRoutes.ts

export const routes = [
    {
        /** order: 1 **/
        path: "/about/components/aboutcomponent2",
        name: "AboutComponentsAboutComponent2",
        component: () => import('../views/about/components/AboutComponent2.vue'),
        meta: { "name": "about", "type": "sideMenu" },
    },
    {
        /** order: Infinity **/
        path: "/home/homelayout",
        name: "HomeHomeLayout",
        component: () => import('@/layouts/empty/index.vue'),
        meta: { "name": "一级菜单", "type": "sideMenu" },
        children: [
            {
                /** order: 1 **/
                path: "/home/components/homecomponent2",
                name: "HomeComponentsHomeComponent2",
                component: () => import('../views/home/components/HomeComponent2.vue'),
                meta: { "type": "sideMenu" },
            },
            {
                /** order: 2 **/
                path: "/home/components/homecomponent1",
                name: "HomeComponent1",
                component: () => import('../views/home/components/HomeComponent1.vue'),
                meta: { "type": "sideMenu" },
            }],
    }
];

原理与流程

插件

vite插件:本质上就是一个具有特定结构的js对象,对象提供了钩子函数,在vite构建的不同阶段执行特定的逻辑

钩子函数:主要用到两个:configResolvedhandleHotUpdate

configResolved:在解析 Vite 配置后调用。使用这个钩子读取和存储最终解析的配置。相当于每次执行vite来启动项目或打包项目之前,会先执行该函数

handleHotUpdate:热更新钩子函数,当vite检测到热更新后,会执行该钩子函数

本插件的核心是在configResolved阶段去读取views文件中的vue文件并将其转化为路由

文件读取

单个文件:

  1. fs模块读取文件
  2. compiler插件去解析文件,并提取自定义标签里面的内容
  3. 内容转化为js对象

嵌套文件:递归读取,分三种情况

  1. 当前文件夹内的所有的内容均为vue文件时,将这些vue文件置为同级路由,并结束递归
  2. 当前文件夹内的内容为vue文件+文件夹,vue文件全部做父路由,文件夹则进行递归处理并将其作为vue文件的子路由
  3. 当前文件夹内的所有内容为文件夹时,递归

注:

排序:对同级的路由进行排序,根据order从小到大排。排序在情况1进行排

排序的原因:生成的路由顺序是严格按照目录结构来的,目录结构是a~z来排,而菜单是严格根据路由顺序来的,因此菜单的顺序无法自定义

内容转化为js对象

  1. 将文件的当前路径到views的相对路径作为path和name(字符串切片和拼接实现)
  2. 将文件的当前路径到生成的路由文件的相对路径作为component,并使用懒加载形式
  3. 用户没有添加oder属性,将其赋值为无穷大
  4. 在自定义标签中,若isLayout=true,则表示该路由是layout路由,对其进行单独处理

路由文件生成

fs.writeFile就可以写入一个文件,将之前生成好的js对象的集合,全部转为字符串再写入到指定目录即可