Laravel v9.19开发环境:如何将config.js注入head标签提前执行?
解决Laravel+Vite中config.js在head中提前执行的问题
问题原因
当你使用@vite('resources/js/config.js')引入文件时,Vite默认会生成type="module"的script标签,这类标签默认采用defer加载机制——即等待整个HTML文档解析完成后才执行脚本。这就导致body中的同步脚本执行时,window.config还未被定义。
解决方案
方案1:将config.js打包为非模块脚本并同步加载
通过Vite配置修改config.js的输出格式,使其成为普通同步脚本,确保在head中加载时立即执行:
- 修改
vite.config.js:
import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; export default defineConfig({ plugins: [ laravel({ input: [ 'resources/scss/theme.scss', 'resources/scss/user.scss', 'resources/js/config.js', ], refresh: true, }), ], build: { rollupOptions: { output: { // 为config.js指定单独的输出规则 entryFileNames: assetInfo => { if (assetInfo.name === 'config') { return 'js/[name].js'; } return 'js/[name]-[hash].js'; }, format: 'iife', // 输出为立即执行函数,直接挂载全局变量 }, }, }, });
- 在
welcome.blade.php中直接引入编译后的脚本(无需@vite):
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> <!-- 同步加载config.js,确保在body解析前执行 --> <script src="{{ asset('js/config.js') }}"></script> </head>
- 开发环境下Vite dev server会自动处理资源路径;生产环境执行
npm run build后,config.js会输出到public/js/目录。
方案2:内联config.js内容到head标签
如果config.js内容简单,直接内联是最直接的解决方案,完全避免加载顺序问题:
<head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Laravel</title> <script> const config = { mode: 'dark' }; window.config = config; </script> </head>
方案3:调整body内脚本的执行时机
如果不想修改config.js的加载方式,可以让body中的脚本等待模块加载完成或DOM解析完成:
<body> <!-- 方式1:使用模块脚本导入config.js --> <script type="module"> import '../resources/js/config.js'; console.log(window.config); </script> <!-- 方式2:监听DOMContentLoaded事件 --> <script> document.addEventListener('DOMContentLoaded', () => { console.log(window.config); }); </script> </body>
补充说明
你之前使用的VitePluginEntryInject插件是针对所有入口文件的全局注入配置,但当你单独使用@vite('resources/js/config.js')时,该插件的规则不会生效——因为@vite是直接在当前位置生成脚本标签,而非依赖插件的自动注入逻辑。
内容的提问来源于stack exchange,提问作者Muazzem Ovi
相关产品推荐
相关产品推荐

