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

express-route-xloader

v2.0.2

Published

方便统一配置路由,设置中间件

Readme

方便统一配置路由,设置中间件

V2

npm i express-route-xloader@2
import { rtl } from 'express-route-xloader';
import express from 'express';
import path from 'path';
const app = express();

(async () => {
  await rtl(app)(path.resolve(__dirname, './actions/'));
  await rtl(app)(path.resolve(__dirname, './basicActions/'));

  app.use((rr, req, res, next) => {
    res.status(500);
    res.json({
      code: 'E500',
      message: 'ERR。',
    });
  });

  app.listen(3000, () => {
    console.log(`app is startd.`);
  });
})();

folder

  ▾ actions/                   |~
    ▸ test/                    |~
    ▸ v1/                      |~
      _mixin.js                |~

设置中间件

  ▾ actions/                   |~
    ▾ test/                      |~
      ▸ v1/                  |~
    _middlewares.js        |~

_middlewares.js 必须返回中间件数组, 中间件方法名请设为不同名称,action 需要排除中间件时需要。

中间件会影像所有当前目录的路由(action),已经当前目录之下的所有子目录的路由。

想要给路由单独加路由的话,创建名称为 _{action 名称}_middlewares.js

const middleware = async (req, res, next) => {
  next();
};

const middlewares = [middleware];
export default middlewares;

改造每个 action - mixin

该文件放在 action 文件夹根目录,已让全部修改生效_mixin.js

import moment from 'moment';

const params = (action) => {
  return async (req, res, next) => {
    await action({
      moment,
      req,
      res,
      next,
    });
  };
};

// 错误捕捉
const error = (action) => {
  return async (params) => {
    const { res } = params;
    try {
      const result = await action(params);
      if (!res.headersSent) {
        res.json({
          code: 'S000',
          message: 'SUCCESSED.',
          ...result,
        });
      }
    } catch (e) {
      const [code, message] = Array.isArray(e) ? e : ['E000', e.message];
      if (envs.ENV === 'LOCAL') {
        logger.error('Mixin Catched Error: ', e);
      }
      res.json({
        code,
        message,
      });
    }
  };
};

const mixins = [params, error];
export default mixins;

之后就 action 就可以通过第一个参数获取 moment

export default async ({ moment, next, req, res }) => {};

action

可以返回 3 个参数

const url = '/test/:uid'; // 不返回时路由名称以文件名为准
const method = 'post'; // 不返回时默认get
const exceptMiddlewares = ['auth']; // 排除中间件, 所有中间不应该用相同的名字, 如果中间件名字相同,则会同时排除
export { url, method, exceptMiddlewares };
export default async () => {}; // action

404


设置 ./basicActions/ 文件夹
放置404.js

```javascript
export const url = '*';
export default async ({ res }) => {
   res.send('404 - Page Not Found.');
};

V1

npm i express-route-xloader@1

routes

routes.js

const routes = [
  {
    path: 'v1',
    children: [
      {
        path: 'image',
        children: [
          {
            path: 'upload',
            middleware: [],
            method: 'post',
            action: () => {},
          },
        ],
      },
    ],
  },
];

export default routes;

visit api url /v1/image/upload

import routes from './routes';
import express from 'express';
const app = express();

const routeLoader = new RouteLoader(app);
routeLoader.setRoute(routes);

app.listen(PORT || 3000, () => {});

middleware

auth.js

export default (req, res, next) => {
  // do someting
  next();
};

on routes.js

import auth from './auth';

const routes = [
  {
    path: '/board',
    middleware: [auth],
    action: (req, res) => {
      res.json({});
    },
  },
];

mixin

mixin.js

import moment from 'moment';

export default (action) => {
  return async (req, res) => {
    res.xjson = (data) => {
      return res.json(response(data));
    };

    console.log.log('[START]');

    await action(req, res, {
      moment,
    });

    console.log(`[END]`);
  };
};

add mixin

import actionMixin from './mixin';

const routeLoader = new RouteLoader(app);
// add before setRoute
routeLoader.addMixin(actionMixin);
routeLoader.setRoute(routes);

test.js

export default (req, res, { moment }) {
  res.json({
    date: moment().format('YYYY/MM/DD')
  })
}
import testAction from './test';

const routes = [
  {
    path: 'v1',
    children: [
      {
        path: 'image',
        children: [
          {
            path: 'upload',
            middleware: [],
            method: 'post',
            action: testAction,
          },
        ],
      },
    ],
  },
];

export default routes;