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

@jasw/galaxy-mf

v0.1.0

Published

Module Federation dependency resolution, Result helpers and bundle analysis utilities.

Readme

@jasw/galaxy-mf

@jasw/galaxy-mf 提供一组与 React 解耦、可复用于微前端运行时和构建流程的基础能力:

  • 用 Result<T, E> 表达可预期的失败,减少远程加载流程中的异常分支;
  • 按 semver 判断 Host 能否安全共享依赖,并为版本冲突提供明确的隔离信号;
  • 在 Webpack 或 Vite/Rollup 构建结束后统计第三方依赖体积和重复情况。

该包不依赖 React,也不负责远程应用渲染;其职责是处理 Module Federation 接入过程中的版本协商、错误建模和构建统计。

维护者:jasw · 许可证:MIT

安装

pnpm add @jasw/galaxy-mf

也可以使用 npm:

npm install @jasw/galaxy-mf

包内置 TypeScript 类型声明,同时提供 ESM 和 CommonJS 产物。Node.js、Webpack 配置以及 Vite 项目都可以直接使用。

// ESM:从主入口按需导入
import { ok, resolveSharedDependency } from '@jasw/galaxy-mf';

// ESM:通过子路径明确导入某一组能力
import { mapResult, type Result } from '@jasw/galaxy-mf/result';
import { BuildAnalyzerPlugin } from '@jasw/galaxy-mf/build-analyzer';
// CommonJS
const { BuildAnalyzerPlugin } = require('@jasw/galaxy-mf');

目前公开的子路径如下:

| 子路径 | 内容 | | ----------------------------------- | --------------------------------- | | @jasw/galaxy-mf/result | Result 类型及组合函数 | | @jasw/galaxy-mf/shared-dependency | 共享依赖的 semver 判断和错误类型 | | @jasw/galaxy-mf/build-analyzer | Webpack、Vite/Rollup 构建分析能力 |

Result:显式处理可预期的失败

Result<T, E> 只有成功和失败两个分支。检查 ok 后,TypeScript 会自动收窄到 value 或 error,不需要类型断言。

import { err, mapResult, ok, type Result } from '@jasw/galaxy-mf/result';

class ParsePortError extends Error {
  override readonly name = 'ParsePortError';
}

function parsePort(input: string): Result<number, ParsePortError> {
  const port = Number(input);

  return Number.isInteger(port) && port > 0
    ? ok(port)
    : err(new ParsePortError(`端口无效:${input}`));
}

const endpoint = mapResult(parsePort('3000'), (port) => `http://localhost:${port}`);

if (endpoint.ok) {
  console.log(endpoint.value);
} else {
  console.error(endpoint.error.message);
}

常用组合函数:

  • mapResult:转换成功值,失败分支原样向后传递;
  • mapError:给底层错误补充业务上下文;
  • andThen:成功后继续下一步返回 Result 的计算;
  • isOk / isErr:在过滤、守卫或测试代码中收窄类型;
  • fromThrowable:把同步异常转换成 Result;
  • fromPromise:把 Promise rejection 转换成 Result。

异步取消仍由实际发起请求的一层负责。fromPromise 只封装结果,不负责创建或触发 AbortController:

import { fromPromise } from '@jasw/galaxy-mf/result';

const controller = new AbortController();

const response = await fromPromise(() =>
  fetch('/remote-manifest.json', { signal: controller.signal }),
);

// 页面卸载或路由切换时调用
controller.abort();

如果业务需要区分超时、取消和网络错误,建议给 fromPromise 传入错误转换函数,统一成自己的领域错误,而不是直接判断错误文案。

共享依赖版本判断

Module Federation 的 singleton 只能保证共享作用域里尽量只有一个实例,不能让互不兼容的版本变得兼容。尤其是 React,强行让旧版 Remote 使用新版 Host 的运行时,很容易出现 hooks 或 context 错误。

resolveSharedDependency 用完整 Host 版本和 Remote 要求的 semver 范围做判断:

import {
  resolveSharedDependencyResult,
  type SharedDependencyPolicy,
} from '@jasw/galaxy-mf/shared-dependency';

const policy: SharedDependencyPolicy = {
  name: 'react',
  hostVersion: '19.0.0',
  requiredRange: '^18.0.0',
  fallback: 'isolated',
};

const resolution = resolveSharedDependencyResult(policy);

if (!resolution.ok) {
  // React 19 不满足 ^18.0.0,加载器应改用 Remote 自己的 React 运行时。
  console.warn(resolution.error.code, resolution.error.message);
}

这里提供了三种调用方式:

  • resolveSharedDependency:兼容时返回 { mode: 'shared' },配置非法或版本不匹配时抛出具体错误;
  • resolveSharedDependencyResult:把上述错误包装为 Result,适合放进远程加载流水线;
  • resolveSharedDependencyWithFallback:版本不匹配时直接返回 { mode: 'isolated' },但配置非法时仍会抛错。

可识别的错误包括:

| 错误 | code | 含义 | | ------------------------------------ | ------------------------------------ | ---------------------------------------- | | InvalidSemverError | INVALID_SEMVER | Host 版本或 Remote 范围不是有效 semver | | SharedDependencyVersionError | SHARED_DEPENDENCY_VERSION_MISMATCH | 版本合法,但 Host 版本不满足 Remote 范围 | | InvalidSharedDependencyPolicyError | INVALID_SHARED_DEPENDENCY_POLICY | 依赖名为空或降级策略不受支持 |

判断内部使用 semver.valid、semver.validRange 和 semver.satisfies,时间复杂度约为版本与范围字符串总长度的 O(n)。建议使用完整版本号,例如 19.0.0,不要把 19 或 latest 当作 hostVersion。

BuildAnalyzerPlugin:查看依赖体积和重复打包

该插件用于分析第三方依赖在各个 chunk 中的分布。它不会修改分包策略,也不会因为统计信息不完整而阻断构建。

Webpack

const { BuildAnalyzerPlugin } = require('@jasw/galaxy-mf');

module.exports = {
  plugins: [new BuildAnalyzerPlugin({ app: 'checkout-remote' })],
};

插件通过 compiler.hooks.done 读取 Webpack stats,所以应放在普通 plugins 数组中,不需要额外调用。

Vite / Rollup

import { defineConfig } from 'vite';
import { BuildAnalyzerPlugin } from '@jasw/galaxy-mf/build-analyzer';

export default defineConfig({
  plugins: [new BuildAnalyzerPlugin({ app: 'shared-utils' }).asRollupPlugin()],
});

Vite/Rollup 需要使用 asRollupPlugin()。这个适配器只暴露 Rollup 所需的 hook,避免构建工具误处理 Webpack 专用的 apply 方法。

构建结束后会通过 console.table 输出:

| 字段 | 含义 | | ------------ | -------------------------------------------------- | | app | 创建插件时传入的应用名 | | dependency | 从 node_modules 或 pnpm .pnpm 路径解析出的包名 | | bytes | 该依赖在统计数据中的累计字节数 | | percentage | 占当前应用全部第三方依赖体积的比例 | | chunks | 依赖出现过的 chunk | | duplicate | 同一依赖是否出现在多个 chunk 中 |

duplicate: true 是排查线索,不一定就是错误。动态路由、Remote 独立运行时或构建工具生成的公共 chunk 都可能让同一包出现在多个位置,仍需要结合实际加载链路判断。

聚合 M 个模块、P 个第三方包的复杂度为 O(M + P),输出前的稳定排序额外需要 O(P log P)。

在仓库中开发

源码和测试分别位于:

packages/shared-utils/src/
packages/shared-utils/tests/

在仓库根目录执行:

# 构建 ESM、CJS 和类型声明
pnpm --filter @jasw/galaxy-mf build

# 运行测试并检查覆盖率
pnpm --filter @jasw/galaxy-mf test:coverage

# 查看实际会进入 npm 包的文件
pnpm --filter @jasw/galaxy-mf pack --dry-run

pack 会先重新构建,并用 TypeScript 的 NodeNext 模式检查生成的声明文件,避免发布后才发现 ESM 相对导入不兼容。

改动公共 API 时,请同步检查根入口和对应子路径的导出,并补充测试。这个包刻意不绑定 React 或具体的 Federation 容器实现,新增能力也会优先维持这一边界。

维护

该包由 jasw 维护。完整的 React 19 Host、React 18/17 Remote、隔离挂载和预加载示例见项目仓库。维护者发布新版本时应遵循仓库中的 RELEASING.md。