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

fedom

v1.0.23

Published

fe dom solution: 灵活简洁易用的前端框架

Readme

fedom: 前端DOM渲染方案

安装&使用:

$ npm i fedom -S // 安装fedom 

// 配置webpack 的 module.rules 选项, 解析.js文件
{
  test: /\.js$/,
  exclude: /node_modules/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: ['@babel/preset-env',],
      plugins: [
        // ... // 其他配置 
        
        ...require("fedom/babel_config_plugins.js"), // 支持 jsx 编译 
      ],
    }
  }
}

import "fedom";  // 引入fedom 

API:

const {
  // 渲染方法 
  render, 
  
  // 组件&生命周期 
  onMounted, // 渲染后 
  onUnmount, // 卸载前 
  onReused,  // 使用缓存后 
  Component, // 类组件 
  
  // model&view 
  VaryValue, // 单个动态值 
  VaryList, // 动态列表
  VaryMap, // 动态所有键值 
  
  // 路由 
  Router, 
  DecorateSync, // 同步路由函数组件修饰器 
  DecorateSyncMore, // 同步路由函数组件默认配置修饰 
  DecorateAsync, // 懒加载路由函数组件修饰器 
  DecorateAsyncMore, // 懒加载路由函数组件默认配置修饰 
  
  // 其他工具 
  Promising, // 进行中的Promise
  utils, // 工具集合对象 
} = window.$fd;

功能列表:

1 JSX模板渲染

render 渲染方法 
  支持渲染 VaryValue(动态值) / Array(列表) / Promise(异步渲染) / fdNode(jsx) / Node(原生dom节点) / text(其他任意作为文本渲染)
  
  // 如渲染 fdNode 
  render(
    <div>JSX内容渲染</div>, 
    document.getElementById("#app")
  )
ref 
  ref={<Promising>} Promise异步执行 
    let refVal = Promising();
    refVal.then((node)=>{
      console.log(node); // 若绑定在组件根节点,则为组件context 
    })
    
    // 该节点渲染完毕后, refVal 将 resolved 
    <div ref={refVal}>aaa</div>
    
  ref={callback} 回调函数形式 

2 视图的渲染&动态更新: model<->view

数据模型 
  VaryValue 动态值,动态更新视图  
    let vv = VaryValue(val, trimFn);
      trimFn 默认为: val=>val; // 无格式化 
    初始渲染通知 
      vv.mounted(()>{
        // vv在视图中被渲染后调用 
      }) 
    更新视图  
      vv.set((originVal, trimedVal)=>{
        return '设置的值'
      }) 
    model取值 
      vv.get(true) 
      vv.get(false) 
      vv.$$ 
    动态化监听 
      vv.watch((nextVal, prevVal, trimedNextVal, trimedPrevVal)=>{
        // vv被设置值时调用 
      }) 
    动态化开关 
      vv.on()   关闭动态响应 
      vv.off()  开启动态响应 
      vv.kill() kill掉vv, 不可逆操作 
    动态值依赖 
      let vv1 = VaryValue.depend([vv], (lst)=>{
        return '-' + lst[0]
      }) 
  VaryList  动态列表,优化列表渲染, 继承自VaryValue 
    let vl = VaryList(listVal, trimFn);
    提供各种列表的更新方法 
    vl.$insert(id, list)  // 指定位置开始插入若干项 
    vl.$remove(id, len)   // 指定位置开始删除指定个数项 
    vl.$update(id, val)   // 更新指定项为指定的值
    vl.$slice(id1, id2)   // 返回指定范围内的项 
    vl.$unshift(val1, val2, ...)
    vl.$push(val1, val2, ...)
    vl.$shift()
    vl.$pop()
    vl.$map(()=>{ })
    vl.$set(list)  // 全量更新 
  VaryMap   动态值集合 
    let vm = VaryMap(mapVal, trimFn)
    vm.$insert(key, val)
    vm.$update(key, val)
    vm.$get() 
    vm.$set(()=>{ return newMapVal })
    vm.$each(()=>{})
    vm.$remove(key1)
    vm.key2   map中的指定key对应的VaryValue值 
动态内容类型 
  vary组件
  vary标签 
  vary属性 
    额外提供两个便捷控制属性 
      fd_if={VaryValue(bol)} 
      fd_show={VaryValue(bol)}
  vary子节点
    整个数组 
    单个子节点 
    文本内容 

3 组件化

class组件 
  class Cpnt extends Component {
    constructor(props){
      super(props)
    }
    
    onMounted(elem){
      console.log('渲染完毕');
    }
    onUnmount(){
      console.log('组件卸载');
    }
    onReused(elem){
      console.log('组件缓存');
    }
    
    render(){
      
      return (
        <section>

        </section>
      )
    };
  }
function组件 (推荐使用函数组件代替类组件) 
  function Cpnt(props, context){
    context.onMounted = (elem)=>{
      console.log('渲染完毕');
    }
    context.onUnmount = (elem)=>{
      console.log('组件卸载');
    }
    context.onReused = ()=>{
      console.log('组件缓存');
    }
    
    return (
      <section>

      </section>
    );
  } 
类hook的生命周期: 该使用方式,可逻辑抽离管理 
  onMounted(ctx, ()=>{})  // 渲染完毕后 
  onUnmount(ctx, ()=>{})  // 卸载前 
  onReused(ctx, ()=>{})   // 缓存页面重载 
组件通信 
  <VaryValue>.watch()  // 监听属性的动态值变化 
  <component>.xxx(val) // 子组件的方法被调用 
组件状态共享/多组件通信 
  使用集中的动态值导出, 在需要的地方引入, 即可进行状态共享,视图更新 
  // store.js 
  export const statusA = VaryValue(1);
  
  // 组件A 引入, 可更新和使用  
  import { statusA } from '../store.js';
  
  // 更新
  statusA.set((val)=>{
    return val+1;
  })
  
  // 使用(渲染结果) 
  <div>{ statusA }</div> 
css命名空间: fedom框架标识了组件内的所有节点 
  配合loader使用: @justfn/css-scope-loader 

4 路由 Router

// 静态方法 
Router.push(hashPath, hashQuey) // 路由跳转
Router.replace(hashPath, hashQuey) // 路由跳转(不保留当前记录)
Router.forward()  // 前进一步  
Router.back()  // 后退一步  
Router.go(num) // 前进/后退num步  
Router.parseURL(url)  // 解析指定url,url默认为:location.href 
const router = Route({
  routes: [
    {
      path: '/',
      // 路由懒加载 
      component: (preRoute, newRoute)=>import('../pages/homePage.js')
      // 注意非懒加载也需使用函数返回的形式: 可额外为页面组件提供路由参数  
      // component: (preRoute, newRoute)=>homePage, 
      alias: '/home', // 
      isCache: true,  // bol,是否缓存, 默认: false 
      // 其他额外可自定义放置的参数 
      extra: {
        title: '首页',
      },
      // 子路由 
      children: [
        {
          path: 'pageA', // 简化逻辑, 不区分 '/pageA' 或 'pageA' 
          component: (preRoute, newRoute)=>import('../pages/pageA.js')
          extra: {
            title: '页面A',
          },
        },
      ],
    },

  ],
  root: document.querySelector("#app"),
  beforeEach(oldRoute, newRoute){
    if (newRoute.hashPath==='/forbid') { 
      return false; 
    }
    
    return true;
  },
  afterEach(oldRoute, currentRoute){
    let routeOption = currentRoute.option || {};
    let routerExtra = routeOption.extra || {};
    let title = routerExtra.title || '页面标题';
    document.title = title; 
  },
})
let router = Router(options) // 多次调用 Router, 总会返回唯一的 router 对象 
// 实例属性  
router.getOld  // 前一路由信息对象 
router.getNew  // 当前路由信息对象 
router.routes  // 所有配置的路由信息列表 
// 实例方法  
router.backUntillTo(url, dftUrl)  // 返回到指定URL,不存在则返回到dftUrl

5 其他工具方法

utils  工具集对象 
  .html(str)  将富文本解析为可渲染的内容  

待办TODO

bug: scoped css 
写框架文档 
错误/编译错误 提示优化  
性能优化: 
  DOM操作性能优化 
组件根节点可为一数组 实现非单一节点功能  
--------------------------------------------------------------------------------