webpack5
1、提升webpack5构建速度有哪些?
可以通过多种策略来提升webpack5的构建速度
- 使用持久化缓存
- webpack5引入了内置的持久化缓存功能,通过缓存模块和生成的代码块,可以在多个构建间重用这些信息,从而减少构建时间
- 优化配置文件
- 仔细审查和优化
webpack.config.js
文件,确保只加载需要的插件和加载器,避免不必要的开销
- 仔细审查和优化
- 多线程,并行处理
- 使用
thread-loader
,parallel-webpack
或者HappyPack
这类工具,将构建过程分布到多个进程或线程上,加快构建速度
- 使用
- 优化loaders加载器
- 限制加载器的作用范围,例如只在需要的文件类型或目录中时使用特定加载器
- 使用SWC、EsBuild等基于Rust或者Go的高性能loader
- 最小化入口
- 减少入口数量,每个额外的入口点都会增加构建时间
- 代码拆分和懒加载
- 使用
splitChunksPlugin
和动态导入(import())来实现代码拆分,减少单个代码块的大小,提高构建效率
- 使用
- 压缩和优化输出
- 使用压缩插件,如
TerserWebpackPlugin
来优化和压缩输出的javascript代码
- 使用压缩插件,如
- 利用外部模块(Externals)
- 将不经常更改的第三方库标记为外部,这样避免每次构建时都重复打包
- 使用更快的
source-map
源码映射- 如果在开发环境使用source-map,可选择
eval-source-map
- 如果在开发环境使用source-map,可选择
- 资源模块代替文本加载器 * 使用
webpack5
的资源模块(asset/resouce,asset/inline)来代替file-loader
和url-loader
- 移除效率低下的插件 * 使用
speed-measure-webpack-plugin
审查项目中的插件 - 将webpack升级到最新版本 * 确保使用最新的
webpack
和Node
版本,可以使用最新的性能改进 - 分析和监控构建性能 * 使用
webpack-bundle-analyzer
或speed-measure-webpack-plugin
这类工具来分析和监控构建过程
2、webpack5源码核心模块有哪几个,分别是什么作用?
- Compiler模块是Webpack的主要引擎,它负责创建编译对象,处理配置文件,并管理整个构建过程。它会启动构建,调用插件,生成最终的编译结果。
- Compilation模块是与每次构建关联的对象。它包含了此次构建的所有资源、依赖和其他相关信息。Compiler对每次构建都会创建一个新的Compilation对象。
- Module模块代表了一个模块或文件。Webpack通过不同类型的Module来处理不同类型的文件(如JavaScript、CSS等)。
- Chunk模块代表一个代码块,它是多个模块的集合。在输出阶段,Chunk将被转换成一个或多个文件。
- Loader模块用于转换模块内容。它们允许开发者编写自定义的加载逻辑来处理非JavaScript文件(如CSS、图片等)。
- Plugin模块提供了一个广泛的API,允许开发者创建自定义的插件,以参与并影响构建过程。插件可以在构建的不同阶段执行操作。
- Resolver模块负责解析模块的路径,将模块名(或路径)转换成实际的文件路径。
- FileSystem模块处理所有文件系统的操作。Webpack使用它来读取文件、监听文件变化等。
- Tapable是一个插件架构的核心库,Webpack使用它来实现事件驱动的架构。许多Webpack的核心对象都继承自Tapable。
- Template模块负责生成最终的输出文件。它根据Chunk生成结果代码。
- Output模块处理输出文件的写入。它根据Compilation的结果和配置的输出路径将文件写入文件系统,
3、如何保证loader按照预想的方式工作?
- 正确的配置
- 确保在vebpack.config.js文件中正确配置每个loader,这包括正确的匹配规则(通常使用test正则表达式来匹配文件类型)、正确的loader顺序以 及必要的选项设置。
- 理解Loader执行顺序
- Webpack的 loader遵循从右到左(或从下到上)的执行顺序。理解这一点对于配置 loader链至关重要,例如, use: ['style-loader', 'css- loader'中,css-loader将先于 style-loade执行
- 使用链式Loader
- 有时,一个文件类型需要通过多个loader处理。确保这些loader的组合是正确的,并且它们各自的输出能够被下一个loader正确处理。
- 版本兼容性
- 检查所有使用的loader是否与你的Webpack版本兼容。不兼容的loader版本可能导致构建失败或不按预期工作。
- 测试和验证
- 在开发环境中进行充分测试,以确保loader正确处理文件。可以通过调整配置和观察输出来验证loader是否按预期工作。
- 使用Loader的默认配置
- 许多loader提供默认配置,这些通常是推荐的使用方式,除非有特定需求,否则尽量使用默认配置。
- 阅读文档和实例
- 阅读每个loader的官方文档,理解其工作原理和配置选项。查看社区中的实例配置,特别是对于复杂的loader或常见的loader组合。
- 处理冲突
- 如果使用了多个loader处理相同类型的文件,确保它们之间不会产生冲突。例如,一个处理CSS的loader应该不会与另一个处理相同CSS的loader冲突。
- 优化性能
- 适当地配置loader可以提高构建性能。例如,通过include或exclude选项限制loader的作用范围。
- 调试和错误处理
- 如果loader不按预期工作,使用Webpack的调试工具和错误日志来诊断问题。有时,错误消息可以提供关于配置问题或冲突的有用信息。
4、描述babel原理
- 解析(Parsing)
- 词法分析出关键字
- 语法分析出表达式,最终生成出AST文件
- 转换(Transforming)
- 遍历AST
- 用插件或者预设(preset)应用转换,将高阶语法转为ES5
- 生成(Generating)
- Babel生成新的代码字符,构建出最终代码
- 也可以生成souremap,将生成的代码与原始代码对应起来,方便调试。
5、swc-loader比babel-loader好在哪里?
- swc是用Rust编写,比基于js编写的babel更快
- swc在编译过程中消耗更低的资源
- 由于rust的并发性,swc可以并发处理
- swc的配置更简洁
- swc尽力去兼容babel,项目迁移相对容易,但是有些特殊的插件swc还没有提供,有些插件还要调整和测试
- swc内置typescript支持,不需要额外配置ts
6. Vite原理
- 使用esbulid和rollup进行编译打包,开发环境使用go开发的Esbuild和服务器优化处理减少打包步骤
- 利用浏览器支持的ES模块加载,vite对模块做少量处理就可以直接丢给浏览器。
- vite优化node_modules,在第一次加载的时候对不支持ES模块的依赖通过EsBuild预构建成ESM,并做缓存处理
- 使用websocket与浏览器建立双向通信实现HMR热加载,vite能监听到所有有更改的模块,并更新,HMR是模块级的
- 插件可无缝链接的使用rollup插件
- CSS和图片等一些资源有特殊处理
- 开发环境不用打包,构建生产版本的时候使用rollup打包。
7、是否写过loader?
- 需要遵循webpack的一定步骤和原则,loader本质上是一个导出为函数的JavaScript模块,比如module.exports=一个function,这个函数会在文件处理时被调用
8、webpack热更新原理?
- webpack启动一个webpack dev server服务器,生成一个Manifest文件描述所有模块的依赖关系,
- webpack dev server提供一个websocket服务实现HMR,
- 基于文件系统的监听机制来检测源代码更新,当源码发生变化时,websocket将修改的模块发给客户端,客户端实现局部刷新,不需要刷新整个路由。
9、如何对bundle体积进行监控和分析
- 使用webpack插件webpack-bundle-analyzer生成模块组成图
- bundlesize工具包实现自动化资源体积监控
10、node_modules的包安全性问题如何解决
- 使用可信的包
- 定期扫描安全漏洞,npm audit,yarn audit等工具,将扫描功能集成到CI/CD中去
- 锁定依赖包的版本号
- 使用私有仓库
11、webpack-splitChunks是如何配置的
- chunks制定哪些chunk被优化,可用
all
、async
、initial
- minSize最小拆包体积,小于配置的包不会被拆
- maxSize最大拆包体积,webpack会尝试分割大于此值的chunk
- miniChunks模块引用次数达到这个值会被分配到新的chunk
12、目前构建工具有哪些?
- webpack
- rollup
- Vite
- Bun
13、three-shaking的工作原理
- three-shaking依赖ES6模块的静态结构特性,编译阶段就确定哪些模块是“死代码”,然后将其删除