UNPKG

mm_os

Version:

MM_OS服务端架构,用于快速构建应用程序,支持网站建设、小程序后台、AI应用、物联网(IOT/AIOT)、游戏服务端等多种场景。

227 lines (214 loc) 5.2 kB
const Manager = require('mm_machine').Manager; const Drive = require('./drive'); /** * 静态文件管理类 * @augments {Manager} * @class */ class Static extends Manager { /** * 配置参数 * @type {object} */ static config = { /** * 名称 * @type {string} */ name: '', /** * 标题 * @type {string} */ title: '静态文件管理', /** * 描述 * @type {string} */ description: '这是静态文件管理器', /** * 检索文件名 * @type {string} */ filename: 'static.json', /** * 模板目录 * @type {string} */ tpl_dir: __dirname, /** * 基础目录 * @type {string} */ base_dir: '../common/static'.fullname(__dirname), /** * 自定义目录,加载项目自定义资源 * @type {string} */ dir: './app'.fullname(), /** * 搜索模式 dir按目录搜索 | file按文件名搜索 * @type {string} */ search_way: 'file', /** * 是否懒加载 * @type {boolean} */ lazy_load: false, /** * 模式 * 1.生产模式,改变文件不会重新加载 * 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本 * 3.热重载模式,改变配置文件都会加载配置和脚本 * 4.重载模式,执行完后重新加载脚本,避免变量污染 * 5.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本 * @type {number} */ mode: 3 }; /** * 构造函数 * @param {object} config 配置参数 * @param {object} parent 父级模块 */ constructor(config, parent) { super({ ...Static.config, ...config }, parent); } /** * 处理请求 * @param {object} ctx Http请求上下文 * @param {object} next 跳过函数 */ async _handleRequest(ctx, next) { var md = ctx.method; var path = ctx.path; if (md === 'GET' || md === 'HEAD') { await this._handleGetRequest(ctx, next, path); } else { await next(); } } /** * 处理GET请求 * @param {object} ctx Http请求上下文 * @param {object} next 跳过函数 */ async run(ctx, next) { var done; var infos = this.getInfos(); var len = infos.length; let path = ctx.path; if (path.indexOf('.') !== -1) { done = await this._tryServeFile(ctx, infos, len, function () { }); if (!done) { await next(); } } else { await next(); await this._handleDirReq(ctx, infos, len, path); } } /** * 尝试提供文件服务 * @param {object} ctx Http请求上下文 * @param {Array} list 驱动列表 * @param {number} len 列表长度 * @param {object} next 跳过函数 * @returns {boolean} 是否成功 */ async _tryServeFile(ctx, infos, len, next) { for (var i = 0; i < len; i++) { var info = infos[i]; if (info.state === 1) { let mod = this.getMod(info.name); if (mod) { var done = await mod.run(ctx, next); if (done) { return true; } } } } return false; } /** * 处理目录请求 * @param {object} ctx Http请求上下文 * @param {Array} infos 驱动信息列表 * @param {number} len 列表长度 * @param {string} path 请求路径 */ async _handleDirReq(ctx, infos, len, path) { var q = ctx.request.querystring; for (var i = 0; i < len; i++) { var info = infos[i]; if (info.state === 1) { let mod = this.getMod(info.name); if (mod) { var p = mod.config.path; if (path === p) { this._handleExactMatch(ctx, q, p); break; } else { var done = await mod.run(ctx, () => { }); if (done) { break; } } } } } } /** * 处理精确匹配 * @param {object} ctx Http请求上下文 * @param {string} q 查询字符串 * @param {string} p 路径 */ _handleExactMatch(ctx, q, p) { if (ctx.status === 404) { if (q) { ctx.redirect(p + '/?' + q); } else { ctx.redirect(p + '/'); } } } } /** * 静态文件驱动类 * @type {Drive} */ Static.prototype.Drive = Drive; exports.Static = Static; /** * 创建全局管理器 */ if (!$.pool.static) { $.pool.static = {}; } /** * 静态文件管理器 * @param {string} scope 作用域 * @param {string} title 标题 * @returns {object} 返回一个缓存类 */ function staticAdmin(scope, title) { var sc = scope || $.val.scope + ''; var obj = $.pool.static[sc]; if (!obj) { $.pool.static[sc] = new Static({ name: sc, title: title }); obj = $.pool.static[sc]; } return obj; } /** * @module 导出Static管理器 */ if ($.admin) { $.admin.static = staticAdmin; }