webpack最简单的入门教程里bundle.js之运行单步调试的原理解析
读这篇文章的朋友,请确保对webpack有最基础的认识。
您可以阅读我前一篇文章:Webpack 10分钟入门 来在本地运行一个Webpack的hello world项目。https://www.toutiao.com/i6612879647568822788/
我这里可以在回顾一下这个web pack的hello world项目。
用webpack打包之后,项目文件夹里包含了这些资源:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8EmBA_0EYGSryKIlTaksCkcfwc05gjk3kXAaq29GVaNQscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
index.html的源代码很简单,就包含了一个webpack打包后生成的bundle.js文件:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB81mBKquuCkGj3rmAAm0jqqHo-6yhRND3PLgqzvNxy-ScscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
那么运行时,Hello,Jerry的字符串是如何通过bundle.js打印出来的呢?
这就是本文要阐述的内容。我们可以从bundle.js第一行设置断点,然后开始调试:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8Tc11wgekJHylO9_szqLNrFd0FQFiAJAPAWyOw2Ln18gscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB82uk699HjhRQVLctsPRoXZHQJY43csPA7u8nywU9aFr8scTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8BD2x_-1jZmgTHrDL1e5d3e9OQjgkQ0b7WKQky5Npqe4scTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8GYWIsIEW8I1j3006RFCpO8R0fWJAcLSOJUww1PpdTnYscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
把我们web工程里定义的两个module注入到webpack_require.m里:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8IGSBITVxXk11qQidNeYIjnt5jFLf26SNKQqocthsynMscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
因为我们在webpack.config.js里定义的入口模块为main.js:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8e5wxfb_MwrIfJaprPn22M_bu3kN-orgY1ZzfTgkEpkgscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
在bundle.js里此处进行运行时加载:return webpack_require(webpack_require.s = "./main.js");
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8895zLtbWXJJ1U8A-RJcmqEC-qMoCRGjDeO5f4Xh97GgscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVXj5z-1gnOZUpa0dwSLTX5__IsNR4b6vPkB3LNWBww2G.jpg)
webpack_require函数本来就是在bundle.js里定义的:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8CvdfdBqCZzeiVCoFSHulbIciYTiRQim57z_SgJ8WRbMscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
首先检查main.js是否已经装载在内存里了:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8pj-7nIFoPm0eDmqb2mhol6OFFVi9ywFsz_lPLdqVVegscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVXj5z-1gnOZUpa0dwSLTX5__IsNR4b6vPkB3LNWBww2G.jpg)
对于我这个例子,显然没有,所以从头开始装载main.js.首先创建一个对象,id为./main.js:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8OF6K-qXvxHrKBXp7475Ax7vzZ3poIf5tOfstfi-eSp8scTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
然后执行这个module的函数,即我们实现在main.js里的javascript代码。当然经过webpack的加工,main.js里的代码已经通过eval的方式嵌入到bundle.js里了。
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8GwbY2EtEVrOJS0kJ6nsUoidDXJM4buJhxUQ1_Hz9h_QscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
原始的main.js代码:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8doTFHEIKfL0KcVk5hH_eSWn0y14d8JFUi_aS_J1usEAscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVUjPHLmr0O7aN8rHHuyy-SGT-LQ65_K1aUUOd8tUFmNE.jpg)
上述代码被webpack转换之后,main.js里的源代码被替换成了webpack_require:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8n-jfRIsP2t1J3h8TziIzRR5Ar6wEK1YFUG3vp5rQI2sscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVWF1YuZJpeAlfbpLoWqnhtaT-LQ65_K1aUUOd8tUFmNE.jpg)
从这里也能看出webpack递归处理module的思路,从webpack.config.js定义的entry module,即main.js出发,在main.js遇到需要require其他mobule的地方,递归进入webpack_require:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8pR6CKnJDHbEvWJyYTXbsyFeCgP3Ww3_OVG4-20B4KVMscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
require("print.js")的执行过程,就是把print.js里定义的print函数本身,赋给module的exports属性:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8Ei80_v4gqYY2hwXDOTCTj3kxPnA8cuP3Wlpqx_FGUw0scTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
print.js module装载完毕之后,就可以执行了。
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8Pogx0lC-U0wxMki0VwyPvwt08d7hrGwIsKIgKYICqIsscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8rTDi7RNSBG7TlSv0OGujlhBhx4RrtrzfpdpRmafJQd4scTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVXj5z-1gnOZUpa0dwSLTX5__IsNR4b6vPkB3LNWBww2G.jpg)
注意第2行代码执行完毕后,html页面就出现了期望的字符:
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8eG-DUU4w4SOkR_8JfCNebWCTFbNz8CgTVMzzbatCtE8scTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVbSde5GZufnEzUg3D5l8dQ2T-LQ65_K1aUUOd8tUFmNE.jpg)
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8d_qBH03NlXuqVO-zcLcksPzQKvUjd9hDxCXq0YnkS3gscTCfsrs63c479zLGuwUxaMyZD3shmd8BUYQBXGheVdFFJQhNZmPR9GXZgHSMOpmT-LQ65_K1aUUOd8tUFmNE.jpg)
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
![webpack最简单的入门教程里bundle.js之运行单步调试的原理解析 webpack最简单的入门教程里bundle.js之运行单步调试的原理解析](https://cdn.ancii.com/article/image/v1/V1/gl/_d/d_g1lVoFnaHF66uLvjLNgrNwLOlgxjAwTZLe7DAT3x2t904_cuYFw1FRoLgZPQB8K7gdM8gnGSzN8RP5ldmSoznjrqvKho3Fqs4_XBZSsFUP-PpFD76OUWGM57t7CEKQ7qC4HCdHZEnGUWeSsil818NOM-SYxbINt1Exa_4cYubMmE7PboFomS2ziSMb4EX7.jpg)