27 comments

[ 4.1 ms ] story [ 77.1 ms ] thread
Do you plan to support middlewares?
Could you explain further, please? I plan on changing it a bit internally but not on growing it past its purpose as I like it to do only one thing (and hopefully do it well)
I think page.js supports middleware if you're looking for something to emulate. Basically chainring callbacks.
Only reference I could find in https://visionmedia.github.io/page.js/ was:

    page(callback)

    This is equivalent to page('*', callback) for generic "middleware".
Which is... pointless? If you are going to call a function everywhere in front-end why don't you use an IIFE for scope or just nothing at all? Unless you wanted to put it on the <head> and make it load when the page is ready.
A callback is middleware, you can

    page('/some/path', middleware, callback);
I see, but I don't really like this extra functionality for pagex. I am not looking to copy express with middleware for front-end, just wanted some easy and straight way to load a script if we are in the correct part of the website.
Uh, then you and I have very different definitions of "express-like". When I think of express I think of middleware.
In the simple way, express accepts a path (url-like fragment) and executes a callback when it matches the url. THAT is what I meant from express-like, but from this and other comments I can see it wasn't clear at all.
I'm watching a movie so I haven't looked too deeply at this, but your regexes aren't safe from ReDoS according to substack's safe-regex [1]. It might be worth finding a non-regex-based way to parse regular expressions in case of some weird routes that could cause exponential-time parsing.

[1] https://github.com/substack/safe-regex

The path is preferred to the Regex, and I hope that no developer is using user input to create a route here. As specified in substack's safe-regex:

> WARNING: This module merely seems to work given all the catastrophic regular expressions I could find scouring the internet, but I don't have enough of a background in automata to be absolutely sure that this module will catch all exponential-time cases.

I also don't have it and I think the case for this error is so contrieved that it doesn't make sense to add a check in pagex. So adding a couple of warnings, one for not trusting user input and another for this specific error, should be fine.

Isn't this client-side? So, what could a malicious user DoS other than their own browser? Am I missing something?
How is this different from page.js?
It was initially a Regex-only project so it was quite different. Then I added path-to-regex and forgot to check if there was some library out there similar so now they are quite similar.

However I can see a couple of important differences:

1. The parameters are passed to the callback in pagex which makes it cleaner:

    pagex('/users/:id/:frag?', function(id, frag = 'profile'){ ... });
While with page.js you have to retrieve them manually:

    pagex('users/:id/:frag?', function(ctx){ var id = ctx[0], frag = ctx[1] });
2. You can negate the url. For instance, if you want something to run in all pages except in the users page:

    pagex('/users', true, function(){ ... });
3. [undocumented, not-official] There is a before and after catch-all which can be useful for debugging, analytics or similar
Quick tip, instead of passing true here, having an options object improves readability. As somebody who's never seen it before, the following does the opposite of what I expect:

  pagex('/users', true, function(){ ... });
But _this_ is more readable—communicates exactly what I need to know, and requires no previous knowledge of the library:

  pagex('/users', { negate: true }, function(){ ... });
Thanks for sharing your library, I love how you've put the ergonomics of use first. :)
I am totally going to do that, but haven't got around to do it yet. This will also add a bit of flexibility (much needed) about how to pass options.
One powerful feature of the Express router (but missing here) is that it's just a middleware, making composition trivial, e.g.:

    const userRouter = router()
      .get('/', showUser)

    const usersRouter = router()
      .get('/', listUsers)
      .use('/:username', userRouter)

    const mainRouter = router()
      .use('/users', usersRouter)
Ah that is really cool, recently a user requested a feature[1] that is basically this but I solved it in a different way [undocumented]:

    pagex.base = '/users';
    pagex('/', listUsers);
    pagex('/:username', showUser);
    pagex.base = '';
I am still considering extend it in this way:

    pagex.namespace('/users', function(pagex){
      pagex('/', listUsers);
      pagex('/:username', showUser);
    });
[1] https://github.com/franciscop/pagex/issues/1
Why .namespace and not .use like express?
Because it is completely unrelated to express, and even with express that is not really how it works so it'd only cause confusion
I don't understand the "express-like" in the title. What's similar to express in your router?
It uses the same path-to-regex package. Other than that I can't tell how it's similar.
Hmm not sure what problem this was trying to solve since client side router has been a solved one for a long time. And this is not looking close to express w/o middleware, which page.js does.
Honestly one of the worst ShowHN submissions I've ever seen.
Could you elaborate further, please? What you don't like and what could be improved? It is a small project and I didn't think it'd make it to the front page but yet here it is, so some people must like it and see something positive.