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

@heisea/navim

v1.0.0

Published

面向 `single-spa + Vue 2` 场景的前端打包工具库。当前实现已经统一到三套引擎:

Readme

Navim

面向 single-spa + Vue 2 场景的前端打包工具库。当前实现已经统一到三套引擎:

  • webpack
  • vite
  • rsbuild

文档按当前仓库实现编写,重点说明可用命令、配置 schema、引擎差异和兼容行为。本文中把体积分析能力统一称为 analyze,当前 CLI 命令名仍保留为 analyzer,用于兼容既有项目。

适用范围

  • Node.js >= 20.0.0
  • 仓库维护和 CI 基线统一使用 pnpm 9.15.9
  • Vue 2 项目
  • 微前端场景,尤其是 single-spa
  • 项目根目录通过 navim.config.js 驱动 Navim

安装

推荐把 @heisea/navim 安装到项目依赖中,再通过 npm scripts 或 npx 调用。

pnpm add -D @heisea/navim

或:

npm install -D @heisea/navim

快速开始

{
  "scripts": {
    "dev": "navim-service dev --engine webpack",
    "dev:vite": "navim-service dev --engine vite",
    "dev:rsbuild": "navim-service dev --engine rsbuild",
    "build": "navim-service build --engine webpack",
    "build:vite": "navim-service build --engine vite",
    "build:rsbuild": "navim-service build --engine rsbuild",
    "analyze": "navim-service analyzer --engine webpack",
    "inspect": "navim-service inspect --engine webpack",
    "single-spa:doctor": "navim-service single-spa doctor"
  }
}

目录约定

Navim 依赖一些固定文件位置,缺少这些文件时命令会直接失败。

your-project/
├── build/
│   └── config.js
├── public/
│   └── index.html
├── src/
│   ├── main.js
│   ├── styles/
│   │   └── variables.less
│   └── plugins/
├── .env
├── .env.local
├── .env.development
├── .env.production
└── navim.config.js

关键约定:

  • 根目录必须存在 navim.config.js
  • build/config.js 必须存在,哪怕只导出空对象
  • HTML 模板固定为 public/index.html
  • 默认 Less 全局变量入口为 src/styles/variables.less
  • 默认插件目录为 src/plugins

CLI 命令

统一入口

统一入口是以下四类命令:

navim-service dev --engine webpack|vite|rsbuild
navim-service build --engine webpack|vite|rsbuild
navim-service analyzer --engine webpack|rsbuild
navim-service inspect --engine webpack|vite|rsbuild

说明:

  • dev 默认引擎是 webpack
  • build 默认引擎是 webpack
  • analyzer 默认引擎是 webpack
  • inspect 默认引擎是 webpack
  • dev 固定按开发模式运行
  • build 只接受 productionpretest 三种环境值,默认 production
  • analyzer 语义上对应 analyze

dev

navim-service dev --engine webpack
navim-service dev --engine vite
navim-service dev --engine rsbuild
navim-service dev --engine webpack --micro
navim-service dev --engine webpack --mode sit

公共参数:

  • --engine <engine>webpackvitersbuild
  • --micro:微前端模式,主要影响 webpack 和 rsbuild 的 externals 策略
  • --mode <type>:额外读取 .env.<type>

build

navim-service build
navim-service build test
navim-service build pre
navim-service build production --mode sit
navim-service build --engine vite
navim-service build --engine rsbuild

行为说明:

  • 默认环境为 production
  • 合法环境值只有 productiontestpre
  • --mode <type> 会额外读取 .env.<type>
  • webpackvitersbuild 都支持构建

analyzer

navim-service analyzer
navim-service analyzer --engine webpack
navim-service analyzer --engine rsbuild

说明:

  • 当前 CLI 命令名仍然是 analyzer
  • 语义上对应统一的 analyze 能力
  • webpack 使用 webpack-bundle-analyzer
  • rsbuild 会启用 bundleAnalyze
  • vite 当前不支持分析命令

inspect

navim-service inspect
navim-service inspect --engine vite
navim-service inspect --engine rsbuild --env production
navim-service inspect --micro

用途:

  • 输出当前引擎翻译后的运行时配置
  • 适合排查 entryaliasproxyhtmloutputstyles 的最终值

兼容命令

以下旧命令仍然保留:

  • navim-service start 等价于 navim-service dev --engine webpack
  • navim-service vite start 等价于 navim-service dev --engine vite
  • navim-service single-spa doctor 仍然可用

build/config.js

build/config.js 是代理配置文件。当前实现会直接读取它,因此文件必须存在。

如果没有代理需求,也请至少导出空对象:

module.exports = {};

常见写法:

module.exports = {
  "/api": {
    target: "http://localhost:8080",
    changeOrigin: true,
  },
};
//

navim.config.js

navim.config.js 是 Navim 的核心配置文件,支持对象形式和函数形式。当前实现同时兼容两种 schema:

  • legacy:顶层使用 webpackvitersbuild
  • current:顶层使用 common,再加上 webpackvitersbuild 作为引擎覆盖项

当前 schema 边界

  • vitersbuilddev / build / inspect 直接消费 common
  • webpackdev / build / analyzer 仍然走 legacy webpack 配置块
  • single-spa doctor 也仍然只面向 legacy webpack 配置块
  • 如果项目同时要跑 webpackvite / rsbuild,当前需要保留一份 legacy webpack 字段,并与 common 中的对应值保持同步
  • 只写 common 而不写 legacy webpack.entrywebpack.librarywebpack.publicPath,当前并不足以驱动 webpack 实际构建

函数形式

函数会收到两个参数:

  • NODE_ENV
  • extraInfo
    • 当前实现中包含 extraInfo.navim_hash
module.exports = (NODE_ENV, extraInfo) => {
  const entry = NODE_ENV === "development" ? "./src/main.dev.js" : "./src/main.js";
  const publicPath = NODE_ENV === "development" ? "//localhost:9000/" : "/demo/";

  return {
    common: {
      entry: {
        app: entry,
      },
      output: {
        outDir: "dist",
        publicPath,
        library: {
          name: "demo-app",
          format: "umd",
        },
      },
      dev: {
        host: "127.0.0.1",
        port: 9000,
        open: false,
        headers: {
          "Access-Control-Allow-Origin": "*",
        },
      },
      html: {
        template: "./public/index.html",
        rootElementId: "app",
      },
      resolve: {
        alias: {
          "@": "./src",
        },
      },
      styles: {
        extract: true,
        resources: ["./src/styles/variables.less"],
        less: {
          javascriptEnabled: true,
        },
      },
      assets: {
        copy: [],
      },
      define: {},
      externals: {
        dev: {
          react: "React",
          "react-dom": "ReactDOM",
        },
        micro: {
          vue: "Vue",
          "vue-router": "VueRouter",
          "element-ui": "ELEMENT",
        },
      },
      micro: {
        enabled: false,
        type: "single-spa",
        cssExtractDoctor: true,
      },
    },
    webpack: {
      // webpack 运行时当前仍然依赖这组 legacy 字段
      entry: {
        app: entry,
      },
      library: "demo-app",
      publicPath,
      isExtractCss: true,
      styleResourcesLoaderPatterns: ["./src/styles/variables.less"],
      extraPlugins: [],
      htmlWebpackPlugin: {},
      htmlWebpackTagsPlugin: {},
      copyWebpackPluginPatterns: [],
    },
    vite: {
      entry: "./src/main.js",
      rootElementId: "app",
      optimizeDeps: {
        include: ["@heisea/brick"],
        exclude: ["vue-router", "vuex"],
      },
      staticCopyTargets: [],
      plugins: [],
    },
    rsbuild: {
      plugins: [],
      tools: {},
      config: {},
    },
  };
};

旧 schema

如果你不想迁移,旧的顶层写法仍然可用。

module.exports = {
  webpack: {
    entry: {
      app: "./src/main.js",
    },
    library: "demo-app",
    publicPath: "/demo/",
  },
  vite: {
    entry: "./src/main.js",
    rootElementId: "app",
  },
  rsbuild: {
    plugins: [],
  },
};

common 配置

common 是推荐的 normalized 公共配置层,但当前只有一部分字段真正进入了运行时。

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | entry | object | {} | 入口定义 | | output.outDir | string | dist | 输出目录 | | output.publicPath | string | 无 | 资源前缀 | | output.library.name | string | 无 | 主要给 webpack 用的库名 | | output.library.format | string | umd | 主要给 webpack 用的输出格式 | | dev.host | string | 127.0.0.1 | 开发服务 host | | dev.port | number | 9000 | 开发服务端口 | | dev.open | boolean | false | 是否自动打开浏览器 | | dev.headers | object | CORS 头 | 开发服务响应头 | | html.template | string | ./public/index.html | HTML 模板 | | html.rootElementId | string | app | 根节点 id | | html.tags | object | {} | HTML tag 扩展数据 | | resolve.alias | object | 内置别名 | 路径别名 | | resolve.extensions | string[] | 内置扩展 | 解析扩展名 | | styles.extract | boolean | false | 主要给 webpack 的 CSS 抽离开关 | | styles.resources | string[] | [] | Less 全局注入文件 | | styles.less.javascriptEnabled | boolean | true | Less loader 选项 | | assets.copy | Array | [] | 复制静态资源 | | define | object | {} | 常量注入 | | externals.dev | object | react / react-dom | 开发态 externals | | externals.micro | object | 微前端 externals | 微前端外部依赖 | | micro.enabled | boolean | false | 微前端开关 | | micro.type | string | single-spa | 微前端类型 | | micro.cssExtractDoctor | boolean | true | CSS 抽离提示开关 |

当前生效范围

  • 已在 vitersbuild 运行时直接生效:entryoutput.publicPathoutput.outDirdev.hostdev.portdev.openhtml.templateresolve.aliasresolve.extensionsstyles.resourcesstyles.less.javascriptEnableddefine
  • 当前只在 vite 运行时直接生效:html.rootElementId
  • 当前只在 rsbuild 运行时直接生效:dev.headersassets.copyexternals.devexternals.micro
  • 当前主要是 schema 预留、归一化输出或未来收敛位,不应当视为“已经全面支持”:output.library.nameoutput.library.formathtml.tagsstyles.extractmicro.enabledmicro.typemicro.cssExtractDoctor

如果你当前仍然依赖 webpack 命令,请继续在 webpack 配置块里显式声明这些 legacy 字段:

  • entry
  • library
  • publicPath
  • isExtractCss
  • styleResourcesLoaderPatterns
  • copyWebpackPluginPatterns
  • htmlWebpackPlugin
  • htmlWebpackTagsPlugin
  • extraPlugins

默认别名

当前实现内置了这些别名:

  • @ -> ./src
  • ~@ -> ./src
  • /plugins -> ./src/plugins
  • images -> ./images
  • vue -> vue/dist/vue.esm.js
  • vue$ -> vue/dist/vue.common.js
  • ~element-ui -> ./node_modules/element-ui

默认扩展名

当前实现默认会解析:

.js .json .css .less .vue .mjs .mts .ts .jsx .tsx

webpack 配置

webpack 仍然是能力最完整的引擎,也是当前默认引擎。但要注意,当前 webpack 运行时还没有切到 common 驱动模型,仍然直接读取 legacy webpack 配置块。

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | extraPlugins | Array | [] | 额外追加到 webpack 配置中的插件实例 | | htmlWebpackPlugin | object | {} | html-webpack-plugin 的配置 | | htmlWebpackTagsPlugin | object | {} | html-webpack-tags-plugin 的配置 | | copyWebpackPluginPatterns | Array | [] | copy-webpack-pluginpatterns |

常见示例:

const path = require("path");
const webpack = require("webpack");

module.exports = {
  webpack: {
    entry: {
      app: "./src/main.js",
    },
    library: "navbar",
    publicPath: "/navbar/",
    isExtractCss: true,
    styleResourcesLoaderPatterns: ["./src/styles/variables.less"],
    copyWebpackPluginPatterns: [
      {
        from: path.resolve(__dirname, "src/static"),
        to: path.resolve(__dirname, "dist/static"),
      },
    ],
    htmlWebpackPlugin: {
      title: "Navim Demo",
    },
    htmlWebpackTagsPlugin: {
      tags: ["https://example.com/runtime.js"],
      append: false,
    },
    extraPlugins: [
      new webpack.DefinePlugin({
        __BUILD_NAME__: JSON.stringify("navim-demo"),
      }),
    ],
  },
};

webpack 内置行为:

  • 输出目录固定为 dist/
  • 主入口产物固定为 dist/app.js
  • 动态 chunk 输出到 dist/static/js/
  • 图片输出到 dist/static/images/
  • 字体输出到 dist/static/fonts/
  • libraryTarget 固定为 umd
  • 支持 .vue.css.less.styl.js.jsx
  • JS/JSX 使用 Babel
  • 开发态和生产态会按当前实现生成不同的 webpack 配置
  • common.output.library.*common.styles.extractcommon.assets.copy 等字段目前不会直接驱动 webpack 运行时

vite 配置

vite 现在同时支持开发和构建。

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | entry | string | 自动从 common.entry 兜底 | HTML 入口文件 | | rootElementId | string | app | HTML loading 插件替换的根节点 id | | optimizeDeps | object | include @heisea/brick / exclude vue-router, vuex | Vite 预构建配置 | | staticCopyTargets | Array | 内置主题 CSS 和 element-ui 字体 | 复制静态资源 | | plugins | Array | [] | 额外 Vite 插件 |

内置行为:

  • configFile=false,不会读取项目自己的 vite.config.*
  • 使用 @vitejs/plugin-vue2@vitejs/plugin-vue2-jsx
  • 代理配置来自 build/config.js
  • common.output.publicPath 会映射到 Vite 的 base
  • common.output.outDir 会映射到 Vite 的 build.outDir
  • common.resolve.aliascommon.resolve.extensions 会参与 Vite 解析
  • common.styles.resources 会通过 Less hack 注入
  • 会默认复制 @heisea/brick 的主题 CSS 和 element-ui 字体文件

示例:

module.exports = {
  vite: {
    entry: "./src/main.js",
    rootElementId: "app",
    optimizeDeps: {
      include: ["@heisea/brick"],
      exclude: ["vue-router", "vuex"],
    },
  },
};

rsbuild 配置

rsbuild 也已经接入统一 schema,并支持 devbuildanalyze 三条路径。

| 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | plugins | Array | [] | 额外 Rsbuild 插件 | | tools | object | {} | Rsbuild tools 合并配置 | | config | object | {} | 最终运行时配置覆盖 |

内置行为:

  • common.entry 会映射到 source.entry
  • common.output.publicPath 会映射到 output.assetPrefix
  • common.output.outDir 会映射到 output.distPath.root
  • common.dev.hostcommon.dev.portcommon.dev.opencommon.dev.headers 会映射到 server
  • common.resolve.aliascommon.resolve.extensions 会参与解析
  • common.styles.resources 会通过 Less hack 注入
  • common.assets.copy 会映射到 output.copy
  • common.externals.dev / common.externals.micro 会按当前命令和微前端状态切换
  • 默认会尝试加载 @rsbuild/plugin-vue2

依赖要求:

  • rsbuild 支持依赖 @rsbuild/core
  • Vue 2 场景下建议同时安装 @rsbuild/plugin-vue2
  • 使用 Vue 2 + Rsbuild 时,项目本身还需要安装与 vue 版本匹配的 vue-template-compiler
  • 如果你裁剪了依赖,缺少上述包时会直接报错

示例:

module.exports = {
  common: {
    entry: {
      app: "./src/main.js",
    },
    output: {
      publicPath: "/demo/",
      outDir: "dist",
    },
  },
  rsbuild: {
    tools: {
      less: {
        loaderOptions: {
          lessOptions: {
            javascriptEnabled: true,
          },
        },
      },
    },
  },
};

single-spa doctor

single-spa doctor 仍然是 webpack / legacy 配置链路下的升级工具,不属于三引擎统一能力。

执行边界:

  • 项目依赖中必须已经包含 single-spa-vue
  • 当前只支持单入口项目;如果 webpack.entry 中存在多个入口,会直接退出
  • 入口来源仍然是 legacy webpack.entry
  • 如果项目中还没有 single-spa-css,命令会尝试执行 pnpm add single-spa-css@^2.0.0
  • 命令会改写入口文件源码,补入 single-spa-css 相关逻辑
  • 已经升级过的入口文件再次执行会直接退出
  • vitersbuild 当前没有对应的 doctor 流程

环境变量加载规则

Navim 通过 dotenv + dotenv-expand 加载环境变量。

加载优先级从高到低如下:

  1. .env.[NODE_ENV].local
  2. .env.[mode]
  3. .env.[NODE_ENV]
  4. .env.local
  5. .env

说明:

  • NODE_ENV 由 Navim 命令自身设置
  • mode 来自 --mode <type>
  • 同名变量以高优先级文件中的值为准

开发服务相关变量:

  • PORT:开发服务端口
  • HOST:开发服务 host

webpack 构建时会通过 DefinePlugin 注入:

  • process.env.NODE_ENV
  • process.env.navim_hash
  • 所有以 NAVIM_ 开头的变量,例如 NAVIM_API_BASE

示例:

PORT=9000
HOST=127.0.0.1
NAVIM_API_BASE=/api

业务代码中可直接读取:

console.log(process.env.NODE_ENV);
console.log(process.env.navim_hash);
console.log(process.env.NAVIM_API_BASE);

兼容性说明

  • 旧项目可以继续使用顶层 webpack / vite / rsbuild 配置
  • 新项目建议优先使用 common + 引擎覆盖的写法,但如果仍要跑 webpack,请保留 legacy webpack 字段
  • startvite startanalyzersingle-spa doctor 都保留为兼容入口
  • inspect 是当前用于查看翻译后运行时配置的推荐命令

常见注意事项

  • navim.config.js 必须位于项目根目录
  • build/config.js 必须存在;如果没有代理需求,也请导出空对象
  • public/index.html 必须存在
  • vitersbuild 都已经支持构建,不再只是开发服务
  • webpack 当前仍然依赖 legacy webpack 配置,不是完全由 common 驱动
  • single-spa doctor 会改写源码,执行前建议先提交或备份
  • single-spa doctor 只支持使用 single-spa-vue 的单入口 webpack 项目
  • 如果你在微前端场景中抽离了 CSS,构建完成后 Navim 会提示你接入 single-spa-css
  • 建议将 Navim 作为本地依赖安装,不建议只全局安装 CLI