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 🙏

© 2025 – Pkg Stats / Ryan Hefner

fffmwk

v3.1.9

Published

A simple node server for single page application.

Downloads

8

Readme

A simple node server for single page application

How to use
install the package in global
npm install fffmwk -g

cd to server path and init a config file
fff --init-config
and a file named "server.json" would be created

edit the server.json file (detail below)

start the server:
fff
or
fff -d start

stop:
fff -d stop

restart
fff -d restart

server.json is config file.

{
    "port": 443,
    "http2": true,
    "https": true,
    "httpRedirect": false,
    "rootPath": "/var/server/",
    "staticPath": "static",
    "apiPath": "api",
    "errPagePath": "error",
    "socketFile": "socket/socket",
    "httpsKeyFile": "certificate/key.pem",
    "httpsCertFile": "certificate/cert.pem",
    "nomatchFile": "static/index.html",
    "apiHeaders": {
        "Content-Type": "application/json; utf-8",
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "*"
    },
    "staticHeaders": {},
    "headers": {},
    "apiStringify": "json",
    "staticCache": 10,
    "timeout": 0,
    "logFile": "log/server.log.txt",
    "errFile": "log/server.err.txt"
} 

port: the http server port
http2: enable http2
https: enable https
httpRedirect: when https enabled, this option controls to create an additional http server using 80 port and redirect it to https site.
rootPath: root Path, the file root path, absolute path or relative to pwd.
staticPath: the static file path, absolute path or relative to root path.
apiPath: the api mode path, absolute path or relative to root path.
errPagePath: the http error file path. Name with statusCode + ".html". eg. 404.html
httpsKeyFile: required if "https" is "true", the path of private key with pem encodin.
httpsCertFile: required if "https" is "true", the path of public key with pem encodin.
socketFile: the websocket module path.
nomatchFile: if the static file is not found, show this file. In the single page application, this is usually set to the 'index.html.
apiHeaders: default Api headers. The api module will set these headers as default. It's useful while you want to access CROS in developer mode but not in product mode.
staticHeaders: default static file headers. Such as Cache-Control and so on.
headers: all request will be added, such as HSTS headers.
apiStringify: api return body default format. Can be set to "json", "toString" or "none".
staticCache: cache of static file. Set to 0 means no cache ( read file any time you use it. ). Set to number with out 0 ( read file while last read timestamp is older than it. Unit: second. ). String "Infinity" ( Cache forever until restart the server ).
timeout: while this is not 0, and api module runs longer then this, ther server will return server time out error (status Code 500), unit: second.
logFile: stdout file.
errFile: stderr file.

eg:
For angular, type ng build --aot will built files like these.

index.html  
favicon.ico  
xxxx.js  
yyyy.js  

Move them to a folder . eg: /usr/www/static
Write node mode like user.js and move it to /usr/www/api
Generate or buy certs ( or some other ways . eg. let's encrypt), move them to /usr/www/cert
Modified server.json as follow.

{
    "port": 443,
    "http2": true,
    "https": true,
    "httpRedirect": false,
    "rootPath": "/usr/www",
    "staticPath": "static",
    "apiPath": "api",
    "errPagePath": "error",
    "socketFile": "socket/socket",
    "httpsKeyFile": "certificate/key.pem",
    "httpsCertFile": "certificate/cert.pem",
    "nomatchFile": "static/index.html",
    "apiHeaders": {
        "Content-Type": "application/json; utf-8",
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "*"
    },
    "apiStringify": "json",
    "staticCache": 10,
    "logFile": "log/server.log.txt",
    "errFile": "log/server.err.txt"
} 

run
fff

Access : https://localhost
Access api: https://localhost/api/user

The server will find file in staticPath while the url is not start with 'api':

https://localhost/index.html  =>  static/index.html  
https://localhost/aaaa.js  =>  static/aaaa.js  
https://localhost/aaaa/index.html  =>  static/aaaa/index.html  

If file do not exists:
If nomatch is set, the response is the file in nomatch path, and statusCode is 200
If nomatch is empty, the response is the 404.html file in errPagePath, and statusCode is 404

For the url start with 'api', the server will find node module recursive.
If there is no such file or folder, the server will match the file/folder which start with "_", and pass them to the api module as a parameter.
Tip: The module should be a standard node module, and there shouldn't be a extsion name in the url.
eg:
https://localhost/api/v1/test/testa => api/v1/test/testa.js

if
folder 'v1' do not exists, but there is a folder named '_version'
file 'testa' do not exists, but there is a file named '_id.js'
https://localhost/api/v1/test/testa => api/_version/test/_id.js

Follow params will pass to the module.

param: {  
    version: "v1",  
    id: "testa"  
}  

The api module shoul export function as follow

module.exports = ({  
    param, // the parameter above  
    body, // request body, when post or patch or something else.  
    resquest, // node server resquest  
}) => {  
    let result = {};
    result.body = { a: "b" }  
  
    /**  
      * result.statusCode : http statisCode  
      * result.statusMessage : http statusMessage  
      * result.headers: {},  // object, response headers, default :  { "Content-Type" : "text/json; charset=utf-8"}  
      * result.body: "", // response body, if type of response body is not "string", it will be auto encrypt. 
                         // while apiStringify is:
                         // "json" => JSON.stringify(result.body);
                         // "toString" => result.body.toString();
                         // "none" => result.body;
      **/  
  
    return result; // you should return a object like this.  
}  

P.S. The api module now support async function. Such as

module.exports = async ({ param, body, resquest }) => {  
    result.body = { a: "b" }  
    return result;  
}  

Socket module should export a module with 1 parameter required.
The parameter is websocketserver;

example module

module.exports = server => {
    server.on("connect", client => {
        client.send("Hey!");
    });
}

full Api: https://www.npmjs.com/package/websocket

NOTE: http2 does not support websocket.