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

befly-vite

v1.28.0

Published

Befly Vite 配置预设和插件集合

Readme

befly-vite

befly-vite 是 Befly 后台项目的 Vite 预设包,负责把项目约定、常用插件和 Vite 原生配置组合在一起。

它目前提供 4 类能力:

  1. Vite 配置侧的 createBeflyViteConfig()
  2. Vite 配置侧的 scanViews()
  3. 浏览器运行时的 Layouts()
  4. CLI 入口 befly-vite

适用场景

  • 想在后台管理项目里直接复用 Befly 约定的 Vite 默认配置
  • 想自动扫描 src/viewsbefly-admin-ui/views
  • 想复用 TDesign 相关的自动导入、组件自动注册和图标规则
  • 想保留 Vite 原生 viteConfig 作为统一扩展出口

安装

bun add -d befly-vite vite

如果项目本身还没安装运行时依赖,通常还需要自行安装 Vue 侧依赖,例如:

bun add vue vue-router pinia tdesign-vue-next tdesign-icons-vue-next

导出说明

Vite 配置侧

vite.config.js 里使用:

import { createBeflyViteConfig, scanViews } from "befly-vite";

可用导出:

  • createBeflyViteConfig
  • scanViews

浏览器运行时

在前端运行时代码里使用:

import { Layouts } from "befly-vite";

可用导出:

  • Layouts

createBeflyViteConfig

createBeflyViteConfig(options) 是主入口,用来生成 Befly 项目的 Vite 配置。

最小用法

// vite.config.js
import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig();

默认内置内容

调用后默认会包含以下能力:

  1. vue-router/vite 路由扫描插件
  2. @vitejs/plugin-vue
  3. unplugin-vue-components
  4. @ 指向项目 src
  5. server.open = false
  6. server.hmr = true
  7. build.outDir = "dist"
  8. build.assetsDir = "assets"
  9. build.cssMinify = "lightningcss"
  10. css.transformer = "lightningcss"
  11. 默认 CSS 浏览器基线:Chrome 107 / Edge 107 / Firefox 104 / Safari 16.0

参数说明

| 参数 | 类型 | 默认值 | 作用 | | -------------- | -------------------- | --------------- | ---------------------------------------------------- | | root | string | process.cwd() | 项目根目录,用于解析 src、扫描 views 和生成别名 | | devtool | boolean | false | 是否启用 vite-plugin-vue-devtools | | analyzer | boolean | false | 是否启用打包分析,并输出到 <root>/temp/analyzer | | resolvers | Object \| Object[] | undefined | 追加到组件自动注册中的自定义 resolver | | manualChunks | Function \| Object | undefined | 便捷写入 build.rolldownOptions.output.manualChunks | | viteConfig | Object | {} | 最终合并到默认配置上的 Vite 原生配置 |

参数细节

root

root 决定这些行为的基准目录:

  1. @ 别名指向哪个 src
  2. scanViews() 扫哪个项目目录
  3. 打包分析文件输出到哪个 temp

最常见写法:

import { fileURLToPath } from "node:url";
import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    root: fileURLToPath(new URL(".", import.meta.url))
});

devtool

开启后会额外注入 vite-plugin-vue-devtools

import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    devtool: true
});

适合:本地调试组件树、路由和状态。

analyzer

开启后会额外注入 vite-bundle-analyzer,并把报告输出到项目的 temp/analyzer

import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    analyzer: true
});

适合:分析打包体积、依赖拆分和大包来源。

resolvers

befly-vite 默认内置:

  1. TDesign Vue Next resolver
  2. TDesign 图标 resolver
  3. src/**/*.vuenode_modules/befly-admin-ui/**/*.vuepackages/adminUI/**/*.vue(monorepo 本地源码)都会进入组件自动注册范围

如果项目还想增加额外 resolver,可以通过 resolvers 追加。它会同时追加到:

  1. unplugin-vue-components
import { createBeflyViteConfig } from "befly-vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

export default createBeflyViteConfig({
    resolvers: [ElementPlusResolver()]
});

说明:

  1. 默认的 TDesign resolver 不会被替换,只会追加新的 resolver
  2. 如果你传单个对象,也会自动转成数组处理

manualChunks

manualChunks 是一个便捷入口,会写入 build.rolldownOptions.output.manualChunks

适合:

  1. 只想快速传一个 manualChunks
  2. 不想为了简单分包额外展开完整的 build 配置

如果还要同时配置 output.entryFileNameschunkFileNamesassetFileNames 等其他构建输出项,推荐直接走 viteConfig.build.rolldownOptions

如果旧项目还在传 viteConfig.build.rollupOptions,在 Vite 8 下也还能继续工作;只是新配置更建议直接写 build.rolldownOptions

函数写法:

import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    manualChunks: function (id) {
        if (id.includes("tdesign-vue-next")) {
            return "tdesign";
        }

        if (id.includes("node_modules")) {
            return "vendor";
        }
    }
});

对象写法:

import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    manualChunks: {
        vue: ["vue", "vue-router", "pinia"],
        tdesign: ["tdesign-vue-next", "tdesign-icons-vue-next"]
    }
});

适合:

  1. 把大依赖稳定拆分出去
  2. 减少首屏主包体积
  3. 提升缓存命中率

viteConfig

viteConfig 是扩展出口,所有不值得再额外封装一层的配置,都建议直接从这里传入。

简单示例:

import { createBeflyViteConfig } from "befly-vite";
import { fileURLToPath } from "node:url";

export default createBeflyViteConfig({
    root: fileURLToPath(new URL(".", import.meta.url)),
    viteConfig: {
        server: {
            port: 5600
        }
    }
});

适合放在这里的配置包括:

  1. server.port
  2. server.proxy
  3. define
  4. build.sourcemap
  5. build.cssTarget
  6. css.lightningcss
  7. build.rolldownOptions
  8. 其他任意 Vite 原生配置

chunks 的推荐方式:

  1. 简单场景用顶层 manualChunks
  2. 需要完整控制输出结构时,用 viteConfig.build.rolldownOptions

示例:

import { createBeflyViteConfig } from "befly-vite";
import { fileURLToPath } from "node:url";

export default createBeflyViteConfig({
    root: fileURLToPath(new URL(".", import.meta.url)),
    viteConfig: {
        build: {
            rolldownOptions: {
                output: {
                    manualChunks: function (id) {
                        if (id.includes("tdesign-vue-next") || id.includes("tdesign-icons-vue-next")) {
                            return "tdesign";
                        }

                        if (id.includes("node_modules/vue") || id.includes("node_modules/vue-router") || id.includes("node_modules/pinia")) {
                            return "framework";
                        }
                    },
                    entryFileNames: "assets/[name]-[hash].js",
                    chunkFileNames: "assets/[name]-[hash].js"
                }
            }
        }
    }
});

CSS 兼容配置

befly-vite 不再提供单独的 compat 配置,CSS 兼容统一走 Vite 8 原生配置。

默认行为

默认内置:

{
    build: {
        cssTarget: ["chrome107", "edge107", "firefox104", "safari16"],
        cssMinify: "lightningcss"
    },
    css: {
        transformer: "lightningcss",
        lightningcss: {
            targets: {
                chrome: 107 << 16,
                edge: 107 << 16,
                firefox: 104 << 16,
                ios_saf: 16 << 16,
                safari: 16 << 16
            }
        }
    }
}

为什么同时有 build.cssTargetcss.lightningcss.targets

  1. build.cssTarget 控制 CSS 压缩输出目标
  2. css.lightningcss.targets 控制 Lightning CSS 的语法降级和前缀处理目标

这两者默认保持一致。

项目侧覆盖写法

如果项目需要更高或更低的兼容基线,可以直接通过 viteConfig 覆盖。

import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    viteConfig: {
        build: {
            cssTarget: ["chrome120", "edge120", "firefox120", "safari17"]
        },
        css: {
            lightningcss: {
                targets: {
                    chrome: 120 << 16,
                    edge: 120 << 16,
                    firefox: 120 << 16,
                    ios_saf: 17 << 16,
                    safari: 17 << 16
                },
                drafts: {
                    nesting: true
                }
            }
        }
    }
});

说明:

  1. viteConfig.build.cssTarget 一旦传入,会直接覆盖默认值
  2. viteConfig.css.lightningcss.targets 一旦传入,也会直接覆盖默认值
  3. 其他 css.lightningcss 选项仍会与默认配置合并

常见 CSS 配置案例

只改压缩目标

import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    viteConfig: {
        build: {
            cssTarget: "safari16"
        }
    }
});

调整 Lightning CSS draft 能力

import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    viteConfig: {
        css: {
            lightningcss: {
                drafts: {
                    nesting: true,
                    customMedia: true
                }
            }
        }
    }
});

关闭 CSS 压缩

import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    viteConfig: {
        build: {
            cssMinify: false
        }
    }
});

路由扫描规则

befly-vite 内部通过 scanViews(appRoot) 扫描视图目录,并交给 vue-router/vite

默认扫描来源

  1. <root>/src/views
  2. <root>/node_modules/befly-admin-ui/views

其中 befly-admin-ui/views 会被挂到 core/ 前缀下。

默认排除规则

两个目录都会排除:

**/components/**

单独使用 scanViews

如果项目要直接复用这套扫描规则,也可以单独调用:

import { fileURLToPath } from "node:url";
import { scanViews } from "befly-vite";

const appRoot = fileURLToPath(new URL(".", import.meta.url));
const routesFolders = scanViews(appRoot);

console.log(routesFolders);

返回值结构示例:

[
    {
        src: "/absolute/path/to/src/views",
        path: "",
        exclude: ["**/components/**"]
    },
    {
        src: "/absolute/path/to/node_modules/befly-admin-ui/views",
        path: "core/",
        exclude: ["**/components/**"]
    }
];

组件自动注册规则

befly-vite 现在只负责 Vue 组件自动注册,不再自动导入 Vue、Pinia、Vue Router API。页面和组件里用到这些 API 时,需要显式 import

Components

默认会对以下目录启用组件自动注册:

  1. src/**/*.vue
  2. node_modules/befly-admin-ui/**/*.vue

默认内置 resolver:

  1. TDesign Vue Next resolver
  2. tdesign-icons-vue-next 图标 resolver
  3. 你额外传入的 resolvers

说明:

  1. src/components 会被作为本地组件目录扫描
  2. befly-vite 只自动注册组件;Vue、Pinia、Vue Router API 仍需按项目规范手动导入

Layouts

Layouts(routes, rootRedirectPath, resolveLayoutComponent) 用于浏览器运行时把 auto-routes 结果转换成带布局的最终路由。

作用

它会根据页面文件名里的 _数字 后缀决定使用哪个布局,并把普通路径段统一转换成短横线小写。

例如:

  1. userCenter/account_1.vue -> /user-center/account,布局 1
  2. newsDetail_2.vue -> /news-detail,布局 2
  3. guide/index_1.vue -> /guide,布局 1

基础示例

import { Layouts } from "befly-vite";

const routes = [
    {
        path: "userCenter",
        children: [
            {
                path: "account_1",
                component: () => import("./views/userCenter/account.vue")
            },
            {
                path: "my_news",
                component: () => import("./views/userCenter/my_news.vue")
            }
        ]
    }
];

const finalRoutes = Layouts(routes, "/dashboard", function (layoutName) {
    return layoutName ? `layout:${layoutName}` : "layout:default";
});

参数说明

| 参数 | 类型 | 作用 | | ------------------------ | ---------- | --------------------------------------------- | | routes | Array | auto-routes 产出的原始路由数组 | | rootRedirectPath | string | 根路径 / 的重定向目标;传空值则不注入重定向 | | resolveLayoutComponent | Function | 根据布局名返回布局组件 |

Layouts 规则说明

  1. 动态参数段如 :userId 会保留原样
  2. 普通路径段会统一转成短横线小写
  3. 下划线 _ 会转成 -
  4. 驼峰会转成短横线小写
  5. _数字 后缀只用于布局名,不会出现在最终路径里
  6. index 子页会折叠成父路径下的空子路径

CLI

包内自带 befly-vite 命令,本质上是一个 Bun 环境下的 Vite 启动包装器,用来帮项目找到 vite/bin/vite.js 并转发参数。

最常见脚本写法

页面项目自己的 package.json 在这里主要只保留运行脚本;在 Befly 仓库内,lint / format 的配置文件、根脚本和提交钩子统一跟随仓库根 oxfmt.config.js / oxlint.config.ts 与共享 Oxc 基线,不要在基于 befly-vite 的页面包里再复制第二套可执行 Oxc 配置。

{
    "scripts": {
        "dev": "bunx --bun befly-vite",
        "build": "bunx --bun befly-vite build",
        "preview": "bunx --bun befly-vite preview"
    }
}

作用

  1. 自动定位 vite 可执行文件
  2. 用 Bun 转发执行 vite
  3. 保持页面项目运行脚本写法统一
  4. 让页面包把 dev/build/previewlint/format 的职责边界分开:运行脚本留在页面包,代码规范跟随根配置

完整案例

案例 1:最小后台项目

import { fileURLToPath } from "node:url";
import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    root: fileURLToPath(new URL(".", import.meta.url))
});

案例 2:本地开发端口 + 调试工具

import { fileURLToPath } from "node:url";
import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    root: fileURLToPath(new URL(".", import.meta.url)),
    devtool: true,
    viteConfig: {
        server: {
            port: 5206
        }
    }
});

案例 3:打包分析 + Vite 原生分包

import { fileURLToPath } from "node:url";
import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    root: fileURLToPath(new URL(".", import.meta.url)),
    analyzer: true,
    viteConfig: {
        build: {
            rolldownOptions: {
                output: {
                    manualChunks: function (id) {
                        if (id.includes("tdesign-vue-next") || id.includes("tdesign-icons-vue-next")) {
                            return "tdesign";
                        }

                        if (id.includes("node_modules")) {
                            return "vendor";
                        }
                    }
                }
            }
        }
    }
});

案例 4:自定义 CSS 浏览器兼容目标

import { fileURLToPath } from "node:url";
import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    root: fileURLToPath(new URL(".", import.meta.url)),
    viteConfig: {
        build: {
            cssTarget: ["chrome120", "edge120", "firefox120", "safari17"]
        },
        css: {
            lightningcss: {
                targets: {
                    chrome: 120 << 16,
                    edge: 120 << 16,
                    firefox: 120 << 16,
                    ios_saf: 17 << 16,
                    safari: 17 << 16
                }
            }
        }
    }
});

案例 5:Vite 原生能力扩展

import { fileURLToPath } from "node:url";
import { createBeflyViteConfig } from "befly-vite";

export default createBeflyViteConfig({
    root: fileURLToPath(new URL(".", import.meta.url)),
    viteConfig: {
        define: {
            __APP_NAME__: JSON.stringify("befly-admin")
        },
        build: {
            sourcemap: true
        },
        server: {
            proxy: {
                "/api": {
                    target: "http://127.0.0.1:3000",
                    changeOrigin: true
                }
            }
        }
    }
});

什么时候应该直接用 viteConfig

如果某个能力本身已经是稳定的 Vite 原生配置,而且 befly-vite 没必要再包装一层,优先直接用 viteConfig。例如:

  1. server.port
  2. server.proxy
  3. define
  4. build.sourcemap
  5. build.cssTarget
  6. build.cssMinify
  7. css.lightningcss
  8. resolve.alias

License

Apache-2.0