rollup打包js库 占位符替换成文件名和行号输出日志中定位报错位置

rollup 自定义插件进行代码替换

    • 简易版
      • 问题:在打包的js库中有很多日志或者error的控制台输出,但是打包后的js调用报错后无法从控制台看到堆栈信息,无法定位报错的位置是在哪个文件的哪一行
      • 需求:能够从报错中观察到报错在哪个文件的那一行,便于排查错误
      • 实现:自定义插件来实现此功能
      • 思路:在打包时遍历要打包的文件,将文件内容按照换行符进行分割,得到的集合就是这个文件的代码,便可以拿到行号,然后通过正则表达式对占位符进行全局替换。
      • 代码:
      • 配置:
    • 进阶版
      • 使用简易版的存在一个问题, 打包后生成的sourceMap文件中的映射内容是空的,如果不需要这个文件的可以使用简易版的,进阶版则是完善了这个问题的解决
      • 代码
      • 配置:
      • 扩展:

简易版

问题:在打包的js库中有很多日志或者error的控制台输出,但是打包后的js调用报错后无法从控制台看到堆栈信息,无法定位报错的位置是在哪个文件的哪一行

需求:能够从报错中观察到报错在哪个文件的那一行,便于排查错误

实现:自定义插件来实现此功能

思路:在打包时遍历要打包的文件,将文件内容按照换行符进行分割,得到的集合就是这个文件的代码,便可以拿到行号,然后通过正则表达式对占位符进行全局替换。

代码:

  • replace.js
// 导入path包获取文件名,也可以通过正则来自己获取
import path from 'path';export default function replace(options = {}) {const { placeholders = [] } = options;let fileCount = 0;let replaceCount = 0;return {//插件名name: 'placeholder-replace',transform(code, id) {// 将代码转换为 UTF-8 编码code = code.toString('utf-8');// 获取文件名const fileName = path.basename(id);// 遍历每个占位符code = placeholders.reduce((modifiedCode, placeholder) => {// 构建占位符的正则表达式const placeholderRegex = new RegExp(`${placeholder}`, 'g');return modifiedCode.split('\n').map((line, row) => {let newLine = '';let cursor = 0;let result;while ((result = placeholderRegex.exec(line))) {const col = result.index;// 替换占位符为文件名:行号=>>的形式newLine += line.slice(cursor, result.index) + `${fileName}:${row + 1} =>> `;cursor += col + result[0].length;}newLine += line.slice(cursor);return newLine;}).join('\n');}, code);return code;},buildEnd() {console.log(`\n替换的文件数: ${fileCount}`);console.log(`\n替换的次数: ${replaceCount}`);},};
}

配置:

import replace from './replace.js';export default {// ...其他配置项plugins: [replace({placeholders: ['log-position-placeholder', 'another-placeholder'], // 设置占位符数组}),],
};

进阶版

使用简易版的存在一个问题, 打包后生成的sourceMap文件中的映射内容是空的,如果不需要这个文件的可以使用简易版的,进阶版则是完善了这个问题的解决

代码

replcae.js

import path from 'path';
// 导入 rollup-pluginutils 包,它提供了一些工具函数来处理 sourcemap
import {createFilter} from 'rollup-pluginutils';
// 导入 magic-string 包,它可以让你修改字符串并生成 sourcemap
import MagicString from 'magic-string';export default function replace(options = {}) {const {placeholders = []} = options;let fileCount = 0;let replaceCount = 0;// 使用 createFilter 函数来过滤掉不需要处理的文件const filter = createFilter(options.include, options.exclude);return {// 插件名name: 'placeholder-replace',transform(code, id) {// 如果文件不符合过滤条件,直接返回if (!filter(id)) return null;// 将代码转换为 UTF-8 编码code = code.toString('utf-8');// 创建一个 MagicString 对象,用于修改代码和生成 sourcemapconst magicString = new MagicString(code);// 获取文件名const fileName = path.basename(id);// 遍历每个占位符placeholders.forEach(placeholder => {// 构建占位符的正则表达式const placeholderRegex = new RegExp(`${placeholder}`, 'g');let result;while ((result = placeholderRegex.exec(code))) {const start = result.index;const end = start + result[0].length;// 获取行号和列号const line = getRow(result.input, start, '\n');// 替换占位符为文件名:行号=>>的形式magicString.overwrite(start, end, `${fileName}:${line} =>> `);replaceCount++;}});fileCount++;// 返回修改后的代码和 sourcemap 对象return {code: magicString.toString(),map: magicString.generateMap({hires: true})};},buildEnd() {console.log(`\n替换的文件数: ${fileCount}`);console.log(`\n替换的次数: ${replaceCount}`);},};
}/*** 获取行号* @param str 代码内容* @param end  截止位置* @param tag  换行符* @return {number} 行号*/
function getRow(str, end, tag) {let slice = str.slice(0, end);let split = slice.split(tag);let length = split.length;return  length;
}

配置:

配置和简易版是一样的,只是增加了一个包含和排除掉选项

扩展:

  • 除了 transform钩子函数之外,Rollup 还提供了其他一些常用的钩子函数,用于在构建过程中执行特定的逻辑。以下是一些常用的钩子函数:
buildStart:在构建过程开始时调用,可以在其中执行一些初始化操作。
buildEnd:在构建完成后调用。
resolveId:在解析模块标识符时调用,可以自定义模块的解析逻辑。
load:在加载模块时调用,可以自定义模块的加载逻辑。
transform:在转换模块代码时调用,可以修改模块的代码内容。
renderStart:在开始渲染生成输出文件时调用,可以执行一些准备工作。
renderChunk:在渲染每个输出块(chunk)时调用,可以修改输出块的代码内容。
renderDynamicImport:在渲染动态导入语句时调用,可以自定义动态导入的行为。
writeBundle:在生成输出文件完成后调用,可以执行一些清理或后处理的操作。
这些钩子函数可以根据需要选择使用,并根据特定的构建过程进行定制。你可以根据自己的需求在插件配置中添加这些钩子函数,并在相应的钩子函数中编写你想要的逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/2984.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣206. 反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1]示例 2: 输入:head [1,2] 输出:[2,1]示例 3: 输入&am…

MySQL进阶

目录 一、存储引擎 1、MySQL体系结构 2、存储引擎简介 3、存储引擎特点 InnoDB MyISAM Memory 4、存储引擎选择 二、索引 1、索引概述 2、索引结构 3、索引分类 4、索引语法 5、SQL性能分析 5.1 SQL执行频率 5.2 慢查询日志 5.3 profile详情 5.4 explain执行…

k8s dev环境怎么做到本地调试

列出所有的namespace kubens切换到指定的namespace kubens dev-gmmt 查看namespace 中存在那些service kubectl get services启动链接的服务和端口 kubectl port-forward service/cmdb 8081:8081该命令的含义是将Kubernetes集群中名为"cmdb"的服务的端口8081&…

Spring-Cloud-Gateway如何自定义断言工厂?

遇到这么一个面试题:如何在网关做配置,实现只有在早晨9点到下午18点之间接口才允许访问,其他时间访问都是404。 我们知道网关的一个重要的作用就是路由转发,路由表的配置大概是这个样子: spring:cloud:gateway:routes:- id: user…

Sentinel流量规则模块(新增)

系统并发能力有限,比如系统A的QPS支持1个请求,如果太多请求过来,那么系统A就应该进行流量控制了,比如其他请求直接拒绝 新增流控规则介绍:新增流控规则窗口 1.资源名:默认请求路径。 2.针对来源:Se…

基于51单片机和proteus的温室大棚系统

此系统是基于51单片机和proteus的仿真设计,功能如下: 1. LCD1602实时显示光照/土壤湿度/温度值及设定值。 2. 按键可增减光照/土壤湿度/温度设定阈值。 3. 获取到的温度低于设定温度则打开加热设备。 4. 获取到的光照值低于设定光照值则打开补光灯。…

【SpringBoot Web开发】如何构建树形结构数据

树形结构数据 应用场景 比如我们需要构建菜单、机构树、其他业务类型树形结构 工具类 我们可以把菜单列表返回,获取parent_id字段等于0的节点,称为根节点,这样的节点代表一级菜单再通过根节点的主键去寻找子菜单,因为要有多及菜…

【iOS】编译与链接

前言 计算机语言分为机器语言、汇编语言和高级语言。 可以将高级语言分为两种:编译语言和解释型语言(直译式语言)。 解释型语言(逐步进行解释执行) 解释语言编写的程序在每次运行时都需要通过解释器对程序进行动态…

【区块链+体育】“数智化”的杭州亚运会,中创助力区块链技术发展

“智能”,是杭州亚运会的办赛理念之一。除了数字藏品开亚运先河,杭州亚组委充分应用区块链、大数据、人工智能等前沿技术,为观众提供从购票、出行、观赛到住宿、美食和旅游等“一站式”服务。 本次亚运会将全程智能陆续落到了实处&#xff0…

CSS 实现 Turbo 官网 3D 网格线背景动画

转载请注明出处,点击此处 查看更多精彩内容 查看 Turbo 官网 时发现它的背景动画挺有意思,就自己动手实现了一下。下面对关键点进行解释说明,查看完整代码及预览效果请 点击这里。 简单说明原理:使用 mask-image 遮罩绘制网格&a…

Python测试框架Pytest的基础入门

Pytest简介 Pytest is a mature full-featured Python testing tool that helps you write better programs.The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries. 通过官方网站介绍…

ios 通过xib自定义控件

通过xib自定义控件 xib和stroyboayd对比 共同点: 都是用来描述软件界面 都是用interface Builder工具来编辑 本质都是转换成代码去创建控件 不同点: xib是轻量级的,用来描述局部ui界面 创建模型文件 XMGCar 自定义控件 xib 图形设计 …

graylog源码搭建

这里主要讲如何源码安装graylog 下载地址: https://www.graylog.org/downloads/ 下载带有JVM的源码文件源码安装 下载graylog-5.1.3-linux-x64.tgz,并上传到Centos中,执行以下操作 tar -zxvf graylog-5.1.3-linux-x64.tgzcd /etcmkdir -p …

每天一道C语言编程:Cylinder(圆柱体问题)

题目描述 使用一张纸和剪刀,您可以通过以下方式切出两个面形成一个圆柱体: 水平切割纸张(平行于较短的边)以获得两个矩形部分。 从第一部分开始,切出一个最大半径的圆。圆圈将形成圆柱体的底部。 将第二部分向上滚动&…

在 Amazon 上以高可用性模式实现 Microsoft SQL 数据库服务现代化的注意事项

许多企业都有需要 Microsoft SQL Server 来运行关系数据库工作负载的应用程序:一些应用程序可能是专有软件,供应商可使用它强制 Microsoft SQL Server 运行数据库服务;其他应用程序可能是长期存在的、自主开发的应用程序,它们在最…

我们如何在 Elasticsearch 8.6、8.7 和 8.8 中加速数据摄入

作者:Adrien Grand, Joe Gallo, Tyler Perkins 正如你们中的一些人已经注意到的,Elasticsearch 8.6、8.7 和 8.8 在各种数据集上带来了良好的索引加速,从简单的关键字到繁重的 KNN 向量,以及摄取管道繁重的摄取工作负载。 摄取涉及…

跳跃表SkipList(简单的C++实现)

不懂跳跃表的请直接百度 直接上实现 #include <iostream> #include <string.h> #include <ctime>using namespace std;template<typename T> struct SkipNode {inline static constexpr int Rate3;inline static constexpr int MaxHeight8;inline sta…

2023版7月软件测试面试题(800道)【附带答案】持续更新...

又到了立flag的时候&#xff0c;你的目标是拿下大厂offer&#xff1f;还是多少万年薪&#xff1f;其实这些都离不开日积月累的过程。 为此我特意整理出一份&#xff08;超详细笔记/面试题&#xff09;它几乎涵盖了所有的测试开发技术栈&#xff0c;非常珍贵&#xff0c;人手一…

批量添加:vue+easyexcel 上传excel文件解析为Java对象并保存到数据库

对于像数据库中批量添加数据&#xff0c;我们一般会选择通过Excel文件先按照固定的格式将数据保存&#xff0c;然后再通过系统上传进而保存到数据库中。 阿里的excel解析工具EasyExcel和Apach的POI都能进行Excel文件的解析&#xff0c;但是EasyExcel操作起来要相对更简单一些&…

cancal报错 config dir not found

替换classpath中间封号两边的值