
vite 在构建 laravel 10 项目时,会因 tree shaking 机制误删未显式导出或调用的全局函数,导致如 global.js 等入口文件编译后仅剩部分代码,本文详解成因与专业级修复方案。
vite 在构建 laravel 10 项目时,会因 tree shaking 机制误删未显式导出或调用的全局函数,导致如 global.js 等入口文件编译后仅剩部分代码,本文详解成因与专业级修复方案。
在 Laravel 10 中集成 Vite 后,执行 npm run build 时出现 JS 文件内容“被清空”的现象(例如 global.js 编译后只剩 Swal.mixin({...}) 一行),本质并非 Vite 故意破坏代码,而是其默认启用的 Tree Shaking(摇树优化) 机制将未被显式引用的函数判定为“无用代码”并移除。
Vite(底层基于 Rollup)在生产构建中会深度分析模块依赖图。而你的 global.js 文件中定义了大量工具函数(如 BoxInfo、CreateToast、SelectAll 等),但未通过 export 导出,也未在任何其他模块中 import 调用——Vite 无法识别这些函数将在运行时被全局作用域(如 Blade 模板中的内联 <script> 或事件绑定)动态调用,因此将其视为“死代码”(dead code)予以剔除。</script>
✅ 正确解决方案:显式声明全局可访问性
最稳定、符合 Vite 设计哲学的方式是:将需全局可用的函数挂载到 window 对象上,并向 Vite 明确声明这些符号不应被摇树移除。
✅ 推荐修复步骤(以 resources/js/global.js 为例)
- 在文件末尾显式挂载关键函数到 window:
// ...(原有全部函数定义保持不变) // ? 关键:显式暴露至全局作用域,阻止 Tree Shaking window.Box = Box; window.BoxInfo = BoxInfo; window.BoxConfirm = BoxConfirm; window.CreateToast = CreateToast; window.SelectAll = SelectAll; window.SelectAlternate = SelectAlternate; window.DeleteSelected = DeleteSelected; window.DeleteSingle = DeleteSingle; window.DeleteSingleFromShow = DeleteSingleFromShow; window.ResetForm = ResetForm;
确保该文件被正确纳入 Vite 入口(已在 vite.config.js 中配置,无需改动):
你当前的 input 数组已包含 'resources/js/global.js',这是正确的。(可选但推荐)禁用针对该文件的摇树提示(增强健壮性):
在 vite.config.js 的 build.rollupOptions 中添加 treeshake: false 仅对特定文件生效较复杂;更通用的做法是——在 global.js 顶部添加注释指令,告知打包器保留所有内容:
// resources/js/global.js // @ts-nocheck // vite-ignore // --- DO NOT TREE-SHAKE THIS FILE --- // All functions below are used globally via Blade templates or inline scripts. // ...(后续原有代码)
? 提示:// vite-ignore 并非 Vite 官方指令,但结合 /*#__PURE__*/ 注释或 /*#__NO_SIDE_EFFECTS__*/ 可影响某些场景。实际中最可靠方式仍是显式挂载 window.xxx。
⚠️ 注意事项与最佳实践
-
避免重复引入相同文件:你当前 vite.config.js 中 'resources/js/global.js' 被列出了两次(第 8 和第 9 行),请删除重复项,否则可能引发不可预期行为:
- 'resources/js/global.js', - 'resources/js/global.js', // ← 删除这一行
不要关闭全局 Tree Shaking:在 vite.config.js 中设置 build.treeshake: false 会显著增大最终包体积,且违背现代构建理念,不推荐。
验证是否生效:构建后检查 public/build/assets/global-*.js,应完整保留所有函数定义及 window. 挂载语句。
-
进阶建议(长期维护):
将全局工具函数重构为 ES 模块,按需导入:// resources/js/utils/toast.js export function CreateToast({ message, background = 'text-bg-primary' }) { /* ... */ } // resources/js/app.js import { CreateToast } from './utils/toast'; window.CreateToast = CreateToast; // 仍挂载供旧模板使用这样既保留向后兼容性,又为未来模块化演进打下基础。
✅ 总结
| 问题根源 | Vite 生产构建默认启用 Tree Shaking,将未被静态分析识别为“被使用”的全局函数清除 |
|---|---|
| 核心解法 | 所有需全局调用的函数,必须显式赋值给 window 对象(如 window.CreateToast = CreateToast) |
| 关键动作 | 删除 vite.config.js 中重复的 global.js 条目;确保挂载语句位于文件末尾;构建后验证输出完整性 |
遵循此方案,npm run build 将生成完整、可用的 JS 文件,彻底解决 Laravel 10 + Vite 下“函数消失”问题。










