Webpack
1.说说你对webpack的理解
开发时,我们会使用框架 (React、Vue) ,ES6 模块化语法,Less/Sass 等 CSS 预处理器等语法进行开发,这样的代码要想在浏览器运行必须经过编译成浏览器能识别的 JS、CSS语法才能运行。所以我们需要打包工具帮我们做完这些事。除此之外,打包还能压缩代码、做兼容性处理、提升代码性能等。 webpack 是一个静态模块的打包工具。它会在内部从一个或多个入口点构建一个依赖图,然后将项目中所需的每一个模块组合成一个或多个 bundles 进行输出,它们均为静态资源。输出的文件已经编译好了,可以在浏览器运行。 webpack 具有打包压缩、编译兼容、能力扩展等功能。其最初的目标是实现前端项目的模块化,也就是如何更高效地管理和维护项目中的每一个资源。
2.说说webpack的构建流程
初始化参数:从配置文件和 Shell 语句中读取与合并参数,得出最终的参数
开始编译:用上一步得到的参数初始化 Compiler 对象,加载所有配置的插件,执行对象的 run 方法开始执行编译
确定入口:根据配置中的 entry 找出所有的入口文件
编译模块:从入口文件出发,调用所有配置的 Loader 对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
完成模块编译:在经过第4步使用 Loader 翻译完所有模块后,得到了每个模块被翻译后的最终内容以及它们之间的依赖关系
输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再把每个 Chunk 转换成一个单独的文件加入到输出列表
输出完成:在确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
在以上过程中,webpack会在特定的时间点广播出特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,并且插件可以调用webpack提供的API改变webpack的运行结果
3.Loader是什么?
其作用是让 Webpack 能够去处理那些非 JavaScript 文件。由于 Webpack 自身只理解 JavaScript、JSON ,其他类型/后缀的文件都需要经过 loader 处理,并将它们转换为有效模块。loader 可以是同步的,也可以是异步的;而且支持链式调用,链中的每个 loader 会处理之前已处理过的资源。
loader的两个属性:
1.test,识别出哪些文件会被转换
2.use,在进行转换时,使用的loader
多loader的执行顺序,从右到左(从下到上)
4.常用的Loader
babael-loader
ts-loader
sass-loader
style-loader
css-loader
url-loader
file-loader
postcss-loader
html-loader
eslint-loader
5.手写Loader待补充
6.Plugins是什么?
loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务:打包优化,资源管理,注入环境变量。plugin 会运行在 webpack 的不同阶段,贯穿整个编译周期,目的在于解决 loader 无法实现的其他事。其本质是一个具有apply
方法javascript
对象, apply 方法会被 webpack compiler 调用,并且在整个编译生命周期都可以访问 compiler 对象。
Plugin 是 Webpack 中的扩展器,在 Webpack 运行的生命周期中会广播出许多钩子事件,Plugin 可以监听这些事件,并挂载自己的任务,也就是注册事件。当 Webpack 构建的时候,插件注册的事件就会随着钩子的触发而执行了。
7.常用的Plugin
1.HtmlWebpackPlugin
2.CleanWebpackPlugin
3.CopyWebpackPlugin
4.Webpack.DefinePlugin 定义全局变量
5.MiniCssExtractPlugin
6.PurgeCSSPlugin 删除没用到的CSS样式,需要判断引用文件,起到css tree-shaking的效果
7.webpack.ProvidePlugin 配置全局模块,避免多次引入的麻烦
8.BundleAnalyzerPlugin 分析打包后资源的依赖以及大小
9.ImageminPlugin 压缩图片
10.CompressionPlugin 启用传输压缩,gzip压缩,需要服务端配合
11.webpack.NoEmitOnErrorsPlugin 遇到编译报错不输出
12.OptimizeCssAssetsPlugin 压缩css,去除重复的类名样式
13.UglifyJSPlugin 压缩JS
14.webpack.HotModuleReplacementPlugin 热更新插件
15.TerserPlugin 压缩es6,相比UglifyJsPlugin插件,能更好的处理ES6以上的语法
8.实现一个Plugin
9.Source map是什么?
source map是将编译、打包、压缩后的代码映射和回源代码的过程。打包压缩后的代码不具备良好的可读性,想要调试代码就需要source-map,提高开发效率
10.文件指纹是什么?
文件指纹是打包生成文件的唯一标识
文件指纹通常有两个用途:
-
版本管理: 在发布版本时,通过文件指纹来区分 修改的文件 和 未修改的文件。
-
使用缓存: 未修改的文件,文件指纹保持不变,浏览器继续使用缓存访问。
Hash 是和整个项目的构建相关,
compilation
实例的变化就会触发 Hash 的变化。Chunkhash 是和 webpack 打包的模块相关,每一个 entry 作为一个模块,会产生不同的 Chunkhash 值,所以他们之间的变化是互不影响的。
Contenthash 是和根据文件内容相关,比如一个页面内的 JS 内容、CSS 内容都会拥有自己的 Contenthash,可以保持各自的独立更新。