webpack:
什么是webpack:
webpack用于编译JavaScript模块。
关注javascript技术的同学一定知道,在CommonJS和ES6中,为了支持模块化,而引入了export/require/import这类东西,模块化可以降低开发的复杂度,用于支撑前端的复杂功能,但是模块化后,也带来了许多问题,比如老版本的浏览器不支持ES6/JSX语法,开发和线上不能保持一致,这就为WebPack类的自动化代码转换工具的出现提供了需求。
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
按照官网的说法,webpack可以打包一切资源/图片/样式/依赖等等,webpack默认只支持js模块打包,对于其他文件就需要用loader解析器,比如在vue中,直观的效果就是使用webpack可以将使用的vue,css,图片等打包成一个js。
Source Map:
部署前端之前,开发者通常会对代码进行打包压缩,这样可以减少代码大小,从而有效提高访问速度。然而,压缩代码的报错信息是很难Debug的,因为它的行号和列号已经失真。这时就需要Source Map来还原真实的出错位置了。
为啥变换代码?
前端代码越来越复杂的情况下,开发者通常会使用webpack、UglifyJS2等工具对代码进行打包变换,这样可以减少代码大小,有效提高访问速度。关于变换代码的原因,这里不妨引用一下大神阮一峰的JavaScript Source Map 详解:
压缩,减小体积。比如jQuery 1.9的源码,压缩前是252KB,压缩后是32KB。
多个文件合并,减少HTTP请求数。
其他语言编译成JavaScript。最常见的例子就是CoffeeScript。
如何变换代码?
下面是一个简单的“hello World”程序hello.js
1 | function sayHello() |
使用UglifyJS2对源代码进行压缩变换:
1 | uglifyjs hello.js \ |
压缩后的代码hello.min.js
1 | function o(){var o="Hello, "+Name;console.log(o)}o(); |
为啥需要Source Map?
使用Firefox执行hello.js的报错信息是这样:
1 | ReferenceError: Name is not defined |
而hello.min.js的报错信息是这样:
1 | ReferenceError: Name is not defined |
对比压缩前后的出错信息,我们会发现,错误行号和列号已经失真,且函数名也经过了变换。而对于真实的前端项目,开发者会将数十个源文件压缩为一个文件,这时,错误的列号可能多达数千,且出错的真实文件名也是很难确定的,这样的话,压缩代码的报错信息是很难Debug的。
而Source Map则可以用于还原真实的出错位置,帮助开发者更快的Debug。
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。
source-map文件,这个文件是编译过程中变量与方法的映射表。
VUE/REACT开发场景
在VUE/REACT开发场景下 ,前端开发会引入如模块化等诸多新特性,前端开发不再是几个简单的js文件,开发完成后会通过webpack等打包工具打包生成部署使用的js文件,但是如果我们直接分析该编译的js,很难看懂。
比如某页面下的app.bundle.js,反正我是看不懂写的是啥,这个js文件就是webpack打包后的结果,但是由于我是开启了source-map调试模式,如果你是用chrome浏览器打开的,打开devtools-sources,应该可以看到一个webpack://
,这个就是chrome对source-map调试的支持,点开src目录下就可以看到js代码源文件。
为什么会有这类问题?
大多数开发人员没有意识到的是,这些源映射source-map
实际上包含了其前端源代码的全部。
是的,他们知道可以进行映射,但是源映射后的文件几乎为乱码,更不用说理解了。由于这种误解,发现开发团队在其Webpack配置中将JavaScript源映射留在生产环境中是相对常见的。
解决方案:
修改config/index.js
中的build
对象productionSourceMap: false
即可
渗透思路or危害:
-
通过
source-map
可以获取前端源码,也就是说从黑盒变成了灰盒。 -
泄露的各种信息如网站路径、API、加密算法、管理员邮箱、内部功能等等。
-
很多vue应用都是先渲染页面再判断是否登陆,根据这个小缺陷,我们首先可以查看相关功能
-
前端源码被人copy走
工具:
通过查看浏览器中包含的JavaScript文件并提取捆绑的JavaScript文件底部存在的sourceMappingURL来获取源地图。
原理:
在页面正则匹配 regex = "\\/\\/#\s*sourceMappingURL=(.*)$"