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

@dxyl/babel-macro-util

v1.0.17

Published

有些代码不适合在运行时计算,在编译时运算会更安全。而且还可以结合nodejs端做更强的代码整合。 之前有在webpack通过自定义loader去导出编译后的代码。但那种无法传递结构化的参数。只能通过url形式

Downloads

19

Readme

有些代码不适合在运行时计算,在编译时运算会更安全。而且还可以结合nodejs端做更强的代码整合。 之前有在webpack通过自定义loader去导出编译后的代码。但那种无法传递结构化的参数。只能通过url形式

使用

npm i -D @dxyl/babel-macro-util 该库基于babel-plugin-macros create-react-app脚手架生成的项目自带引用了babel-plugin-macros

// 用法
import {mul} from '@dxyl/babel-macro-util/lib/util.macro'
let value=12;
let a=mul(2,value)
//解析后
let value=12;
let a=24

其它构建工具用到babel时,在babel配置项中添加babel-plugin-macros即可 .babelrc

{
  "plugins":["babel-plugin-macros"]
}

场景

index.js

import store from './store'
ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App></App>
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

slices/global.js


export default {
    name:"global",
    initialState:{
        theme:"default2",
        count:0
    },
    reducers:{
        setTheme(state,action){
            state.theme=action.payload
        },
        setCount(state,action){
            state.count+=action.payload
        }
    },
    asyncReducers:{
        async addCount(action,thunkAPI){
                await new Promise(resolve=>{
                    setTimeout(resolve,2000)
                })
                thunkAPI.dispatch({
                    type:"global/setCount",
                    payload:action.payload*10
                })
        }
    },
    extraReducers: builder => {
    
    }

}

store.js

import {configureStore,createAsyncThunk,createSlice,getDefaultMiddleware} from '@reduxjs/toolkit'
import { requireGlob } from '@dxyl/babel-macro-util/util.macro'
const allSlices=requireGlob('./slices/*.js');

let createStoreFactory=(slices)=>{
    let stores={}
    let reducers={}
    let asyncReducer=new Map()
    let middlewares=[]
    let asyncMiddleWare=({getState,dispatch})=>next=>action=>{
        let type=action.type
        if(asyncReducer.has(type)){
           let fn=asyncReducer.get(type).fn
           return dispatch(fn(action))
        }else{
           return next(action)
        }
    }
    function create(sliceConfig){
            let sliceStore=createSlice(sliceConfig)
            if(sliceConfig.asyncReducers){
               Object.keys(sliceConfig.asyncReducers).forEach(name=>{
                    let type=sliceStore.name+'/'+name
                    asyncReducer.set(type,{
                        namspace:sliceStore.name,
                        name:name,
                        type:type,
                        fn:((oldFn)=>{
                            let ops={}
                            if(Array.isArray(oldFn)){
                                ops=oldFn[1]
                                oldFn=oldFn[0]                            
                            }
                            let asyncFn=createAsyncThunk(type,async (action,thunkApi)=>{
                                let result=await oldFn(action,thunkApi)
                                return result
                            },ops)
                            return (action)=>{
                                let asyncDispatch=asyncFn(action)
                                return  (dispatch,getState)=>{
                                     let promise=asyncDispatch(dispatch,getState)                                   
                                     let p=Promise.resolve(promise).then((result)=>{
                                         if(asyncFn.fulfilled.type===result.type){
                                             return result.payload
                                         }else if(asyncFn.rejected.type==result.type){
                                             return Promise.reject(result)
                                         }else{
                                             return Promise.reject(result)
                                         }
                                     })
                                     Object.assign(p,promise)
                                     return p;
                                }
                            }
                        })(sliceConfig.asyncReducers[name])
                    })
               })
            }
            reducers[sliceStore.name]=sliceStore.reducer
            stores[sliceStore.name]=sliceStore
            return sliceStore
    }
    function addMiddlewares(...fns){
        middlewares.push(...fns)
    }
    slices.forEach(create)
    addMiddlewares(...getDefaultMiddleware())
    addMiddlewares(asyncMiddleWare)
    return {
        stores,
        reducers,
        create,
        addMiddlewares,
        middlewares:middlewares,
        createStore(options={}){
            return configureStore ({
                middleware:middlewares,
                reducer:reducers,
                ...options
            })
        }
    }
}
export default createStoreFactory(allSlices.map(slice=>slice.ref['default'])).createStore()

app.js

import React from 'react';
import {useSelector,useDispatch} from 'react-redux'
import './App.css';
function UpdateTheme(){
    const dispatch=useDispatch()
    const onChange=(e)=>{
        dispatch({
          type:"global/setTheme",
          payload:e.target.value
        })
    }
    const onAdd=()=>{
       dispatch({
         type:"global/addCount",
         payload:10
       }).then((result)=>{
          console.log('result',result)
       })
    }
    return <div><button onClick={onAdd}>add</button><input onChange={onChange}/></div>
}
function App() {
  let global=useSelector(state=>state.global)
  return (
    <div className="App">
      theme2:{global.theme}{global.count}
      <UpdateTheme></UpdateTheme>
    </div>
  );
}

export default App;

自定义宏文件

cust.macro.js

  import {createMacroHandle,PluginManager,macroPlugin,convertToJsObject} from '@dxyl/babel-macro-util'

  let custMacroPlugin=new PluginManager(macroPlugin.plugins)//继承
  custMacroPlugin.add('mul',(currentPath, babel, state) => {
      const t = babel.types
      const args = currentPath.get('arguments').map(convertToJsObject)

    currentPath.replaceWith(t.valueToNode(args[0]*args[1]))
  }))
  export default createMacroHandle(custMacroPlugin)
util

自定义添加方法

import {macroPlugin,convertToJsObject} from '@dxyl/babel-macro-util'

macroPlugin.add('mul',(currentPath, babel, state) => {
    const t = babel.types
    const args = currentPath.get('arguments').map(convertToJsObject)

   currentPath.replaceWith(t.valueToNode(args[0]*args[1]))
}))

匹配模式加载模块

import {configureStore} from '@reduxjs/toolkit'
import { requireGlob } from '@dxyl/babel-macro-util/util.macro'

let reducers=requireGlob('./reducers/**/*.js');
reducers=reducers.reduce((memo,reducers)=>{
     reducers=reducers.ref['default']
     return {
         ...memo,
        ...reducers
     }
},{})

let sliceReducers=requireGlob('./slices/**/*.js');
sliceReducers=sliceReducers.reduce((memo,slice)=>{
     slice=slice.ref['default']
     return {
         ...memo,
        [slice.name]:slice.reducer
     }
},{})

const store= configureStore ({
    reducer:{
        ...reducers,
        ...sliceReducers
    }
})
export default store

requireProperties 加载模块


const config = [{
  path: "/",
  component: "src/layouts/BasicLayout",
  routes: [{
    path: "/",
    redirect: "/home",
  }, {
    path: "/home",
    component: "src/App"
  }]
}]
const routes = requireProperties(config,['component'])
// 编译后
const config = [{
  path: "/",
  component: "src/layouts/BasicLayout",
  routes: [{
    path: "/",
    redirect: "/home",
  }, {
    path: "/home",
    component: "src/App"
  }]
}]
const routes = [{
  path: "/",
  component: require("src/layouts/BasicLayout"),
  routes: [{
    path: "/",
    redirect: "/home",
  }, {
    path: "/home",
    component: require("src/App")
  }]
}]

evalCode

const files=evalCode(`
  const fs=require('fs)
  module.exports=fs.readdirSync('./src')
`,{sourceString:false})

sourceString:true

const routes=evalCode(`
  let routes=[{
    path:"/",
    component:"src/layouts/BasicLayout",
    routes:[{
        path:"/",
        component:"src/layouts/BasicLayout",
    }]
  }]  
  module.exports=JSON.stringify(routes,(key,value)=>{
    if(key==='component'&&typeof value ==='string'){
        return 'require(\\''+value+'\\')'
    }
    return value
},2).replace(/"component":\\s*"require\\((.*?)\\)"/g,'"component":require($1)')
`,{sourceString:true})

evalCode

const files=evalCode(`
  const fs=require('fs)
  module.exports=fs.readdirSync('./src')
`,{sourceString:false})

sourceString:true

const routes=evalCode(`
  let routes=[{
    path:"/",
    component:"src/layouts/BasicLayout",
    routes:[{
        path:"/",
        component:"src/layouts/BasicLayout",
    }]
  }]  
  module.exports=JSON.stringify(routes,(key,value)=>{
    if(key==='component'&&typeof value ==='string'){
        return 'require(\\''+value+'\\')'
    }
    return value
},2).replace(/"component":\\s*"require\\((.*?)\\)"/g,'"component":require($1)')
`,{sourceString:true})