UNPKG

f2e-server3

Version:

f2e-server 3.0

164 lines (161 loc) 6.93 kB
import { F2EConfigResult } from "../interface"; import { MemoryTree } from "../memory-tree"; import logger from "../utils/logger"; import { MiddlewareEvents, MiddlewareCreater, MiddlewareReference } from "./interface"; import { exit } from 'node:process'; import * as _ from '../utils/misc'; import middleware_livereload from './livereload'; import middleware_tryfiles from './try_files'; import middleware_proxy from './proxy'; import middleware_esbuild from './esbuild'; import middleware_less from './less'; import middleware_postcss from './postcss'; import middleware_auth from './auth'; import middleware_alias from './alias'; import middleware_include from './include'; import middleware_routes from './routes'; export const combineMiddleware = async (conf: F2EConfigResult, middlewares: (MiddlewareCreater | MiddlewareReference)[]): Promise<Required<MiddlewareEvents>> => { const onMemoryLoads: Required<MiddlewareEvents>["onMemoryLoad"][] = [] const onMemoryInits: Required<MiddlewareEvents>["onMemoryInit"][] = [] const beforeRoutes: Required<MiddlewareEvents>["beforeRoute"][] = [] const onRoutes: Required<MiddlewareEvents>["onRoute"][] = [] const buildWatchers: Required<MiddlewareEvents>["buildWatcher"][] = [] const onSets: Required<MiddlewareEvents>["onSet"][] = [] const onGets: Required<MiddlewareEvents>["onGet"][] = [] const buildFilters: Required<MiddlewareEvents>["buildFilter"][] = [] const watchFilters: Required<MiddlewareEvents>["watchFilter"][] = [] const outputFilters: Required<MiddlewareEvents>["outputFilter"][] = [] /** 开始内置中间件加载 */ middlewares.push(middleware_auth) middlewares.push(middleware_routes) middlewares.push(middleware_include) middlewares.push(middleware_alias) middlewares.push(middleware_less) middlewares.push(middleware_postcss) middlewares.push(middleware_esbuild) middlewares.push(middleware_proxy) middlewares.push(middleware_livereload) /** tryfiles 顺序需要在最后 */ middlewares.push(middleware_tryfiles) for (let i = 0; i < middlewares.length; i++) { const m = middlewares[i] const middle = 'execute' in m ? m : (function (m) { let middle: MiddlewareCreater | undefined = undefined; if ('middleware' in m) { const middlewareName = `f2e-middle-${m.middleware}` try { middle = require(middlewareName) if (middle) { middle.name = middle.name || middlewareName } } catch (e) { logger.error(e) exit(1) } } return middle })(m); if (!middle) continue; const { mode = ['dev', 'build', 'prod'], name = 'system', execute } = middle if (mode.includes(conf.mode)) { const result = await execute(conf) if (!result) continue; const { onMemoryInit, onMemoryLoad, beforeRoute, onRoute, buildWatcher, onSet, onGet, buildFilter, watchFilter, outputFilter } = result onMemoryInit && onMemoryInits.push(onMemoryInit) onMemoryLoad && onMemoryLoads.push(onMemoryLoad) beforeRoute && beforeRoutes.push(beforeRoute) onRoute && onRoutes.push(onRoute) buildWatcher && buildWatchers.push(buildWatcher) onSet && onSets.push(onSet) onGet && onGets.push(onGet) buildFilter && buildFilters.push(buildFilter) watchFilter && watchFilters.push(watchFilter) outputFilter && outputFilters.push(outputFilter) } } return { onMemoryInit: async (store) => { await Promise.all(onMemoryInits.map(fn => fn?.(store))) }, onMemoryLoad: async (store) => { await Promise.all(onMemoryLoads.map(fn => fn?.(store))) }, beforeRoute: async (pathname, ctx) => { let _pathname = pathname for (let i = 0; i < beforeRoutes.length; i++) { // beforeRoute 返回 false 停止继续 let res = await beforeRoutes[i](pathname, ctx) if (res === false) { return res } if (typeof res === 'string') { _pathname = res } } return _pathname }, onRoute: async (pathname, ctx) => { let _pathname = pathname for (let i = 0; i < onRoutes.length; i++) { // onRoute 返回 false 停止继续 let res = await onRoutes[i](_pathname, ctx) if (res === false) { return false } if (typeof res === 'string') { _pathname = res } } return _pathname }, buildWatcher: (pathname, eventType, build, store) => { buildWatchers.map(item => item(pathname, eventType, build, store)) }, onSet: async (pathname, data, store) => { let result: MemoryTree.SetResult = { data, originPath: pathname, outputPath: pathname } for (let i = 0; i < onSets.length; i++) { const temp = await onSets[i](result.outputPath, result.data, store) result = Object.assign({}, result, temp) } return { ...result, originPath: pathname, } }, onGet: async (pathname, data, store) => { let temp = data for (let i = 0; i < onGets.length; i++) { let res = await onGets[i](pathname, temp || data, store) temp = res || temp } return temp }, watchFilter: (pathname) => { for (let i = 0; i < watchFilters.length; i++) { let allow = watchFilters[i](pathname) if (allow === false) { return false } } return true }, buildFilter: (pathname, size) => { for (let i = 0; i < buildFilters.length; i++) { let allow = buildFilters[i](pathname, size) if (allow === false) { return false } } return true }, outputFilter: (pathname, data) => { for (let i = 0; i < outputFilters.length; i++) { let allow = outputFilters[i](pathname, data) if (allow === false) { return false } } return true } } }