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

hbx-env-pack-inject

v1.0.0

Published

hbx-env-pack 的构建侧:按 env-pack.json 的 mode 加载对应 .env,再 DefinePlugin 注入 process.env。HBuilderX 打 App 包和 vue-cli 构建都适用。

Downloads

141

Readme

hbx-env-pack-inject

构建期环境变量注入。按项目根 env-pack.jsonmode 找到对应环境变量文件, 解析后通过 DefinePlugin 注入 process.env,代码里直接写 process.env.VUE_APP_XXX

为什么单独一个包:这段逻辑以前住在每个项目的 vue.config.js 里,换个项目就得 再复制一遍。现在只有这一份。


为什么必须有 vue.config.js,且只能留一行

HBuilderX 编译 App 时写死了唯一一个 webpack 配置入口:

// <HBuilderX>/plugins/uniapp-cli/bin/uniapp-cli.js
const vueConfigJsPath = path.resolve(process.env.UNI_INPUT_DIR, 'vue.config.js')
if (fs.existsSync(vueConfigJsPath)) {
    process.env.VUE_CLI_SERVICE_CONFIG_PATH = vueConfigJsPath
}

HBuilderX 插件没有任何构建期扩展点(contributes 里只有 commands / menus / launchers / configuration 这些,没有构建钩子),所以 <项目根>/vue.config.js 这个文件躲不掉 —— 但它的内容可以只剩一行,逻辑放在本包里。


用法

项目里加依赖,然后把 vue.config.js 包在 withEnvInject() 外面

{
  "dependencies": {
    "hbx-env-pack-inject": "file:../install-App/packages/hbx-env-pack-inject"
  }
}
// vue.config.js —— 它仍然是项目自己的配置文件,只是外面包了一层
const { withEnvInject } = require('hbx-env-pack-inject')

module.exports = withEnvInject({
  // 项目自己的 vue-cli 配置照常写在这里,跟本包互不干扰
  devServer: { port: 8080 },
  chainWebpack(config) { /* ... */ }
})

为什么不让项目直接 module.exports = require('hbx-env-pack-inject')vue.config.js 是项目自己的配置文件,直接整个导出本包等于把它占掉了, 以后想加 devServer、加自己的 chainWebpack 就没地方写。所以主 API 是 withEnvInject(userOptions),把注入挂到你那份配置上。

项目还要有:

| 文件 | 作用 | |---|---| | env-pack.json | 环境列表 + 当前环境(mode),要提交。由 HBuilderX 插件 hbx-env-pack 维护 | | .env.<环境> | 各环境的环境变量,只认 VUE_APP_ 前缀 |

改本包的配置(配置文件不叫 env-pack.json、前缀不是 VUE_APP_),第二个参数传进去:

module.exports = withEnvInject(
  { /* 项目自己的配置 */ },
  { configFile: 'env-rc.json', prefix: 'CUSTOM_' }
)

三个导出怎么选

| 导出 | 用在什么时候 | |---|---| | withEnvInject(userOptions?, pluginOptions?) | 默认选它。项目有自己的 vue-cli 配置时 | | chainWebpack | 项目确实没有别的配置,且想省掉那层包装 | | create(pluginOptions) | 只要注入函数本身,chainWebpack 想自己组装 |

顺序

项目自己的 chainWebpack 先跑,注入后跑。因为注入要复用 uni-app 已经注册好的 define 插件(config.plugin('define').tap(...)),先让你那份有机会注册或改写它, 注入再去 tap 才拿得到同一个插件;反过来这里可能自己新挂一个 DefinePlugin, 两个都定义 process.env.X,谁生效就说不清了。

对照 vue-cli 的配置文档

本包只用到 vue.config.js 里两样东西,签名跟文档一致(schema 见 @vue/cli-service/lib/options.js):

// webpack
chainWebpack: joi.func(),
configureWebpack: joi.alternatives().try(joi.object(), joi.func()),

// 3rd party plugin options
pluginOptions: joi.object()

本包提供的就是一个 chainWebpack 函数(chainWebpack: joi.func() 那个), 用 withEnvInject() 包一层只是为了它跟你自己的那份不打架。

vue.config.js 本身也可以是函数,@vue/cli-service/lib/Service.js 里:

fileConfig = require(configPath)
if (typeof fileConfig === 'function') {
  fileConfig = fileConfig()
}

所以本包如果哪天要支持「不传参直接 require」,靠的也是这条,不需要额外机制。

为什么不用 vue-cli 插件那条路vue-cli-plugin-* 包 + pluginOptions 传参, 文档「插件开发」一节的正规做法):HBuilderX 下走不通。Service.jsresolvePlugins 是从它自己所在目录 require 项目声明的插件的,而 HBuilderX 用的是 它自带的那份 @vue/cli-service(在 plugins/uniapp-cli/node_modules 里), 永远解析不到项目的 node_modules。详见下一节。

跨项目复用只有这一条路vue.config.js 就是个普通 Node 模块,require 一个 npm 包 就行 —— 没有别的共享机制(vue-cli 的 presets 是 vue create 的脚手架模板,跟运行时 注入无关)。所以本包就是个普通 npm 包,不是 vue-cli 插件。


两个坑(改这个包之前先读)

包名不能叫 vue-cli-plugin-*

@vue/cli-serviceresolvePlugins 会把项目 package.json 里匹配 /^(@vue[\/\\]|vue-cli-plugin-|@[\w-]+\/vue-cli-plugin-)/ 的依赖自动 require

const projectPlugins = Object.keys(this.pkg.devDependencies || {})
  .concat(Object.keys(this.pkg.dependencies || {}))
  .filter(isPlugin)
  .map(id => idToPlugin(id))          // → { apply: require(id) }

而那个 require 是从 Service.js 自己所在的目录解析的 —— HBuilderX 下是 <HBuilderX>/plugins/uniapp-cli/node_modules/@vue/cli-service/lib/, 解析路径永远走不到项目的 node_modules。真取了那个名字,项目一声明该依赖, HBuilderX 就会在构建最开始抛 MODULE_NOT_FOUND

现在这个名字不会被自动加载,只能由 vue.config.js 显式 require —— 而那是从项目根解析的,正好命中项目的 node_modules

项目根不能再靠 __dirname

这段代码以前住在项目的 vue.config.js 里,__dirname 恰好就是项目根。 搬进 node_modules/ 之后 __dirname 是包自己的目录,照着它找 env-pack.json 会找到 node_modules 里去。现在改用 process.env.UNI_INPUT_DIR || process.cwd()

  • UNI_INPUT_DIR 由 HBuilderX 设置(uniapp-cli.js 进来第一件事就是 path.resolve 它, 所以走 HBuilderX 时一定有值)
  • 脱离 HBuilderX 直接跑 vue-cli-service 时退回 cwd —— 那种情况下命令就是在项目根敲的

依赖没装会怎样

硬报错,不会静默失效:

// @vue/cli-service/lib/Service.js
} catch (e) {
  error(`Error loading ${chalk.bold('vue.config.js')}:`)
  throw e
}

npm install 没跑,构建会直接失败并打出 Error loading vue.config.js。 这比「静默注入 0 个变量、请求打到 undefined/api」好得多。