模块系统与打包工具

共 48 题
#

1. package.json exports 条件导出与类型解析(exports.types 条件、typesVersions 回退)的工程实践与常见踩坑

A typesVersions 只用于浏览器运行时解析,与类型无关
B exports 中未声明的子路径仍可通过 main 字段访问
C TS 解析类型时按条件顺序取第一个命中的条件,因此 "types" 条件应放在 import/require 之前 ✓ 正确答案
D 发布 CJS/ESM 双产物时只需提供一份 .d.ts 即可覆盖两种格式
#

2. dual package hazard(CJS/ESM 双实例)的成因(同一包被两种格式加载导致状态不一致)与治理(单实例设计、isomorphic 包)

A 同一包被 CJS 与 ESM 两种格式分别加载会得到两份实例,导致单例状态不一致 ✓ 正确答案
B dual package hazard 只会造成打包体积增大,不影响运行时行为
C 只要包内代码全部用函数式写法就不会出现双实例
D 双实例问题只出现在浏览器中,Node.js 不存在
#

3. Rspack 的 SWC 集成与自定义 loader 的 Rust 迁移路径

A 自定义 loader 迁移到 Rust 时应先保证功能等价,再针对瓶颈逐步替换 ✓ 正确答案
B Rspack 不支持任何自定义 loader,只能使用内置能力
C Rspack 内置的 SWC 转译可完整覆盖所有 Babel 插件能力
D 迁移到 Rust loader 后构建产物语义必然与 JS loader 完全一致,无需验证
#

4. TC39 Deferred Imports 提案 import defer(Stage 3)的声明式懒加载

A import defer 是运行时 API,必须在函数内部调用
B import defer 会把模块的语法错误推迟到运行时才暴露
C import defer 推迟模块的解析与实例化,但模块引用在编译期建立,打包器仍可静态分块 ✓ 正确答案
D import defer 与动态 import() 的语义完全相同
#

5. Rollup 的库打包与 esbuild 的转译职责

A Rollup 只能打包浏览器代码,不能用于库打包
B esbuild 的 tree-shaking 与产物精细度全面优于 Rollup
C Rollup 以 ESM 为中心擅长精确 tree-shaking 与多格式输出,esbuild 以极速转译见长,常被组合使用 ✓ 正确答案
D esbuild 完全无法做依赖预构建
#

6. Vite 的 SSR load/transform 钩子与 ssrLoadModule 在服务端模块转换的工程应用

A SSR 模式下 Vite 会把 node_modules 全部打进 bundle,无法外部化
B SSR 中 transform/load 钩子处理模块转换,ssrLoadModule 在服务端按需转换并执行模块且复用模块图缓存 ✓ 正确答案
C ssrLoadModule 是浏览器端加载模块的 API
D ssr.noExternal 的作用是强制把所有依赖打成一份 bundle,且不能配置
#

7. Vite SSR import.meta.env.SSR/.CLIENT 在 SSR 导入分支的工程价值

A import.meta.env.SSR 在 SSR 构建时为 true,是编译期替换的常量,静态分支可被 tree-shaking 消除 ✓ 正确答案
B import.meta.env.CLIENT 在 SSR 构建时恒为 true
C import.meta.env.SSR 是运行时环境变量,值可在请求期间改变
D 通过变量间接引用 import.meta.env.SSR 也能正常工作
#

8. Vite 8 的 import.meta.hot.accept 与 HMR API 在大型应用工程价值

A import.meta.hot.accept 只能用在 Vue/React 框架内,原生模块不可用
B 只要任意模块更新,浏览器必然整页刷新
C 模块更新时 HMR runtime 沿依赖图冒泡寻找最近的 accept 声明,dispose 用于清理旧模块资源 ✓ 正确答案
D import.meta.hot 在生产构建中依然执行热更新逻辑
#

9. Turbopack 的 Rust 增量构建与 Webpack 兼容层

A Turbopack 用 Rust 实现,通过增量计算图与持久化缓存只重算受影响部分,但其 Webpack 插件生态兼容并不完整 ✓ 正确答案
B Turbopack 的增量构建仍会全量重算所有模块
C Turbopack 完全兼容所有 Webpack loader 与插件
D Turbopack 不支持任何缓存复用
#

10. Babel/SWC/Oxc(Oxidation Compiler)

A Babel 是 Rust 实现,性能优于 SWC
B Oxc 只能做转译,不能做 Lint
C SWC 与 Oxc 都是 Rust 实现,Oxc 还覆盖 oxlint 等一体化能力,三者可按职责组合使用 ✓ 正确答案
D SWC 的插件生态完整覆盖所有 Babel 插件
#

11. Vite 最新版的 optimizeDeps.esbuildOptions 在依赖预构建含 CJS/ESM 互操作的工程价值

A optimizeDeps.esbuildOptions 可向预构建的 esbuild 传入 plugins、define 等选项,用于治理 CJS/ESM 互操作与全局引用问题 ✓ 正确答案
B esbuildOptions 只能修改预构建产物的文件名
C optimizeDeps 预构建只能处理 ESM 依赖,不能处理 CJS
D Vite 预构建的目的是让依赖代码运行更快,与模块格式无关
#

12. Webpack 仅作为备选 flag 的迁移策略

A Webpack 作为备选 flag 意味着永远保留两套构建,不能移除
B 双引擎迁移无需验证产物差异,只要构建成功即可
C flag 迁移策略只适用于 Webpack 到 Rspack,不适用于其他构建器
D 迁移时应通过 flag 保留旧引擎兜底,并用双构建金丝雀验证产物语义等价,而非只比较构建耗时 ✓ 正确答案
#

13. ESM 与 CJS 在 Node.js 与浏览器的工程边界与互操作

A require() 无法加载任何 ESM 模块
B ESM 模块可以在运行时任意修改导出内容
C 浏览器只支持原生加载 ESM,CJS 需经打包器转换;Node.js 中新代码应优先采用 ESM ✓ 正确答案
D import 加载 CJS 时必然得到 undefined 的命名导出
#

14. Vite 6+ 相比 Webpack 5 在开发体验(HMR、启动速度)

A Vite 采用原生 ESM 按需转换加依赖预构建,冷启动与 HMR 不随项目规模线性劣化,而 Webpack 5 是启动即全量打包 ✓ 正确答案
B Vite 开发服务器启动时也会打包全部依赖
C Webpack 5 的 HMR 比 Vite 更快,因为它是 bundle 型
D Vite 的 HMR 只能整页刷新
#

15. Rolldown(Rust 实现的 Rollup 兼容打包器)

A Rolldown 是完全独立的新插件体系,Rollup 插件全部不可用
B Rolldown 只能打包,不能做 tree-shaking
C Rolldown 是 Rust 实现的 Rollup 兼容打包器,通过插件桥接层兼容 Rollup 生态,并计划作为 Vite 的生产构建底座 ✓ 正确答案
D Rolldown 与 Vite 无关,是独立项目
#

16. Vite 的 import.meta.glob 在多文件批量导入的工程价值

A import.meta.glob 接受运行时变量拼出的路径
B import.meta.glob 只能用于导入图片资源
C import.meta.glob 在编译期按 glob 模式扫描文件生成静态映射,支持 eager 与懒加载模式 ✓ 正确答案
D glob 结果会在文件新增时自动实时更新,无需重启
#

17. Module Federation 2.0 的微前端共享与远程模块加载

A 远程模块一旦构建即固定,无法在运行时切换
B Module Federation 只能用于 webpack,其他打包器无法使用
C Module Federation 的共享依赖会为每个远程模块单独实例化,无法单例
D Module Federation 2.0 通过独立运行时支持动态远程模块与多打包器集成,并可在运行时按 semver 协商共享依赖单例 ✓ 正确答案
#

18. Turbopack 在 Next.js 15(Turbopack 稳定版)

A Next.js 15 中 Turbopack 已完全兼容所有 webpack 插件与配置
B 启用 Turbopack 后无法回退到 webpack
C Turbopack 只支持 dev 模式,不支持生产构建
D Next.js 15 将 Turbopack 标记为稳定,可经 --turbopack 启用,但部分 webpack 配置与插件仍需核对兼容性并保留回退 ✓ 正确答案
#

19. Rspack 2.1.x(Rust 实现、兼容 Webpack 生态)

A Rspack 2.1.x 用 Rust 实现并兼容 webpack 配置与 loader/插件体系,迁移时应用双构建金丝雀验证产物语义而非只比构建耗时 ✓ 正确答案
B Rspack 的构建速度与 webpack 相同
C Rspack 无法使用任何 webpack loader 与插件
D 迁移到 Rspack 无需验证产物差异
#

20. 浏览器 ESM、动态 import() 与依赖图构建

A 浏览器原生 ESM 会阻塞页面解析
B 动态 import() 在浏览器中不可用
C 浏览器按 import 语句递归抓取模块构建运行时依赖图,动态 import() 实现按需请求,打包器产物与原生 ESM 可配合获得按需加载与长缓存 ✓ 正确答案
D 原生 ESM 模块每次请求都会重复执行
#

21. Vite 的环境变量 import.meta.env 与类型生成 在大型团队的可维护性

A import.meta.env 支持在函数内动态拼接访问
B import.meta.env 的值可以在运行时由代码动态修改
C .env 文件中的全部变量都会暴露给浏览器
D 只有 VITE_ 前缀的环境变量会暴露给客户端,import.meta.env 在构建期静态替换,团队可配合类型声明与示例文件治理 ✓ 正确答案
#

22. vite-plugin-legacy/@vitejs/plugin-legacy 在传统浏览器兼容的工程取舍

A @vitejs/plugin-legacy 会让所有浏览器都加载 legacy 产物
B 使用该插件后现代浏览器也会加载双份脚本
C 该插件只做语法转译,不处理 polyfill
D @vitejs/plugin-legacy 生成 legacy 产物与 polyfill,通过 nomodule 回退让旧浏览器降级加载,但会增大产物体积与构建时间 ✓ 正确答案
#

23. Vite 的 defineConfig/define 与环境变量 在大型项目构建链的工程价值

A define 的替换发生在运行时,值可以动态改变
B define 只能定义对象,不能定义字符串
C defineConfig 提供类型提示并可结合 loadEnv 读取环境变量,define 在编译期把全局常量替换为字面量,适合注入版本号等构建期信息 ✓ 正确答案
D Vite 中所有环境变量都会自动注入到 import.meta.env
#

24. Turbopack 在 Next.js 15 的工程边界与性能取舍

A Turbopack 在 Next.js 15 中支持全部 webpack 配置与插件
B Turbopack 在 Next.js 15 中核心链路稳定,但仍有配置与插件兼容边界,应采用数据对比与回退机制做工程取舍 ✓ 正确答案
C 启用 Turbopack 后无法再使用 App Router
D Turbopack 只提升构建速度,不影响 HMR
#

25. esbuild 在依赖预打包(Vite prebundle)的工程价值

A Vite 预打包会把所有源码也一起打包
B Vite 用 esbuild 对依赖做预打包,实现 ESM 化、依赖扁平化与请求收敛,并以 lockfile 为缓存键复用结果 ✓ 正确答案
C 预打包与生产构建总是产生完全相同的产物
D 预打包只能处理 ESM 依赖
#

26. Rspack 的 experiments.outputModule 与 ESM 产物 在大型团队的可维护性

A experiments.outputModule 会输出 CJS 格式产物
B ESM 产物无法被浏览器直接加载
C experiments.outputModule 输出原生 ESM 产物,带来更彻底的 tree-shaking 与生态一致性,但需注意 CJS 依赖的 interop 与旧浏览器兼容 ✓ 正确答案
D outputModule 开启后所有 CJS 依赖都会报错
#

27. Bun/Deno 与 Node 在打包链中的互操作边界(模块解析算法、内置模块、lockfile 格式差异)

A Bun、Deno 与 Node 的模块解析算法完全一致
B Bun 与 Deno 无法运行任何 Node 项目
C 三者解析算法、内置模块与 lockfile 格式存在差异,团队应锁定单一包管理器与 lockfile 格式,并以 Node 为基准做兼容验证 ✓ 正确答案
D lockfile 格式差异不影响打包器行为
#

28. SWC 在代码转译(Babel 替代)的工程性能与生态取舍

A SWC 的插件生态与 Babel 完全一致
B SWC 不支持 TS 与 JSX 转译
C SWC 用 Rust 实现转译,性能远优于 Babel,但自定义 Babel 插件大多无法直接复用,需按项目插件依赖程度取舍 ✓ 正确答案
D SWC 只能做压缩,不能做转译
#

29. Vite 6+ 的 optimizeDeps 在依赖预构建的工程配置边界

A exclude 不会带来任何副作用
B Vite 能自动扫描所有动态加载的依赖,无需 include
C optimizeDeps.include 用于强制预构建扫描遗漏的依赖,exclude 用于排除无法转换或需原生加载的依赖 ✓ 正确答案
D optimizeDeps 配置只对生产构建生效
#

30. Vite 6+ 的 build.rollupOptions 在自定义打包配置的现代实践

A build.rollupOptions 透传 Rollup 配置,可用于多入口、manualChunks 依赖分组与构建期插件注入,拆分策略应基于产物分析数据 ✓ 正确答案
B build.rollupOptions 只能配置入口,不能配置输出
C Vite 生产构建不经过 Rollup,rollupOptions 无效
D manualChunks 拆得越细性能越好
#

31. Bun 1.2 作为运行时与打包器相较 Node.js 的工程取舍

A Bun 与 Node 的 API 完全一致,可直接替换
B Bun 不能运行任何 Node 项目
C bun build 与 esbuild 完全无关
D Bun 提供运行时、打包器与包管理器一体化能力且性能优越,但 Node 原生模块兼容与部署生态是主要风险,建议渐进引入 ✓ 正确答案
#

32. Nitro 2(Nuxt 3 底层)在跨平台部署的工程价值

A Nitro 只能部署到 Node 服务器
B Nitro 与 Nuxt 无关,只能独立使用
C Nitro 通过预设体系为 Node、Serverless、Edge 等平台生成适配产物,实现一份代码跨平台部署 ✓ 正确答案
D Nitro 不具备缓存与静态化能力
#

33. Vite 6+ 的 SSR 配置(ssr.noExternal、ssr.target)的工程应用

A ssr.target 只能设为 node
B ssr.noExternal 用于把所有依赖都排除在 bundle 外
C SSR 构建中 Node 内置模块也会被打包进产物
D ssr.noExternal 控制依赖是否打进 SSR bundle,ESM-only 或依赖 Vite 特性的包应列入其中,ssr.target 指定运行环境 ✓ 正确答案
#

34. Vite 6+ 的 resolve.alias 与 resolve.extensions 在路径解析的工程实践

A resolve.extensions 的顺序只影响性能,不影响解析结果
B Vite 的别名配置只对浏览器端生效,SSR 不生效
C resolve.alias 不能用于替换库实现
D resolve.alias 支持 $ 精确匹配与正则,工程上应把别名同步到 tsconfig paths 与编辑器配置以保持解析一致 ✓ 正确答案
#

35. Tree-shaking 在 ESM 与 CJS 的工程差异与 sideEffects 字段的应用

A CJS 与 ESM 的 tree-shaking 效果相同
B sideEffects: false 声明后所有模块都会被删除
C ESM 静态导出使摇树更彻底,sideEffects: false 允许打包器删除未使用模块,但必须与真实副作用一致,否则会误删有副作用的代码 ✓ 正确答案
D 打包器无法对 ESM 做摇树
#

36. Vite 6+ 的 CSS Modules、PostCSS 与 CSS 预处理器(Sass)

A Vite 中 .css 文件不能使用 CSS Modules
B Vite 通过 *.module.css 自动启用 CSS Modules,PostCSS 处理插件链,预处理器经 preprocessorOptions 配置,三者分层协作 ✓ 正确答案
C Sass 文件在 Vite 中必须手工编译
D Vite 不支持 PostCSS 配置
#

37. 代码分割(dynamic import)的 chunk 命名与缓存策略的工程应用

A 代码分割后所有 chunk 共享同一个文件名
B chunk 文件名只要唯一即可,无需考虑可读性
C 用稳定命名加 contenthash 文件名,配合 immutable 缓存头可获得长期缓存,同时保证产物可排查 ✓ 正确答案
D contenthash 会让每次构建都改变所有文件名
#

38. Vite 6+ 的 legacy 插件在老旧浏览器兼容的现代实践

A legacy 插件应始终兼容到 IE6
B 现代实践是根据用户浏览器数据设置 targets 并持续监控 legacy 产物占比,逐步收窄或移除兼容范围 ✓ 正确答案
C legacy 产物与 modern 产物使用相同缓存策略即可
D 启用 legacy 插件不影响构建时间
#

39. Vite 6+ 的 import.meta.glob 在动态资源加载的工程应用

A import.meta.glob 只能导入 JS 模块
B import.meta.glob 可配合 ?url、?raw、?worker 等 query 定制资源导入语义,适合目录化资源批量接入 ✓ 正确答案
C glob 支持运行时动态计算路径
D 使用 glob 导入的资源无法被 tree-shaking
#

40. Source maps 在生产环境(hidden source maps)

A 生产环境应把 source map 与产物一起公开部署
B source map 只对开发调试有用,生产无用
C hidden source maps 不把映射注释写入产物,map 单独上传错误监控平台,兼顾线上定位与源码保护 ✓ 正确答案
D nosources-source-map 会包含完整源码内容
#

41. Vite 6+ 的依赖升级(vite deps)与自动 lockfile 更新的工程实践

A lockfile 更新与预构建缓存无关
B Vite 的预构建缓存永不失效
C 依赖升级后 Vite 会基于 lockfile 内容自动失效并重建预构建,工程上应在升级 CI 中做产物对比与回归验证 ✓ 正确答案
D 依赖升级不需要回归测试
#

42. Vite 6+ 与 Vitest 单元测试的工程协作与配置复用

A Vitest 使用独立的模块解析,与 Vite 配置无关
B Vitest 无法与 monorepo 协作
C Vitest 不能使用 jsdom 环境
D Vitest 复用 Vite 的 alias、plugins 与模块图,测试与构建共享解析链路,同时用 test 字段隔离测试专属配置 ✓ 正确答案
#

43. Vite 切换 Rolldown 后,依赖 Rollup 插件钩子顺序、this.getModuleInfo、virtual module 或 manualChunks 的插件可能出现哪些兼容差异

A Rolldown 与 Rollup 的插件行为完全一致
B this.getModuleInfo 在 Rolldown 中不存在
C manualChunks 在 Rolldown 中不被支持
D Rolldown 兼容 Rollup 插件但钩子顺序、this.getModuleInfo、virtual module 与 manualChunks 可能存在差异,需行为对比与适配验证 ✓ 正确答案
#

44. Vite 6/7 中依赖预构建使用 esbuild、生产构建使用 Rollup 时,CJS 动态 require、条件导出和同一依赖的双实例问题应如何定位,并保证 dev 与 build 行为一致

A dev 预构建(esbuild)与生产构建(Rollup)对 CJS 动态 require、条件导出的处理存在差异,需对齐配置并增加 dev/build 一致性验证 ✓ 正确答案
B 双实例问题只存在于生产环境
C 条件导出在 dev 与 build 中总是命中相同分支
D esbuild 与 Rollup 对依赖的处理完全一致,无需关心
#

45. 从 Webpack 迁移到 Rspack 2.1.x 时,如何盘点自定义 loader、compiler/compilation hooks、Module Federation、HMR 与 source map 的兼容层,并设计双构建金丝雀验证产物语义而非只比较构建耗时

A 迁移验证只需比较两引擎的构建耗时
B 迁移应盘点 loader、hooks、MF、HMR、source map 兼容层,并用双构建金丝雀对比产物语义,耗时仅供参考 ✓ 正确答案
C Rspack 与 webpack 的钩子行为必然一致
D 金丝雀验证通过后无需保留回退
#

46. Tailwind 4.x 中用 logical-property utilities 替换 left/right、margin-left 等物理属性时,如何验证 LTR/RTL、vertical writing mode 与旧浏览器降级,并防止组件库仍输出相互冲突的物理属性

A logical properties 在 LTR 与 RTL 下行为完全相同
B Tailwind 4.x 的 logical utilities 可随书写方向自动翻转,工程上需结合 RTL/vertical 视觉回归、旧浏览器降级与 lint 约束防止物理属性冲突 ✓ 正确答案
C 使用 logical utilities 后无需任何回归测试
D 物理属性与逻辑属性可以随意混用
#

47. 如何在 Tailwind 4.x 用 @custom-variant/@variant 表达 data-state、supports 和容器状态,同时统一原生 scrollbar-* 与 WebKit scrollbar 样式,并通过生成 CSS 检查控制变体爆炸和跨浏览器回退

A Tailwind 4.x 的 @custom-variant 可定义 data-*、supports 与容器状态变体,scrollbar 样式需按引擎分支统一封装,并应检查生成 CSS 控制变体爆炸 ✓ 正确答案
B ::-webkit-scrollbar 已被所有浏览器支持
C @custom-variant 只能用于悬停状态
D 自定义变体不会影响生成 CSS 的体积
#

48. esbuild 的 transform/build API 与插件在单文件转译与 bundle 产物的性能取舍

A transform 与 build 的输入输出完全一致
B transform 做无依赖图的高频单文件转译,build 做完整打包并支持插件体系,按是否需要依赖图与产物管理选型 ✓ 正确答案
C build API 无法输出多格式产物
D 插件只能在 transform 中使用