Elpis

60 阅读4分钟

Elpis

基于 Koa 框架二次开发的应用程序,采用约定大于配置的方案,自定义了一系列 loader 来加载和组织Koa应用的各个部分,包括

  • middleWare
  • config
  • extend
  • controller
  • service
  • router-schema
  • router

里程碑1 elpis-core心得

  • 在每一个loader中通过约定好对应的文件目录及文件格式,将核心部分与用户实践时的目录区分开来,同时对相关联的依赖文件进行自动解析并引入加载到服务实例上。
  • 同时为了更好的支持用户自定义中间件的添加,初始化时提供全局中间件的注册路径。

以middleware的配置来做举例说明

这个中间件的核心作用是自动加载位于特定目录下的所有中间件文件,并将其组织到 app.middlewares 对象中。中间件会以模块化的方式存放在 app/middleware 目录下,并按照文件结构动态生成对应的访问路径。

加载步骤:

  • 获取目录路径:首先,加载器会解析 app/middleware 目录。通过 path.resolve 获取到实际的文件路径,然后通过使用 glob.sync 方法同步读取该目录及其子目录下的所有 .js 文件。

  • 处理文件路径:每个中间件文件的路径都会被提取出来,接着进行路径解析,去除文件扩展名(.js)和根目录部分,得到一个结构化的中间件名称(如 custom-module/custom-middleware)。

  • 名称规范化:为了规范化中间件的命名,文件名中的 _- 会被转化为小驼峰命名方式,例如:custom-module/custom-middleware.js 会被转为 customModule/customMiddleware

  • 挂载中间件:加载器会通过循环解析,在 app.middlewares 对象下创建对应的嵌套结构,然后把每个中间件函数挂载到该结构的相应位置。最终,应用程序的 app.middlewares 对象将包含所有加载的中间件。

示例:

app/middleware
    ├── custom-module
    │   └── custom-middleware.js
    └── another-module
        └── another-middleware.js

在加载器执行后,app.middlewares 将会变成:

app.middlewares = {
    customModule: {
        customMiddleware: require('path/to/custom-middleware')(app)
    },
    anotherModule: {
        anotherMiddleware: require('path/to/another-middleware')(app)
    }
}

这样就可以通过 app.middlewares.customModule.customMiddleware 直接访问到自定义的中间件。


webpack基础配置建设

1.wepack下的分包策略

  • 第三方依赖包为一类 vendors
  • 公共方法为一类 common
  • 单独引用为一类

配置如下:

splitChunks: {
    chunks: 'all',// 对同步或一部模块都进行分割
    maxAsyncRequests: 10,// 每次异步加载的最大并行请求数量
    maxInitialRequests: 10,// 入口点的最大并行请求数量
    cacheGroups: {
        vendor: { // 第三方依赖库
            test: /[\/]node_modules[\/]/,
            name: 'vendor',// 模块名称
            priority: 20,// 优先级,数字越大优先级越高
            enforce: true,// 强制执行
            reuseExistingChunk: true,// 不需要重复打包,复用已有的公共 chunk
        },
        common: { // 公共模块
            name: 'common',
            minChunks: 2,// 被n个地方同时引用,就归为公共模块
            minSize: 1,// 最小分割文件大小  (1 byte)
            priority: 10,// 优先级
            reuseExistingChunk: true,// 不需要重复打包,复用已有的公共 chunk
        },
    }
},

2.什么是热更新(HMR)

  • 什么是 HMR(Hot Module Replacement)?

HMR 是 Webpack 提供的一种机制,允许在应用运行时替换、添加、删除模块,而无需完全刷新页面。

  1. 目的
  • 快速预览最新代码变化。
  • 保留应用状态,避免刷新页面导致的状态丢失(如表单输入、页面路由等)。
  • 提升前端开发体验和效率。
  1. 实践
  • 项目中通过express建立一个 devServer 服务
  • 通过 divMiddleware 实时监听文件的变动
  • 通过 hotMiddleware 去替换更新的文件

3.HMR 原理流程

1. 构建流程
  • Webpack 编译时,会在入口文件注入 HMR 客户端代码(如 webpack-hot-middleware/client)。
  • 该客户端代码会与 Dev Server(webpack-dev-serverwebpack-hot-middleware)建立 WebSocket 连接。
2. 监听变更
  • 当代码变更时,Webpack 会重新编译变更的模块,生成新的 Bundle。
  • 与正常构建不同,HMR 只输出变更的模块,而不是整个应用。
3. 推送变更
  • Webpack Dev Server 会通知 HMR 客户端(通过 WebSocket)。
  • 客户端接收到更新信息后,通过 JSON 形式描述变更的模块列表。
4. 替换模块
  • HMR 客户端会动态地用新的模块替换掉旧的模块(通过 __webpack_require__.hot.accept)。

  • 具体的替换行为依赖于代码是否支持 HMR:

    • 模块自带 HMR 处理逻辑(如 Vue、React 热更新插件)时,会只更新变更的部分组件,保留页面状态。
    • 如果模块不支持 HMR(如普通 JS 模块),可能会触发页面自动刷新。

3.核心原理关键点

关键点说明
WebSocket 长连接客户端与 Dev Server 之间保持连接,用于监听变更推送
只重新打包变更模块Webpack 只编译变更的模块,避免全量打包
Module API(HMR API)通过 module.hot.acceptdispose 控制热替换
状态保持只替换模块,不刷新页面,页面状态不丢失

抖音“哲玄前端”《大前端全栈实践》