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

@lhx-kit/offline

v1.1.0

Published

Offline packaging pipeline: whitelist filter, sha256 manifest, AdmZip packer, HTML CDN URL strip, and inspect tools.

Readme

@lhx-kit/offline

📦 为 Hybrid App WebView 容器生成离线包。 产出 manifest.json + .zip,跟随 App 发布;页面零延迟从本地磁盘加载。

npm license English


安装

pnpm add -D @lhx-kit/offline

通常你不会直接 import——由 @lhx-kit/clilhx-cli offline build 调用。


快速使用

通过 CLI(推荐)

lhx-cli offline build --hybrid-type=test

编程式

import {buildOfflinePackage, normalizeOfflineConfig} from '@lhx-kit/offline';

const config = normalizeOfflineConfig({
  packageName: 'my-app',
  version: '1.0.0',
  pages: [
    {name: 'home', route: '/', file: 'index.html'}
  ]
});

const result = await buildOfflinePackage({
  projectRoot: process.cwd(),
  config,
  zip: true
});

console.log(result.zipPath);         // → dist-offline/my-app-1.0.0.zip
console.log(result.manifestPath);    // → dist-offline/manifest.json
console.log(result.validation.valid); // → true

产物布局

dist-offline/
├── manifest.json              # 容器入口:页面清单 + 文件 hash + 回滚策略
├── files/                     # WebView 实际加载的目录
│   ├── home/
│   │   ├── index.html         # CDN URL 已清空
│   │   └── assets/…
│   └── shared/
│       └── assets/…
└── my-app-1.0.0.zip           # 一步打好的包

算法

  1. 🔍 递归遍历 dist/
  2. 🚫 通过 buildOfflineFileFilter 过滤:
    • 白名单 page 目录 + shared 目录 + 顶层文件 → 包含
    • 其他 → 排除
  3. 🔐 对每个文件做 SHA-256(流式,内存恒定)
  4. 📝 生成 manifest.jsonschemaVersion: '1.0.0'
  5. 📂 拷贝到 files/(不用软链——容器沙盒需要真实文件)
  6. 🌐 重写每个 HTML 的 CDN URL,让离线 WebView 不发网络
  7. 🗜️ 用 adm-zip 打包(纯 JS,无 native binding)

完整流程见 离线打包概览


关键特性

🛡️ 文件级 SHA-256

manifest.json 里每个资源:

{
  "path": "home/index.html",
  "size": 676,
  "hash": "ab12cd34…",
  "contentType": "text/html"
}

容器下载完包后根据 hash 校验,防止传输损坏。

🌐 HTML CDN URL 清空

如果构建用了 @lhx-kit/vite-plugin 的 CDN 功能,HTML 里会包含:

<!-- lhx-kit: CDN loader -->
<script>var plan = {entries:[{urls:["https://cdn.jsdelivr.net/…"]}]}; …</script>
<!-- /lhx-kit: CDN loader -->

离线 builder 会重写为:

<!-- lhx-kit: CDN loader -->
<script>var plan = {entries:[{urls:[]}]}; …</script>
<!-- /lhx-kit: CDN loader -->

空的 urls 数组让 loader 跳过 DNS 查询,直接走 loadLocalFallback零网络请求,避免每个 URL 5 秒超时。

📋 白名单过滤规则

defineOfflineConfig({
  whitelistPages: ['home'],                     // 仅此 page 进包
  excludeFilenames: ['mockServiceWorker.js'],   // MSW 永不随包发布
  excludePaths: ['analytics/'],                 // 自定义前缀排除
});

规则:

| 路径形状 | 判定 | | --- | --- | | shared/... | ✅ 总是包含(vendor chunk) | | <白名单-page>/... | ✅ 包含 | | <其他-page>/... | ❌ 排除(避免混合) | | 顶层文件(favicon 等) | ✅ 包含,除非显式 exclude |


公开 API

| 导出 | 用途 | | --- | --- | | OfflineConfigSchema | 配置的 zod schema | | normalizeOfflineConfig(input) | parse + 填默认值 | | generateOfflineManifest(config, buildDir) | 返回 manifest 对象 | | writeOfflineManifest(manifest, outDir) | 持久化到磁盘 | | buildOfflinePackage(opts) | 端到端:manifest + copy + zip | | inspectOfflinePackage(outDir) | 校验已有包 | | formatBytes(bytes) | 字节数格式化 |


依赖

| 依赖 | 用途 | | --- | --- | | adm-zip ^0.5.16 | 纯 JS zip,无 native binding(Docker 友好) | | fs-extra ^11.2.0 | readdir {withFileTypes} 等便利 API | | zod ^3.24.1 | 配置校验 |


什么时候用

✅ 适合:

  • 移动端 Hybrid App(淘宝 / 京东 / 各家银行 / 美团风格容器)
  • 严格审计要求(每次发版一个不可变 zip)
  • 弱网 / 完全离线场景

❌ 不适合:

  • 纯 Web 站点——浏览器缓存 + CDN 足够
  • PWA——用 Service Worker 即可
  • Electron / Tauri——有自己的打包器

文档

License

MIT © luhanxin


📦 安装

npm install @lhx-kit/offline
# 或
pnpm add @lhx-kit/offline

npm provenance

📖 文档与延伸阅读

🤝 参与贡献

欢迎 PR!请阅读 CONTRIBUTING.md,用户可见变更请用 pnpm changeset 声明。新手友好 label:good first issue / help wanted

📄 License

MIT © luhanxin

属于 @lhx-kit monorepo。每次发布都经过 npm Trusted Publishing(OIDC)签名——可在 npm 包页面验证 provenance 证明。