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

ifs-code-tools

v1.0.11

Published

IFS Code - tools for embedding widgets in third-party platforms

Readme

ifs-code-tools

轻量级 Widget 嵌入工具库,用于在第三方平台加载并渲染由 IFS Code / Mixo 平台生产的 Widget。

支持两种加载方式: 通过 appId(推荐)或 url 加载 Widget,内置资源缓存、超时控制和错误处理。

安装

npm install ifs-code-tools

| 环境要求 | 版本 | | --- | --- | | 浏览器 | 支持 ES2020 的现代浏览器 | | React(宿主页面提供) | 16 / 17 / 18,react 与 react-dom 版本需一致 |

前置条件:宿主页面需提供 React 全局

Widget 产物不自带 React,运行时依赖宿主页面的 UMD 全局 window.React / window.ReactDOM

即使通过 npm 安装本库、业务代码使用的是 npm 版 React,也仍需在页面中通过 <script> 引入一份 React UMD(供 Widget 产物复用,全页面共享同一实例):

<script crossorigin src="https://g.alicdn.com/code/lib/react/18.3.1/umd/react.production.min.js"></script>
<script crossorigin src="https://g.alicdn.com/code/lib/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
  • 缺失时 loadWidget / preloadWidget / WidgetRender 会直接失败并在控制台报错,不会静默加载第二份 React(避免多实例共存导致 hooks / Context / 事件系统错串的隐蔽故障)。
  • 不支持 React 19+:React 19 起官方不再提供 UMD 构建,无法产生 window.React / window.ReactDOM 全局。

快速开始

import { loadWidget } from 'ifs-code-tools';

const instance = await loadWidget({
  appId: 'my-app-id',
  container: '#widget-container',
  props: { theme: 'dark' },
});

instance.update({ theme: 'light' }); // 更新属性
instance.unmount();                  // 卸载

API

loadWidget(options): Promise<WidgetInstance>

加载并挂载 Widget 到指定容器,返回可控制的实例对象。

import { loadWidget } from 'ifs-code-tools';

// 方式一:通过 appId 加载(推荐)
const instance = await loadWidget({
  appId: 'my-app-id',
  container: '#widget-container',
  props: { theme: 'dark' },
});

// 方式二:通过 url 加载(产物压缩包地址)
const instance = await loadWidget({
  url: 'https://cdn.example.com/widgets/my-widget.zip',
  container: document.getElementById('widget-container'),
});

Options (LoadWidgetOptions):

| 参数 | 类型 | 必填 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | appId | string | 二选一 | — | Widget 应用 ID | | url | string | 二选一 | — | Widget 产物压缩包地址 | | platform | 'mixo' \| 'ifs' \| 'external' | 否 | 自动判断 | Widget 所属平台,仅 appId 方式生效(见下方说明) | | container | HTMLElement \| string | 是 | — | 挂载容器(DOM 元素或 CSS 选择器) | | props | WidgetProps | 否 | {} | 传递给 Widget 的属性 | | timeout | number | 否 | 30000 | 加载超时时间(ms) | | onLoad | () => void | 否 | — | 加载成功回调 | | onError | (error: Error) => void | 否 | — | 加载失败回调 |

appIdurl 必须提供其中一个,同时提供时 appId 优先。

关于 urlappId 走完全相同的解析逻辑,区别只在于压缩包地址的来源:

| 入参 | 压缩包地址来源 | 后续处理 | | --- | --- | --- | | appId | 按 platform 请求接口换取 | 下载压缩包,解析包内 widget/index.jswidget/index.csswidget/schema.json | | url | 就是传入的 url | 同上 |

url 不要求 .zip 后缀,发布后的产物链接(包含无扩展名、带签名参数的 OSS 地址)直接传入即可;请确保该地址开启了 CORS。

关于 platform:一键对外的小部件必须传 'external',其余大多数情况不用传。

通过 appId 加载时,库会先请求一个接口换取 Widget 产物地址。三个取值的流程完全一致,只是接口地址不同:

| 传入值 | 请求地址 | | --- | --- | | 'mixo' | https://mixo.alibaba-inc.com/mixo/open/getPublishFileUrlOpen(内网) | | 'ifs' | https://code.iconfont.cn/ifs/open/getPublishFileUrlOpen(外网) | | 'external' | https://code.iconfont.cn/ifs/api/app/getExternalRenderUrl(一键对外) |

一键对外发布的小部件换取地址的接口不同,必须显式指定:

const instance = await loadWidget({
  appId: 'my-app-id',
  platform: 'external',
  container: '#widget-container',
});
// 实际请求:https://code.iconfont.cn/ifs/api/app/getExternalRenderUrl?appId=my-app-id

不传 platform 时会根据当前页面域名在 'mixo' / 'ifs' 之间自动判断,典型需要显式指定的场景:

  • 一键对外的小部件:自动判断不会选到 'external',必须手传
  • 本地开发localhost)加载 Widget:自动判断会走公共接口,如果 Widget 属于 mixo 平台需要传 'mixo'
  • 跳平台加载:页面所在平台与 Widget 所属平台不一致时

注意:'mixo' 对应的是内网地址,仅内网环境可访问;'external' 固定请求正式外网地址。

返回值 (WidgetInstance):

| 方法 | 说明 | | --- | --- | | update(newProps) | 更新 Widget 属性(不会重新加载) | | unmount() | 卸载 Widget 并清理资源 |


preloadWidget(options): Promise<void>

提前加载 Widget 资源到缓存(不挂载),后续调用 loadWidget 时可跳过网络请求,实现秒开。

import { preloadWidget, loadWidget } from 'ifs-code-tools';

// 页面初始化时预加载
preloadWidget({ appId: 'my-app-id' });

// 用户交互时快速挂载(命中缓存,无需等待网络)
const instance = await loadWidget({
  appId: 'my-app-id',
  container: '#container',
});

| 参数 | 类型 | 说明 | | --- | --- | --- | | appId | string | Widget 应用 ID(与 url 二选一) | | url | string | Widget 产物压缩包地址(与 appId 二选一) | | platform | 'mixo' \| 'ifs' \| 'external' | Widget 所属平台,仅 appId 方式生效,同 loadWidget |

预加载失败时静默处理,不会抛出异常。


<WidgetRender /> React 组件

声明式的 React 组件,封装了 Widget 的加载、更新和卸载生命周期。

import { WidgetRender } from 'ifs-code-tools';

function App() {
  return (
    <WidgetRender
      appId="my-app-id"
      widgetProps={{ theme: 'dark' }}
      loading={<div>加载中...</div>}
      fallback={(error) => <div>加载失败: {error.message}</div>}
      onLoad={() => console.log('Widget 已加载')}
      onError={(err) => console.error(err)}
    />
  );
}

Props (WidgetRenderProps):

| 参数 | 类型 | 必填 | 默认值 | 说明 | | --- | --- | --- | --- | --- | | appId | string | 二选一 | — | Widget 应用 ID | | url | string | 二选一 | — | Widget 产物压缩包地址,同 loadWidget | | platform | 'mixo' \| 'ifs' \| 'external' | 否 | 自动判断 | Widget 所属平台,仅 appId 方式生效,同 loadWidget | | widgetProps | WidgetProps | 否 | {} | 传递给 Widget 的属性 | | timeout | number | 否 | 30000 | 加载超时时间(ms) | | className | string | 否 | — | 容器 CSS 类名 | | style | React.CSSProperties | 否 | — | 容器内联样式 | | loading | ReactNode | 否 | — | 加载中占位内容 | | fallback | ReactNode \| ((error: Error) => ReactNode) | 否 | — | 加载失败兜底内容 | | onLoad | () => void | 否 | — | 加载成功回调 | | onError | (error: Error) => void | 否 | — | 加载失败回调 |

组件行为:

  • url / appId / platform 变化时自动卸载旧实例并重新加载
  • widgetProps 变化时通过 instance.update() 增量更新,不触发重新加载
  • 组件卸载时自动清理 Widget 实例

TypeScript 支持

本库使用 TypeScript 编写,开箱即用地提供完整类型定义,支持类型检查和 IDE 智能提示。

核心类型导出:WidgetPropsWidgetInstanceLoadWidgetOptionsWidgetPlatform

License

MIT