前言
又到一波面试准备的时刻,整理了一波前端相关要点内容,配合
chatGPT完成要点内容的整理输出,有纠正错误和需要补充的小伙伴可以在这里留言,及时更新。
- 跟chatGPT一起复习前端 —— HTML & CSS
- 跟chatGPT一起复习前端 —— JavaScript
- 跟chatGPT一起复习前端 —— Vue
- 跟chatGPT一起复习前端 —— React
- 跟chatGPT一起复习前端 —— Webpack
- 跟chatGPT一起复习前端 —— 浏览器
- 跟chatGPT一起复习前端 —— 计算机网络
- 跟chatGPT一起复习前端 —— Vite
- 跟chatGPT一起复习前端 —— TypeScript
- 跟chatGPT一起复习前端 —— 安全问题
- 跟chatGPT一起复习前端 —— 前端工具
- 跟chatGPT一起复习前端 —— 手写方法
- 跟chatGPT一起复习前端 —— 数据结构与算法
Webpack 是什么?
Webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 Webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个依赖图,然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于在浏览器中加载。
Webpack 可以将 JavaScript、CSS、HTML 和图片等文件打包成一个或多个 bundle。它还支持使用 loader 转换文件,例如将 TypeScript 转换为 JavaScript,或将 Sass 转换为 CSS。
Webpack 的核心概念是 loader 和 plugin。loader 用于转换某些类型的模块,而 plugin 则可以执行范围更广的任务,例如打包优化、资源管理和注入环境变量。
Webpack 构建流程
Webpack 的构建流程是一个串行的过程,从启动到结束会依次执行以下流程:
首先会从配置文件和 Shell 语句中读取与合并参数,并初始化需要使用的插件和配置插件等执行环境所需要的参数;初始化完成后会调用 Compiler 的 run 来真正启动 webpack 编译构建过程, webpack 的构建流程包括 compile 、 make 、 build 、 seal 、 emit 阶段。
- compile 阶段:从配置文件和 Shell 语句中读取与合并参数,并初始化需要使用的插件和配置插件等执行环境所需要的参数。
- make 阶段:从入口点分析模块及其依赖的模块,创建这些模块对象,然后递归地分析这些模块的依赖关系图,最终形成完整的依赖关系树。
- build 阶段:根据依赖关系图,调用配置文件中的 loader 对模块进行编译处理,最终得到每个模块被编译后的代码。
- seal 阶段:将每个模块编译后的代码封装成一个个 chunk,以 chunk 为单位进行优化和封装。
- emit 阶段:将所有 chunk 写入文件系统。
Webpack 的优化
Webpack 的优化主要包括以下几个方面:
- 分析目前的性能,使用 speed-measure-webpack-plugin 进行速度分析。
- 合理使用缓存来减少打包时间。
- 合理使用 plugin,减少打包时间和体积。
- 合理配置 relosve,防止减慢打包时间。
- 启用多进程打包。
- 使用热更新替换自动刷新。
- 使用 DllPlugin 插件,优化提高打包时间。
热更新的原理
webpack 热更新的原理是这样的:在 webpack 的 watch 模式下,文件系统中某一个文件发生修改,webpack 监听到文件变化,根据配置文件对模块重新编译打包,并将打包后的代码通过简单的 JavaScript 对象保存在内存中。webpack-dev-server 将这个简单的 JavaScript 对象与服务器进行通信,服务器将这个简单的 JavaScript 对象推送到客户端,客户端通过 webpack 的 HMR Runtime(Hot Module Replacement)对比这次代码变化前后的差异,决定是刷新整个页面还是局部刷新页面。
文件监听原理
在 Node.js 中,可以使用内置的 fs 模块来监听文件变化。fs.watch() 方法可以监听指定文件或目录的变化,当文件或目录发生变化时,会触发回调函数。
loader是什么?
在 webpack 中,loader 是一种用于将不同类型的文件转换为 webpack 可以处理的有效模块的机制。loader 可以让 webpack 处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,并添加到依赖图中。
plugins是什么?
在 webpack 中,plugin 是一种用于拓展 webpack 功能的机制。它们会在整个构建过程中生效,执行相关的任务。plugin 的目的在于解决 loader 无法实现的其他功能。插件可以用于执行范围更广的任务,例如打包优化、资源管理和注入环境变量等。
常用的 loader 与 plugin
常用的 webpack loader 包括:
-
样式:style-loader、css-loader、less-loader、sass-loader 等
-
文件:raw-loader、file-loader、url-loader 等
-
编译:babel-loader、coffee-loader、ts-loader 等
-
校验测试:mocha-loader、jshint-loader、eslint-loader 等 常用的 webpack plugin 包括:
-
清除 dist 目录:clean-webpack-plugin
-
压缩代码:uglifyjs-webpack-plugin
-
生成 html 文件:html-webpack-plugin
-
去除console:transform-remove-console
如何自定义loader
在 webpack 中,可以通过编写自定义 loader 来处理不同类型的文件。loader 是一个导出为函数的 node 模块,该函数在加载资源时调用。loader 可以将资源转换为新的格式,也可以将资源分成多个模块,或者将模块合并成一个模块等等。
编写一个 loader 需要遵循以下规则:
- loader 是一个 node 模块。
- loader 导出一个函数。
- loader 函数接受资源文件作为参数。
- loader 函数返回转换后的结果。
下面是一个简单的例子,该 loader 可以将所有 JavaScript 文件中的 console.log 语句删除:
module.exports = function(source) {
return source.replace(/console\.log\(.*\);?/g, "");
};
如何自定义plugin
自定义插件是指在webpack中,通过编写自己的插件来扩展webpack的功能。自定义插件需要遵循以下步骤:
- 创建一个JavaScript命名函数或JavaScript类。
- 在插件函数的prototype上定义一个apply方法。
- 指定一个绑定到webpack自身的事件钩子。
- 处理webpack内部实例的特定数据。
- 功能完成后调用webpack提供的回调。
下面是一个简单的示例插件,它可以生成一个资源列表的.md文件
class AssetsPlugin {
constructor(options) {
this.options = options;
}
apply(compiler) {
compiler.hooks.emit.tapAsync('AssetsPlugin', (compilation, callback) => {
let filelist = 'In this build:\n\n';
for (let filename in compilation.assets) {
filelist += `- ${filename}\n`;
}
compilation.assets['assets.md'] = {
source() {
return filelist;
},
size() {
return filelist.length;
},
};
callback();
});
}
}
source map 是什么?
Source Map 是一种文件,它可以将编译后的代码映射回原始源代码。它是一个信息文件,里面存储了代码打包转换后的位置信息,实质是一个 json 描述文件,维护了打包前后的代码映射关系。
在开发过程中,我们通常会将 JavaScript 和 CSS 文件压缩成一行或几行,这样可以减少文件大小并提高加载速度。但是,这样做会使得调试变得困难,因为我们无法直接看到源代码。这时候,Source Map 就派上用场了。它可以帮助我们将编译后的代码映射回原始源代码,从而方便调试。
webpack proxy工作原理?为什么能够解决跨域?
Webpack Proxy 是 Webpack 提供的代理服务,其基本行为是接收客户端发送的请求后转发给其他服务器。其目的是为了便于开发者在开发模式下解决跨域问题(浏览器安全策略限制)。
Webpack Proxy 的工作原理是:在 Webpack 配置文件中,通过 devServer.proxy 属性配置代理服务器,当 Webpack Dev Server 接收到请求时,会将请求转发到代理服务器,代理服务器再将请求转发到真正的服务器。这样就可以绕过浏览器的同源策略,实现跨域访问。
如何对bundle体积进行监控和分析?
你可以使用 VSCode 中的 Import Cost 插件来实时监测引入模块的大小,也可以使用 webpack-bundle-analyzer 来生成 bundle 的模块组成图,显示所占体积。bundlesize 工具包可以进行自动化资源体积监控。
文件指纹是什么?怎么用?
文件指纹是指通过文件的内容结合某种算法得到的唯一值,通常是文件的 MD5 值。在 webpack 中,通常是文件的哈希值。文件指纹通常有两个用途:版本管理,在发布版本时,通过文件指纹来区分修改的文件和未修改的文件;缓存控制,当文件内容发生变化时,文件名也会发生变化,从而避免浏览器缓存旧的文件。
你可以使用 Webpack 的 file-loader 或 url-loader 来为静态资源生成指纹。如果你使用了 create-react-app,那么你可以使用 craco-plugin-fingerprint 插件来为静态资源生成指纹。
Webpack 与 gulp 的区别?
Webpack 和 Gulp 都是前端构建工具,但它们的设计目标和使用方式有所不同。
Gulp 强调的是前端开发的流程,通过配置一系列的 task,定义 task 处理的事务(例如:文件压缩合并,启动 server),然后定义执行顺序,来让 Gulp 执行 task,从而构建其前端项目的流程。
而 Webpack 则本身就是为了模块化而出现的,压缩合并只是它附带的功能。Webpack 可以将 JavaScript、CSS、HTML 和图片等文件打包成一个或多个 bundle。它还支持使用 loader 转换文件,例如将 TypeScript 转换为 JavaScript,或将 Sass 转换为 CSS。Webpack 的核心概念是 loader 和 plugin。loader 用于转换某些类型的模块,而 plugin 则可以执行范围更广的任务,例如打包优化、资源管理和注入环境变量。