H5的接口预请求webpack插件,提升页面秒开率~

先有问题再有答案

  1. webpack有哪些必知必会的概念
  2. webpack的插件到底是什么
  3. webpack打包流程是怎样的
  4. 实现一个接口预请求插件用来提升页面秒来率

基础概念

  • Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。

  • Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。

  • Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。

  • Loader:模块转换器,用于把模块原内容按照需求转换成新内容。

  • Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。

  • Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。

  • Compilation 对象: 当 Webpack 以开发模式运行时,每当检测到文件变化,一次新的 Compilation 将被创建。一个 Compilation 对象包含了当前的模块资源、编译生成资源、变化的文件等。Compilation 对象也提供了很多事件回调供插件做扩展。

  • Compiler 对象: Compiler 对象在 webpack 启动时就已经被实例化,它和 compilation 实例不同,它是全局唯一的,在它的实例对象中,可以得到所有的配置信息,包括所有注册的 plugins 和 loaders。

  • Tapable:是一种实现了发布订阅模式的库,通过 tapable 我们可以注册自定义事件,在合适的时机去触发注册的事件。

打包流程概括

Webpack 的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

  1. 初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数;
  2. 开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译;
  3. 确定入口:根据配置中的 entry 找出所有的入口文件;
  4. 编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理;
  5. 完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系;
  6. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表,这步是可以修改输出内容的最后机会;
  7. 输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统。

在以上过程中,Webpack 会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。

实现插件的流程:

  • 一个 JavaScript 命名函数或 JavaScript 类。
  • 在插件函数的 prototype 上定义一个 apply 方法。
  • 指定一个绑定到 webpack 自身的 事件钩子
  • 处理 webpack 内部实例的特定数据。
  • 功能完成后调用 webpack 提供的回调。

一个H5的接口预请求webpack插件

可以应用在首屏接口上 和 js 并行发送请求 减少网络耗时 提升页面秒开率。

原理

插件会在 html 的 head 里面插入一段 code 从 query 上面获取参数 提前进行请求接口,插件会在 window 上挂载 usePreFetchApiService 方法,业务方可以使用此方法来获取结果数据。

功能

  1. 可以配置一个页面 并行请求多个接口
  2. 可以配置多个页面 请求一个接口
  3. 可以配置多个页面请求多个接口
  4. 多个页面数据通过 hash||path 标识 防止数据互串
  5. 数据获取 支持静态参数,query 参数,cookie 参数

使用

在vue.config.js文件配置

lua 复制代码
const PreFetchApiPlugin = require('pre-fetch-api-webpack-plugin');
chainWebpack: config => {
       config
           .plugin('PreFetchApiPlugin')
           .use(PreFetchApiPlugin, [[{
                method: 'post',
                params: { name: 'username' },
                hashList: ['all'],
                urls: [
                    { url: `/aaa` }
                ],
            }]]);
   }

接口获取数据:

javascript 复制代码
const usePreFetchApiService = window.usePreFetchApiService?.();

export const getPageData = async () => {
    const { preFetchService } = usePreFetchApiService?.() || {};
    if (preFetchService) {
        try {
            const res = await preFetchService; 
            //可能设置多个接口 所以返回的是一个数组
            return res[0];
        } catch (error) {
            // 接口请求报错 这里可以再次发送请求
        }
    } else {
        // 因为异常原因 预请求运行报错导致 方法缺失 
    }
};

关键代码目录

babel-plugin:babel相关插件

build:编译源码ES6->ES5

script: 这里的文件会被自动收集 经过编译后插入到html的header中 src: webpack插件先关逻辑

test: 做一些函数测试

其中在src/index里面的关键代码

ini 复制代码
// 通过compiler注册插件 通过alterAssetTagsCallback修改html的内容 
  apply(compiler) { 
        compiler.hooks.compilation.tap(PluginName, compilation => {
            const alterAssetTags = this.alterAssetTagsCallback.bind(this, compilation);
            const alterAssetTagGroups
                = compilation.hooks.htmlWebpackPluginAlterAssetTags
                || HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups;
            alterAssetTagGroups.tapAsync(PluginName, alterAssetTags);
        });
    }

完整代码

npm_pre-fetch-api-webpack-plugin

github_pre-fetch-api-webpack-plugin

参考

webpack.wuhaolin

相关推荐
小蜜蜂嗡嗡2 小时前
【flutter对屏幕底部有手势区域(如:一条横杠)导致出现重叠遮挡】
前端·javascript·flutter
伍哥的传说3 小时前
Vue 3 useModel vs defineModel:选择正确的双向绑定方案
前端·javascript·vue.js·definemodel对比·usemodel教程·vue3.4新特性·vue双向绑定
胡gh8 小时前
页面卡成PPT?重排重绘惹的祸!依旧性能优化
前端·javascript·面试
言兴8 小时前
# 深度解析 ECharts:从零到一构建企业级数据可视化看板
前端·javascript·面试
山有木兮木有枝_8 小时前
TailWind CSS
前端·css·postcss
烛阴9 小时前
TypeScript 的“读心术”:让类型在代码中“流动”起来
前端·javascript·typescript
杨荧9 小时前
基于Python的农作物病虫害防治网站 Python+Django+Vue.js
大数据·前端·vue.js·爬虫·python
Moment10 小时前
毕业一年了,分享一下我的四个开源项目!😊😊😊
前端·后端·开源
程序视点11 小时前
Escrcpy 3.0投屏控制软件使用教程:无线/有线连接+虚拟显示功能详解
前端·后端
silent_missile11 小时前
element-plus穿梭框transfer的调整
前端·javascript·vue.js