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

@forward-widget/rslib-plugin

v2.1.0

Published

[![NPM Version](https://img.shields.io/npm/v/@forward-widget/rslib-plugin)](https://www.npmjs.com/package/@forward-widget/rslib-plugin) ![NPM License](https://img.shields.io/npm/l/@forward-widget/rslib-plugin)

Readme

@forward-widget/rslib-plugin

NPM Version NPM License

Forward Widget 专用的 Rslib 构建插件

🚀 简介

@forward-widget/rslib-plugin 是一个专为 Forward Widget 开发优化的 Rslib 插件。它提供了以下核心功能:

  • 🔧 自动类型生成:根据 WidgetMetadata 自动生成 TypeScript 类型定义
  • 📦 构建优化:清除 Forward Widget 不支持的导出声明
  • 🛠️ 开发体验:提供完整的类型支持和智能提示
  • 🔄 热更新:开发模式下自动重新生成类型定义

📦 安装

npm install -D @forward-widget/rslib-plugin
# 或
yarn add -D @forward-widget/rslib-plugin
# 或
pnpm add -D @forward-widget/rslib-plugin

🛠️ 使用方法

基础配置

在你的 rslib.config.ts 文件中添加插件:

import { pluginForwardWidget } from '@forward-widget/rslib-plugin';
import { defineConfig } from '@rslib/core';

export default defineConfig({
  plugins: [pluginForwardWidget()],
  lib: [
    {
      format: 'esm',
      syntax: ['node 18'],
      dts: true,
    },
  ],
});

自定义配置

import { pluginForwardWidget } from '@forward-widget/rslib-plugin';
import { defineConfig } from '@rslib/core';

export default defineConfig({
  plugins: [
    pluginForwardWidget({
      typesFilePath: 'src/custom-types.d.ts', // 自定义类型文件路径
    }),
  ],
  lib: [
    {
      format: 'esm',
      syntax: ['node 18'],
      dts: true,
    },
  ],
});

📋 配置选项

| 选项 | 类型 | 默认值 | 描述 | |------|------|--------|------| | typesFilePath | string | 'src/forward-widget-env.d.ts' | 生成的类型定义文件路径 |

💡 工作原理

1. 解析 WidgetMetadata

插件会解析你的代码中的 WidgetMetadata 对象:

// src/index.ts
WidgetMetadata = {
  id: 'my-widget',
  title: 'My Widget',
  modules: [
    {
      id: 'search-module',
      title: 'Search Module',
      functionName: 'searchContent',
      description: 'Search for content',
      params: [
        {
          name: 'query',
          title: 'Search Query',
          type: 'input',
        },
        {
          name: 'category',
          title: 'Category',
          type: 'enumeration',
          enumOptions: [
            { title: 'Movies', value: 'movies' },
            { title: 'TV Shows', value: 'tvshows' },
          ],
        },
      ],
    },
  ],
};

2. 生成类型定义

插件会根据 WidgetMetadata 自动生成相应的类型定义:

// src/forward-widget-env.d.ts
/// <reference types='@forward-widget/libs/env' />

//#region search-module
/**
 * Params of Search Module
 */
interface SearchContentParams {
  /**
   * Search Query
   */
  query: string;
  /**
   * Category
   */
  category: 'movies' | 'tvshows';
}

/**
 * Search Module
 * @description Search for content
 * @param {SearchContentParams} params
 * @returns {Promise<VideoItem[]>}
 */
function searchContent(params: SearchContentParams): Promise<VideoItem[]>;

/**
 * Search Module
 */
type SearchContentType = typeof searchContent;
//#endregion search-module

3. 清除导出声明

插件会自动清除构建输出中的导出声明,因为 Forward Widget 不支持脚本有导出声明。

📚 完整示例

项目结构

my-widget/
├── src/
│   ├── index.ts                    # 主要逻辑
│   └── forward-widget-env.d.ts     # 自动生成的类型定义
├── rslib.config.ts                 # 构建配置
├── package.json
└── tsconfig.json

源代码示例

// src/index.ts
WidgetMetadata = {
  id: 'movie-search',
  title: '电影搜索',
  modules: [
    {
      id: 'search',
      title: '搜索电影',
      functionName: 'searchMovies',
      description: '根据关键词搜索电影',
      params: [
        {
          name: 'keyword',
          title: '关键词',
          type: 'input',
        },
        {
          name: 'year',
          title: '年份',
          type: 'input',
        },
        {
          name: 'genre',
          title: '类型',
          type: 'enumeration',
          enumOptions: [
            { title: '动作', value: 'action' },
            { title: '喜剧', value: 'comedy' },
            { title: '剧情', value: 'drama' },
          ],
        },
      ],
    },
  ],
};

// 实现搜索函数
async function searchMovies(params: SearchMoviesParams): Promise<VideoItem[]> {
  const { keyword, year, genre } = params;
  
  // 使用 Widget API 进行搜索
  const response = await Widget.http.get('https://api.example.com/search', {
    params: { q: keyword, year, genre },
  });
  
  return response.data.map(item => ({
    id: item.id,
    title: item.title,
    year: item.year,
    // ... 其他字段
  }));
}

生成的类型定义

// src/forward-widget-env.d.ts (自动生成)
/// <reference types='@forward-widget/libs/env' />

//#region search
/**
 * Params of 搜索电影
 */
interface SearchMoviesParams {
  /**
   * 关键词
   */
  keyword: string;
  /**
   * 年份
   */
  year: string;
  /**
   * 类型
   */
  genre: 'action' | 'comedy' | 'drama';
}

/**
 * 搜索电影
 * @description 根据关键词搜索电影
 * @param {SearchMoviesParams} params
 * @returns {Promise<VideoItem[]>}
 */
function searchMovies(params: SearchMoviesParams): Promise<VideoItem[]>;

/**
 * 搜索电影
 */
type SearchMoviesType = typeof searchMovies;
//#endregion search

🎯 支持的参数类型

插件支持以下参数类型的自动类型生成:

| 参数类型 | 描述 | 生成的 TypeScript 类型 | |----------|------|----------------------| | input | 输入框 | string | | enumeration | 枚举选择 | 'option1' \| 'option2' \| ... | | constant | 常量值 | 'constantValue' |

🔧 开发模式

在开发模式下,插件会监听文件变化并自动重新生成类型定义:

# 启动开发模式
npm run dev
# 或
pnpm dev

🤝 最佳实践

  1. 保持 WidgetMetadata 结构清晰:确保每个模块都有明确的 ID 和功能定义
  2. 使用描述性的函数名:函数名应该清晰地表达其功能
  3. 提供完整的参数描述:为每个参数提供有意义的标题和描述
  4. 合理组织模块:将相关功能组织在一起,避免模块过于复杂

📚 相关文档

🤝 贡献

欢迎提交 Issue 和 Pull Request 来改善这个项目。

📄 许可证

MIT License