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 🙏

© 2024 – Pkg Stats / Ryan Hefner

f2e-server

v2.20.13

Published

f2e-server 2

Downloads

655

Readme

f2e-server

f2e-server 2

Install

npm i -g f2e-server

Options

  • f2e -h
  • f2e conf 生成 .f2econfig.js 配置文件 .f2econfig.js 的一个clone版本,需要自行修改
  • f2e build 构建到 output 目录 (需要在配置文件中配置 output 路径)
    • f2e build -w true 开启构建并监听文件变化输出结果
  • f2e start 启动开发服务器
  • f2e start -h
    • f2e start 从 2850 开始自增检测可以使用的PORT并启动
    • f2e start -c .f2econfig.js 指定配置文件
    • f2e start -p 8080 指定端口启动
    • sudo f2e start -p 443 开启HTTPS支持
    • sudo f2e start -H mysite.local 设置本地域名并从80端口启动
    • sudo f2e start -H mysite.local -p 8080 设置本地域名并从指定端口启动

Config

f2e conf 生成 .f2econfig.js 配置文件

基本配置


const path = require('path')
const request = require('request')

module.exports = {
    // host: 'f2e.local.cn',
    /**
     * 不启用 host 识别,只根据端口处理
     */
    no_host: false,
    // port: 2850,
    /**
     * 是否开启自动刷新
     * @type {Boolean}
     */
    livereload: true,
    /**
     * 使用 less 编译为css, 使用 less 配置
     * @type {Object}
     */
    useLess: {
        compress: false
    },
    /**
     * 支持babel编译 js/es/jsx, 支持 `.babelrc` 配置,
     * @type {Object}
     */
    useBabel: {
        getModuleId: pathname => pathname.replace(/\\+/g, '/'),
        /**
         * 支持多组babel-option 配置通过 only 参数匹配,匹配到一个,则停止
         */
        _rules: [
            {
                only: ['number.js'],
                getModuleId: pathname => 'number',
            }
        ]
    },
    /**
     * 是否支持 gzip
     * @type {Boolean}
     */
    gzip: true,
    /**
     * Range 默认大小
     * @type {Number}
     */
    range_size: 1024 * 1024,
    /**
     * 支持中间件列表, 默认添加的系统中间件后面, build之前
     *
     * ☆ 重要的
     * 1. 自定义中间件中所有事件 onXxx 也支持在外面定义, 在组件内更显条理, 而且也方便自己封装插件多处引入
     * 2. 系统中间件顺序 include(0) -> less(1) -> babel(2) ---> build(last)
     * 3. 顶层定义的事件顺序在系统中间件之前
     * @type {Array<Function>}
     */
    middlewares: [
        // marked 编译
        (conf) => {
            // conf 为当前配置
            return {
                /**
                 *
                 * @param {string} pathname 当前资源路径
                 * @param {Request} req 原生request对象
                 * @param {Response} resp 原生response对象
                 * @param {Object} memory 所有目录对应内存结构, get/set等方法调用会被 onSet/onGet 等拦截
                 */
                onRoute (pathname, req, resp, memory) {
                    // 搞一个代理试试
                    if (pathname.match(/^es6/)) {
                        request(pathname.replace('es6', 'http://es6.ruanyifeng.com')).pipe(resp)
                        return false
                    }
                },
                /**
                 *
                 * @param {string} eventType 事件类型 change/add/etc.
                 * @param {string} pathname 当前修改文件的路径
                 * @param {boolean} build 是否开启了build配置, build模式下可能同时需要触发其他资源修改等
                 */
                buildWatcher (eventType, pathname, build) {
                    console.log(new Date().toLocaleString(), eventType, pathname)
                },
                /**
                 * onSet 设置资源内容时候触发
                 * @param  {string} pathname 当前资源路径
                 * @param  {string/Buffer} data  上一个流结束时候的数据
                 * @param  {object} store   数据仓库 {_get, _set}
                 * @return {string/Buffer}   将要设置的内容
                 */
                onSet(pathname, data, store) {
                    if (pathname.match(/\.md$/)) {
                        let res = require('marked')(data.toString())
                        // 在数据仓库中设置一个新的资源 .html
                        store._set(pathname.replace(/\.md$/, '.html'), res)
                    }
                },
                /**
                 * 跟onSet类似, 开发环境下面,每次请求都会执行, 缩短server启动时间可以把onSet的逻辑扔这里
                 */
                onGet(pathname, data, store) {},
                /**
                 * 不希望影响构建的操作, 仅在server中触发, 不希望影响构建的操作(例: 自动更新脚本插入)
                 */
                onText(pathname, data, req, resp, memory) {},
                buildFilter(pathname, data) {},
                outputFilter (pathname, data) {
                    // .md 资源server环境可见, 但是不输出
                    return !/\.md$/.test(pathname)
                }
            }
        },
        // lodash 模板引擎
        () => {
            const _ = require('lodash')
            return {
                // 中间件置顶位置 include 之后
                setBefore: 1,
                onSet (pathname, data) {
                    // data 目录下面的文本资源需要经过模板引擎编译
                    if (pathname.match(/^test\/.*.html/)) {
                        let str = data.toString()
                        try {
                            str = _.template(str)({__dirname, require})
                        } catch (e) {
                            console.log(pathname, e)
                        }
                        return str
                    }
                }
            }
        }
    ],
    /**
     * 只构建指定条件的资源
     * @param  {string} pathname 资源路径名
     * @param  {Buffer/string} data     资源内容
     * @return {Boolean}
     */
    buildFilter: (pathname, data) => {
        // 路径过滤
        let nameFilter = !pathname || /lib|test|index|README/.test(pathname)
        // 资源大小过滤
        let sizeFilter = !data || data.toString().length < 1024 * 1024
        return nameFilter && sizeFilter
    },
    /**
     * build 阶段是否使用 uglify/cleanCSS 进行 minify 操作
     * @param  {string} pathname 资源路径名
     * @param  {Buffer/string} data     资源内容
     * @return {Boolean}
     */
    shouldUseMinify: (pathname, data) => {
        let ok = data.toString().length < 1024 * 1024
        !ok && console.log('shouldNotUseMinify: ' + pathname)
        return ok
    },
    /**
     * app 默认时候 f2e 构建系统, 支持 'static' 纯静态服务器
     * 如果 app 自定义, 相当于只是使用 f2e 的端口开启和域名解析功能, 其他所有配置失效
     */
    // app: 'static',
    /**
     * 资源数据目录, 未设置的时候 build 中间件不开启
     * @type {local-url}
     */
    output: path.resolve(__dirname, '../output'),
    /**
     * after server create
     * you can render websocket server via this
     */
    onServerCreate: (server) => {
        const { Server } = require('ws')
        const wss = new Server({server});
        wss.on('connection', (socket) => {
            socket.send('init')
        })
    }
}

中间件

参考 f2e-middleware

  1. lodash 模板引擎
  2. markdown 编译
  3. proxy 请求代理配置
  4. dest 构建资源输出重命名
  5. qrcode 简单二维码生成器

app接入

支持接入 Koa 以及 express

const Koa = require('koa')
const app = new Koa()

app.use(ctx => {
	ctx.body = __dirname
})


const express = require('express')
const app1 = express()

app1.get('/', function (req, res) {
  	res.send(__dirname)
})

app1.use(express.static('lib'))

module.exports = {
	// app: app.callback(),
	// app: 'static', // 纯静态资源服务器
	app: app1
}