欢迎来到皮皮网网首页

【openpilot 源码解析】【妙手源码】【rpcdemo源码】webpack源码调试

来源:mybatis源码 结果集 时间:2024-11-24 19:53:19

1.webpack 4 源码主流程分析(十一):文件的码调生成
2.webpack之devtool详解
3.放弃 console.log 吧!用 Debugger 你能读懂各种源码
4.Webpack入门到精通 五(常用配置)
5.源码细读-深入了解terser-webpack-plugin的码调实现
6.如何在WebStorm 2017下调试Vue.js + webpack

webpack源码调试

webpack 4 源码主流程分析(十一):文件的生成

       本文深入分析了 Webpack 4 中文件生成的具体流程。在资源写入文件阶段,码调通过一系列优化和处理,码调最终返回到 Compiler.js 的码调 compile 方法,其中 Compiler 的码调openpilot 源码解析属性 _lastCompilationFileDependencies 和 _lastCompilationContextDependencies 被赋予了 fileDependencies 和 contextDependencies。紧随其后的码调是创建目标文件夹的过程,该操作通过 outputPath 属性配置,码调结合 mkdirp 函数完成。码调

       在创建目标文件并写入阶段,码调通过 asyncLib.forEachLimit 方法并行处理每个文件资源,码调实现路径拼接、码调源码转换为 buffer,码调最后写入真实路径的码调文件。对于不同类型的码调 source 实例,如 CachedSource、ConcatSource 和 ReplaceSource,其处理逻辑各不相同,但最终目标都是获取替换后的字符串并合并返回 resultStr。所有文件创建写入完成后,执行回调,触发Compiler.afterEmit:hooks,进一步设置 stats 并打印构建信息。

       至此,构建流程全部结束。通过本文的分析,我们可以更直观地了解 Webpack 4 中文件生成的具体实现细节,为深入理解 Webpack 的工作原理和优化提供理论支持。本章小结,下章将解析打包后的文件,敬请期待。

webpack之devtool详解

       Webpack的Devtool详解

       Webpack的Devtool是开发者在开发和调试过程中重要的工具之一,它可以帮助开发者更好地理解和调试代码。妙手源码Devtool提供了多种不同的配置选项,用于生成源代码映射,以便于开发者在浏览器控制台中直接查看源代码,从而更有效地定位和解决代码中的问题。

       一、什么是Devtool?

       Webpack的Devtool是一个配置选项,允许开发者在构建过程中生成源代码映射。源代码映射是一种文件,它将编译后的代码映射回原始源代码,以便于开发者调试。Devtool的不同配置选项会生成不同类型的源代码映射,适用于不同的开发场景。

       二、Devtool的主要配置选项

       1. eval模式:这是最简单的源代码映射形式,它直接在控制台输出源代码。这种模式下,不需要生成额外的文件,但生成的源代码映射相对较小且不持久。

       2. source-map模式:在这种模式下,Webpack会生成一个独立的.map文件来存储源代码映射信息。这种模式的源代码映射比较详细,但会增加构建时间。

       3. inline-source-map模式:与source-map模式类似,但源代码映射信息会直接嵌入到构建后的文件中。这种模式便于传输和分发构建后的文件,但同样会增加文件大小。

       4. cheap-module-eval-source-map模式:适用于模块化的项目,能够提供模块级别的调试信息。它在开发和调试阶段很有用,但生成的源代码映射相对较小。

       三、如何选择适合的rpcdemo源码Devtool配置?

       选择Devtool的配置取决于项目的需求和开发阶段。在开发阶段,为了快速迭代和调试代码,可以选择生成更详细的源代码映射;而在生产环境,为了优化性能和文件大小,可以选择生成较小的源代码映射或者不使用源代码映射。常见的做法是在开发阶段使用如eval或cheap-module-eval-source-map等详细的配置选项,而在生产环境使用source-map或inline-source-map等更精简的配置选项。

       总之,Webpack的Devtool是开发者在开发和调试过程中的重要工具,通过合理配置Devtool,可以大大提高开发效率和代码质量。

放弃 console.log 吧!用 Debugger 你能读懂各种源码

       很多同学不清楚为什么要使用debugger进行调试,难道console.log不行吗?

       即使学会了使用debugger,还是有很多代码看不懂,如何调试复杂的源码呢?

       这篇文章将为你讲解为什么要使用这些调试工具:console.log vs Debugger。

       相信绝大多数同学都会使用console.log进行调试,将想查看的变量值打印在控制台。

       这种方法可以满足基本需求,但遇到对象打印时就无法胜任了。

       比如,我想查看webpack源码中的compilation对象的值,我尝试打印了一下:

       但你会发现,当对象的值也是对象时,它不会展开,而是打印一个[Object] [Array]这样的字符串。

       更严重的是,打印的内容过长会超过缓冲区的大小,在terminal中显示不全:

       而使用debugger来运行,在这里设置一个断点查看,就没有这些问题了:

       有些同学可能会说,那打印一个简单的源码pass值时使用console.log还是很方便的。

       比如这样:

       真的吗?

       那还不如使用logpoint:

       代码执行到这里就会打印:

       而且没有污染代码,使用console.log的话,调试完成后这个console也不得不删除掉。

       而logpoint不需要,它就是一个断点的设置,不在代码中。

       当然,最重要的是debugger调试可以看到调用栈和作用域!

       首先是调用栈,它就是代码的执行路线。

       比如这个App的函数组件,你可以看到渲染这个函数组件会经历workLoop、beginWork、renderWithHooks等流程:

       你可以点击调用栈的每一帧,查看都执行了什么逻辑,用到了什么数据。比如可以看到这个函数组件的fiber节点:

       再就是作用域,点击每一个栈帧就可以看到每个函数的作用域中的变量:

       使用debugger可以看到代码的执行路径,每一步的作用域信息。而你使用console.log呢?

       只能看到那个变量的值而已。

       得到的信息量差距不是一点半点,调试时间长了,别人会对代码的运行流程越来越清晰,而你使用console.log呢?还是老样子,因为你看不到代码执行路径。

       所以,不管是调试库的源码还是业务代码,不管是调试Node.js还是网页,都推荐使用debugger打断点,别再用console.log了,即使想打印日志,也可以使用LogPoint。discuzqApp源码

       而且在排查问题的时候,使用debugger的话可以加一个异常断点,代码跑到抛异常的地方就会断住:

       可以看到调用栈来理清出错前都走了哪些代码,可以通过作用域来看到每一个变量的值。

       有了这些,排查错误就变得轻松多了!

       而你使用console.log呢?

       什么也没有,只能自己猜。

       Performance

       前面说debugger调试可以看到一条代码的执行路径,但是代码的执行路径往往比较曲折。

       比如那个React会对每个fiber节点做处理,每个节点都会调用beginWork。处理完之后又会处理下一个节点,再次调用beginWork:

       就像你走了一条小路,然后回到大路之后又走了另一条小路,使用debugger只能看到当前这条小路的执行路径,看不到其他小路的路径:

       这时候就可以结合Performance工具了,使用Performance工具看到代码执行的全貌,然后用debugger来深入每一条代码执行路径的细节。

       SourceMap

       sourcemap非常重要,因为我们执行的都是编译打包后的代码,基本是不可读的,调试这种代码也没有什么意义,而sourcemap就可以让我们直接调试最初的源码。

       比如vue,关联了sourcemap之后,我们能直接调试ts源码:

       nest.js也是:

       不使用sourcemap的话,想搞懂源码,但你调试的是编译后的代码,怎么读懂呢?

       读懂一行

       前面说的debugger、Performance、SourceMap只是调试代码的工具,那会了调试工具,依然读不懂代码怎么办呢?

       我觉得这是不可能的。

       为什么这么说呢?

       就拿react源码来说:

       switch case能读懂吧。三目运算符能读懂吧。函数调用能读懂吧。

       每一行代码都能读懂,而全部的代码不就是由这一行行代码组成的么?

       加上我们可以单步执行来知道代码执行路径。

       为啥每行代码都能读懂,连起来就读不懂了呢?

       那应该是代码太多了,而你花的时间不够而已。

       先要读懂一行,一个函数,读懂一个小功能的实现流程,慢慢积累,之后了解的越来越多之后,你能读懂的代码就会越多。

       总结

       这篇文章讲了为什么要使用调试工具,如何读懂复杂代码。

       console.log的弊端太多了,大对象打印不全,会超过terminal缓冲区,对象属性不能展开等等,不建议大家使用。即使要打印也可以使用LogPoint。

       使用debugger可以看到调用栈,也就是代码的执行路径,每个栈帧的作用域,可以知道代码从开始运行到现在都经历了什么,而console.log只能知道某个变量的值。

       此外,报错的时候也可以通过异常断点来梳理代码执行路径来排查报错原因。

       但debugger只能看到一条执行路径,可以使用Performance录制代码执行的全流程,然后再结合debugger来深入其中一条路径的执行细节。

       此外,只有调试最初的源码才有意义,不然调试编译后的代码会少很多信息。可以通过SourceMap来关联到源码,不管是Vue、React的源码还是Nest.js、Babel等的源码。

       会了调试之后,就能调试各种代码了,不存在看不懂的源码,因为每一行代码都是基础的语法,都是能看懂的,如果看不懂,只可能是代码太多了,你需要更多的耐心去读一行行代码、一个个函数、理清一个个功能的实现,慢慢积累就好了。

       掌握基于debugger、Performance、SourceMap等调试代码之后,各种网页和Node.js代码都能调试,各种源码都能读懂!

Webpack入门到精通 五(常用配置)

       为更好的阅读体验请移步掘金

       初始化项目

       在package.json中添加

       运行yarn build,即可看到当前打包好的dist.js文件

       使用webpack build支持IE,用babel-loader打包js

       安装babel-loader npm

       使用babel-loader打包jsx

       测试

       yarn build

       为webpack配置eslint

       eslint-config-react-app 包含Create React App使用的可共享 ESLint 配置。npm link

       让webpack可以感知到eslint的配置,从而在编译的过程中提示报错信息

       在没加eslint-webpack-plugin之前,尽管编辑器中eslint报错,但在运行yarn build时,它仍能编译成功。如下图所示

       加完之后的情况,此时不仅eslint报错,webpack构建时也会在控制台报错,这样很好地使用了eslint

       使用babel-loader打包TypeScript

       参考babel官网

       添加一个test.tsx,并在index.js中引入,以下结果编译成功

       让eslint支持TypeScript

       让eslint支持ts,添加相关配置

       运行yarn build发现此时编译仍可成功

       修改后的效果

       使用babel-loader打包tsx

       生成tsconfig.json文件

       编写tsx-demo.tsx文件并在index.js中引入进行测试

       CRLF是什么?一、LF和CRLF是什么?二、LF和CRLF区别

       让js和ts支持@alias

       引入代码进行测试

       让webpack支持scss

       使用sass-loader npm

       scss自动导入全局文件,scss共享变量给js

       可以让项目中使用的css变量由同一份js和scss共同维护一份变量

       webpack支持less文件

       使用less-loader npm

       less共享给js,对比scss和less

       若要选择,则选择scss

       stylus文件

       使用stylus npm

       webpack config重构,生产页面单独提取css文件

       使用mini-css-extract-plugin webpack文档

       自动生成HTML页面

       使用html-webpack-plugin npm

       webpack优化:单独打包runtime

       单独打包runtime的原因

       webpack优化:使用splitChunks将node依赖单独打包

       在编译时缓存React等类库文件

       webpack优化:固定modules

       运行yarn build后,可以看到引入了三个js文件

       optimizationmoduleids

       webpack多页面

       webpack优化:common插件

       如果共有文件,则打包成一个文件;如果两个入口同时引用了一个文件,看这个打包后页面引入js的顺序

       无限多页面的实现思路

       只需将这两个参数设置为动态生成的即可满足要求。测试后大功告成!!!

       最后附上源代码链接

       其他文章

       一咻:Webpack入门到精通 五(常用配置)

       一咻:Webpack 入门到精通四 (插件)

       一咻:Webpack入门到精通 三(Loader原理)

       一咻:Webpack入门到精通 二(核心原理)

       一咻:Webpack入门到精通 一(AST、Babel、依赖)

源码细读-深入了解terser-webpack-plugin的实现

       terser-webpack-plugin 是一个基于 webpack 的插件,它利用 terser 库对 JavaScript 代码进行压缩和混淆。其核心功能在于通过在 webpack 的运行时钩子 optimizeChunkAssets 中注册,实现了代码优化过程。在 apply 函数中,它获取 compilation 实例,并通过 tapPromise 注册一个异步任务,当 webpack 执行优化阶段时,每个 chunk 会触发这个任务,执行 minify 函数进行压缩处理。

       optimise 函数是实际的任务处理入口,它负责具体的优化流程。函数内部,scheduleTask 负责并行处理,如果开启 parallel 模式,会利用jest-worker提供的线程池进行并发工作,线程池管理复杂,根据 node 版本不同采用 worker_threads 或 child_process。minify 函数则是压缩和混淆代码的核心操作,它直接使用 terser 库完成任务。

       总的来说,terser-webpack-plugin 的优化流程包括在 webpack 的优化阶段对代码进行压缩,使用 Jest 的 worker 线程池进行并行处理,以及通过 terser 库的实际压缩操作。理解这些核心环节,可以帮助开发者更深入地掌握该插件的使用和工作原理。

如何在WebStorm 下调试Vue.js + webpack

       æœ‰äººè§‰å¾—vue项目难调试,是因为用了webpack。所有代码揉在了一起,还加了很多框架代码,根本不知道怎么下手。所以vue+webpack调试要从webpack入手。

       1.我们先从一般情况开始说。

       -sourcemap

       webpack配置提供了devtool这个选项,如果设置为 ‘#source-map’,则可以生成.map文件,在chrome浏览器中调试的时候可以显示源代码。

       devtool: '#source-map'

       2.然而这个设置实际上没这么简单。webpack官方给出了7个配置项供选择:

       .devtool介绍

       è¿™é‡Œä¸åŒçš„配置有些不同的效果,比如是否保留注释、保留行信息等,具体每一条什么意思这里不详解释,有兴趣的童鞋可以参考这篇文章

       å®˜æ–¹é»˜è®¤çš„是用 ‘#cheap-module-eval-source-map’

       devtool: '#cheap-module-eval-source-map'

       è®¾ç½®å¥½ä¹‹åŽï¼Œåœ¨vue项目调试的时候,代码里面标注debugger的时候就能看到对应的代码了,非常方便。

       .debugger

       æˆ–者,直接找到对应的文件。在chrome用 ’ctrl(command) + p‘,输入文件名,可以找到对应的源代码。

       command+p

       æ‰“断点:

       æ–­ç‚¹

       éœ€è¦æ³¨æ„çš„是,这里断点会打在下一行。同时一行代码运行在它的下一行才算执行。

       .-vue-cli

       vue家的项目脚手架,推荐使用。vue-cli老家在这里

       vue-cli可以帮我们自动搭建项目,首先npm全局安装

       npm install -g vue-cli

       ç„¶åŽåˆ›å»ºä¸€ä¸ªæ–°çš„项目

       vue init webpack my-project

       ä¸€è·¯å›žè½¦ï¼Œæžå®šã€‚(更多配置项请参考上面给出的vue-cli链接)

       è¿™é‡Œä»Žç½‘上下载了一个带webpack的vue项目(跑之前记得npm install一下)

       .vue-cli webpack

       ä»Žbulid文件夹里面就大概能看出:

       •webpack.dev.conf: 开发模式用

       •webpack.prod.conf: 生产模式用

       å…¶ä¸­ï¼Œå¼€å‘模式提供了devtool为’#cheap-module-eval-source-map’,生产模式根据config文件夹下的productionSourceMap变量控制是否使用。

       è‹¥ä¸ºtrue,则devtool为’#source-map’

       å…¶ä»–使用方法一致。非常方便。

       3.线上调试

       å¹³æ—¶å¼€å‘的时候,我们用webpack的热加载,可以省去挂载调试的步骤,非常方便。但是发布后部署到服务器上,就失去了这个本地优势。

       å¦‚果使用挂载文件方式会比较麻烦。由于webpack打出来的文件有版本号这些信息,而且发布一个包看代码量可能需要等待不等,这个方案不实际。但是如果挂载的是热加载到端口下的文件的话,这个问题就很好办了。

       -热加载

       åœ¨æ­¤ä¹‹å‰ï¼Œå…ˆæ¥åˆ†æžä¸€ä¸‹webpack的热加载原理。

       å¯¹é¡¹ç›®æŠ“包可以发现这么一个文件:__webpack_hmr

       __webpack_hmr

       è¿™æ˜¯webpack热加载的服务器推送事件,eventsource类型,功能和websocket有点类似。大致作用是建立一个不会停止的stream流链接,服务器发送更新数据回来append到流的末端,前端读取最新append的数据,然后动态的更新页面上的东西。

       æŽ¥ä¸‹æ¥æˆ‘们观察下上文提到的更新数据有哪些。随便更新一个文件,触发热加载,再抓个包,发现有两个.hot-update.json和一个.hot-update.js文件

       çƒ­åŠ è½½æ›´æ–°æ–‡ä»¶

       è¿™äº›å…·ä½“做了些啥我不知道,这里就不深究了。应该是根据json里面的数据,达到一个准确更新的效果。

       æ‰€ä»¥çƒ­æ›´æ–°å…¶å®žå°±æ˜¯ç›‘听服务器上的数据,有修改的话服务器发送数据过来,前端把数据拿来后替换到页面上这么一个过程。

       -AutoResponder

       æŽ¥ä¸‹æ¥è°ˆè°ˆçº¿ä¸ŠæŒ‚载测试,这里推荐一款软件:fiddler

       fiddler有一个功能叫做AutoResponder,它可以将一个地址指向另一个地址。之所以用这个软件,是因为它能匹配正则,非常方便。

       AutoResponder

       ä¸Šä¸€èŠ‚说到,webpack热加载用到了这几类文件

       •__webpack_hmr

       •xxxxxxxxxxx.hot-update.json

       •xxxxxxxxxxx.hot-update.js

webpack的devtool 配置

       devtool配置与代码调试紧密相关,旨在优化调试体验。在前端开发中,源代码经过合并、压缩、转换后,运行的是转换后的代码,这给调试带来了挑战。因此,chrome浏览器率先引入了source map技术,其他浏览器也纷纷跟进,如今几乎所有新版浏览器都支持source map。

       source map本质上是一个配置,它不仅记录了所有源码内容,还记录了源码与转换后代码之间的对应关系,便于开发人员直接定位到源代码中的错误。浏览器处理source map的原理在于解析这个映射关系,从而显示正确的源代码位置信息。

       最佳实践包括:在开发环境中使用source map作为调试工具,避免在生产环境中使用,以防止额外的网络传输和潜在的代码暴露风险。如果在生产环境中使用source map用于调试,需采取措施确保网络传输和代码安全。

       在webpack中,devtool配置可以优化调试体验。使用正确的devtool选项,能够提供不同级别的源码映射,以适应开发与生产环境的需求。例如,"eval"配置选项在开发环境中提供快速构建,同时保留了正确的行号映射,而"cheap"配置在开发环境中提供了较低开销的映射,忽略了列映射信息。

       在生产环境中,通常选择不生成source map,以优化性能。然而,如果需要生成source map,可以选择将它作为单独的文件输出,并在bundle中添加引用注释,以便开发工具查找。此外,还存在一些特定场景的配置选项,如仅生成用于错误堆栈跟踪的source map,或不包含sourcesContent的source map,以保护源代码安全。