构建工具
前端构建工具

构建工具

Generated by ChatGPT 4.0

pnpm

pnpm 解决 npm yarn 的哪些痛点?

幽灵依赖指的是

  • 安全, 避免幽灵依赖
  • 快且节省硬盘, 基于软/硬链接, node_modules 下是软链接, 硬链接到 .pnpm 文件夹下的硬链接
pnpm 有什么坑?  
  • 大版本更新比较痛苦, 可能升不上去

webpack

webpack 的四个模块是什么?常见的 loader 和作用?

Webpack 的四个核心概念:

入口(entry): Webpack 执行构建的第一步将从 Entry 开始, 可抽象为输入。 输出(output): 指示 webpack 如何处理、打包并且输出 bundle, 可抽象为输出。 加载器(loader): 让 webpack 能够处理那些非 JavaScript 文件( webpack 自身只理解 JavaScript)。 插件(plugin): 插件用于执行范围更广的任务。插件的范围包括, 从打包优化和压缩, 一直到重新定义环境中的变量等

常见的 loader 和作用:

babel-loader: 转换 ES6、ES7 等 JS 新特性语法 css-loader / style-loader: 处理 .css 文件, 转换为 JS 可以解析的模块 less-loader / sass-loader: 将 less、sass 转换为 css file-loader: 进行图片、字体等打包 url-loader: 和 file-loader 类似, 但是它可以返回一个 DataURL ts-loader: 将 TypeScript 转换为 JavaScript eslint-loader: 通过 ESLint 检查 JavaScript 代码

loaders 跟 plugin 的区别?

Loader 是一个转换器, 将 A 文件进行编译成 B 文件, 比如将 A.less 转换为 A.css, 单纯的文件转换过程。 Plugin 是一个扩展器, 它丰富了 webpack 本身, 针对是 loader 结束后, webpack 打包的整个过程, 它并不直接操作文件, 而是基于事件机制工作, 会监听 webpack 打包过程中的某些节点。

webpack 如何优化构建体积跟速度?

Tree Shaking: 移除 JavaScript 上下文中的未引用代码 Code Splitting: 将代码分离到不同的 bundle 中, 然后可以并行加载 Lazy Loading: 代码不是在初始化时加载, 而是需要的时候才加载 Minification: 通过 UglifyJS 插件压缩 JavaScript 代码 Optimize CSS Assets: 优化和压缩 CSS 代码 使用 DLLPlugin: 将改变不频繁的代码分离出来, 提高打包速度 使用 HappyPack: 多线程执行任务, 提高打包速度

Webpack 的热更新原理

Webpack 的热更新是通过 Hot Module Replacement 插件实现的。它在应用运行的过程中替换、添加或删除模块, 而无需重新加载整个页面。

Webpack 构建流程简单说一下

初始化参数: 从配置文件和 Shell 语句中读取与合并参数, 得出最终的参数。 开始编译: 用上一步得到的参数初始化 Compiler 对象, 加载所有配置的插件, 执行对象的 run 方法开始执行编译。 确定入口: 根据配置中的 entry 找出所有的入口文件。 编译模块: 从入口文件出发, 调用所有配置的 Loader 对模块进行翻译, 再找出该模块依赖的模块, 再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理。 完成模块编译: 在经过第 4 步使用 Loader 翻译完所有模块后, 得到了每个模块被翻译后的最终内容以及它们之间的依赖关系。 输出资源: 根据入口和模块之间的依赖关系, 组装成一个个包含多个模块的 Chunk, 再把每个 Chunk 转换成一个单独的文件加入到输出列表, 这步是可以修改输出内容的最后机会。 输出完成: 在确定好输出内容后, 根据配置确定输出的路径和文件名, 把文件内容写入到文件系统。

webpack 中如何处理图片的?

在 webpack 中, 可以使用 file-loader 或 url-loader 来处理图片。file-loader 会把图片复制到输出目录并返回图片的 URL。url-loader 会把小于限制大小的图片转换为 DataURL, 大于限制大小的图片还是使用 file-loader 处理。

如何对 bundle 体积进行监控和分析?

可以使用 webpack-bundle-analyzer 插件进行分析。它会创建一个可视化的树状图, 展示出打包后的所有模块的大小。

webpack-dev-server 的原理是什么?

webpack-dev-server 是一个基于 express 的小型服务器。它使用 webpack-dev-middleware 中间件服务于 webpack 的 bundle。除此之外, 它还有一个通过 Socket.IO 连接的客户端脚本。当初次构建完成后, 它会通过 socket 通知客户端脚本, 然后客户端脚本会刷新页面。

Webpack proxy 为什么能解决跨域

Webpack devServer 的 proxy 功能是基于 http-proxy-middleware 实现的, 它是一个代理服务器。当你的请求符合配置的规则时, 请求会被发送到指定的目标服务器, 然后代理服务器会将目标服务器的响应返回给客户端, 从而解决了跨域问题。

vite

说说对 Vite 的理解和 Vite 的实现原理

Vite( 法语中的 "快")是一个由 Vue.js 的作者 Evan You 开发的一个现代前端构建工具, 它主要由两部分组成: 一部分是一个轻量级的开发服务器, 利用浏览器的 ES 模块导入进行快速冷启动, 并提供模块热更新;另一部分是一个构建命令, 使用 Rollup 打包你的代码, 预配置输出高度优化的静态资源。

在开发模式下, Vite 有一个开发服务器, 它利用浏览器原生的 ES modules 进行模块加载, 当页面中的某个文件发生变化时, Vite 会直接推送更新的模块, 而不是整个页面, 这样就实现了快速的热更新。

在生产模式下, Vite 使用 Rollup 进行打包。Rollup 是一个高效的模块打包器, 可以利用 tree-shaking 技术去除无用代码, 并且 Rollup 支持将代码编译为 ES6 模块, 这样可以利用浏览器的模块加载机制来进行代码的并行加载。

Vite 开发模式和生产模式的区别

在开发模式下, Vite 服务器只会对被请求的文件进行转换和处理, 所以启动速度非常快。而且它会利用 HTTP/2 的多路复用能力, 能够更快地加载多个模块。

在生产模式下, Vite 会使用 Rollup 对整个应用进行预构建, 输出高度优化的静态资源。Rollup 能够生成更小的 bundle, 因为它可以消除无用的代码, 并且它支持更多的高级特性, 例如动态导入。

Webpack 和 vite 有什么区别
  1. 开发模式下的差异: Webpack 在开发模式下, 无论项目多大, 改动一个文件, 都需要对整个应用进行重新打包。这导致项目越大, 等待时间就越长。而 Vite 则利用了浏览器原生的 ES modules 进行模块加载, 只有被请求的文件会被处理, 所以开发环境启动非常快, 且修改文件后的热更新速度也非常快。

  2. 生产模式下的差异: Webpack 使用自身的打包算法进行打包, 而 Vite 则使用 Rollup 进行打包。Rollup 输出的 bundle 通常比 Webpack 更小, 因为 Rollup 可以更好地进行 tree-shaking 和代码的静态分析。

  3. 特性差异: Webpack 有很多内置功能和丰富的插件系统, 适合大型复杂的项目。Vite 则更轻量级, 更专注于开发体验, 例如快速的热更新, 且对 Vue.js 3 的支持更好。

  4. 配置差异: Webpack 的配置相对复杂, 而 Vite 则提供了更简单的配置方式。

Vite 的热更新原理是什么
  1. Vite 本地启动时会创建一个 WebSocket 连接,同时去监听本地的文件变化
  2. 当用户修改了本地的文件时,WebSocket 的服务端会拿到变化的文件的 ID 或者其他标识,并推送给客户端
  3. 客户端获取到变化的文件信息之后,便去请求最新的文件并刷新页面
Vite 打包主要做了哪些事?