Laravel修改resources目录JS文件后,npm run dev不生效如何解决?
Laravel Vite开发模式下JS修改不生效的解决思路
问题描述
我是编程新手,近期正在使用Laravel框架开发网站。发现每次修改/resources目录下的JavaScript文件时,必须运行npm run build才能在网站上看到更新。了解到Vite后,使用npm run dev修改JS文件仍无法生效,附上vite配置、package.json及文件夹结构,恳请各位提供解决思路,谢谢。
我的Vite配置
import { defineConfig } from 'vite'; import laravel, { refreshPaths } from 'laravel-vite-plugin'; import fs from 'fs-extra'; import path from 'path'; const folder = { src: "resources/", // 源文件目录 src_assets: "resources/", // 源资源目录 dist: "public/", // 构建输出目录 dist_assets: "public/build/" // 构建资源输出目录 }; export default defineConfig({ build: { manifest: true, rtl: true, outDir: 'public/build/', cssCodeSplit: true, rollupOptions: { output: { assetFileNames: (css) => { if (css.name.split('.').pop() == 'css') { return 'css/' + `[name]` + '.min.' + 'css'; } else { return 'icons/' + css.name; } }, entryFileNames: 'js/' + `[name]` + `.js`, }, }, }, plugins: [ laravel( { input: [ 'resources/scss/bootstrap.scss', 'resources/scss/icons.scss', 'resources/scss/app.scss', 'resources/scss/custom.scss', ], refresh: [ ...refreshPaths, 'resources/views/**', ], } ), { name: 'copy-specific-packages', async writeBundle() { try { // 复制图片、json、字体和js await Promise.all([ fs.copy(folder.src_assets + 'fonts', folder.dist_assets + 'fonts'), fs.copy(folder.src_assets + 'images', folder.dist_assets + 'images'), fs.copy(folder.src_assets + 'js', folder.dist_assets + 'js'), fs.copy(folder.src_assets + 'json', folder.dist_assets + 'json'), ]); } catch (error) { console.error('复制资源出错:', error); } const outputPath = path.resolve(__dirname, folder.dist_assets); // 调整目标路径 const configPath = path.resolve(__dirname, 'package-copy-config.json'); try { const configContent = await fs.readFile(configPath, 'utf-8'); const { packagesToCopy } = JSON.parse(configContent); for (const packageName of packagesToCopy) { const destPackagePath = path.join(outputPath, 'libs', packageName); const sourcePath = (fs.existsSync(path.join(__dirname, 'node_modules', packageName + "/dist"))) ? path.join(__dirname, 'node_modules', packageName + "/dist") : path.join(__dirname, 'node_modules', packageName); try { await fs.access(sourcePath, fs.constants.F_OK); await fs.copy(sourcePath, destPackagePath); } catch (error) { console.error(`包 ${packageName} 不存在。`); } } } catch (error) { console.error('复制并重命名包出错:', error); } }, }, ], });
package.json
{ "private": true, "name": "cfm", "version": "1.0", "type": "module", "author": "test", "scripts": { "clean": "rimraf public/build", "dev": "vite dev", "build": "npm run clean && vite build", "build-rtl": "rtlcss public/build/css/app.min.css & rtlcss public/build/css/bootstrap.min.css" }, "devDependencies": { "@popperjs/core": "^2.10.2", "axios": "^1.6.5", "laravel-vite-plugin": "^1.0.1", "lodash": "^4.17.19", "popper.js": "^1.12", "postcss": "^8.3.5", "postcss-import": "^14.0.1", "resolve-url-loader": "^5.0.0", "rimraf": "^5.0.1", "rtlcss": "^3.0.0", "sass-loader": "^11.0.1", "vite": "^5.0.12" }, "dependencies": { "@ckeditor/ckeditor5-build-classic": "^38.0.1", "@simonwep/pickr": "^1.8.2", "@tarekraafat/autocomplete.js": "^10.2.7", "aos": "^2.3.4", "apexcharts": "^3.41.0", "bootstrap": "5.3.2", "card": "^2.5.4", "chart.js": "4.3.0", "choices.js": "^10.2.0", "cleave.js": "^1.6.0", "dom-autoscroller": "^2.3.4", "dragula": "^3.7.3", "dropzone": "^6.0.0-beta.2", "echarts": "^5.4.2", "feather-icons": "^4.29.0", "fg-emoji-picker": "^1.0.1", "filepond": "^4.30.4", "filepond-plugin-file-encode": "^2.1.10", "filepond-plugin-file-validate-size": "^2.2.8", "filepond-plugin-image-exif-orientation": "^1.0.11", "filepond-plugin-image-preview": "^4.6.11", "flatpickr": "^4.6.13", "fs": "^0.0.1-security", "fs-extra": "^11.2.0", "fullcalendar": "^6.1.8", "glightbox": "^3.2.0", "gmaps": "^0.4.25", "gridjs": "^6.0.6", "isotope-layout": "^3.0.6", "jsvectormap": "1.4.2", "leaflet": "^1.9.4", "list.js": "^2.3.1", "list.pagination.js": "^0.1.1", "masonry-layout": "^4.2.2", "moment": "^2.30.1", "multi.js": "^0.5.3", "node-waves": "^0.7.6", "nouislider": "^15.7.0", "particles.js": "^2.0.0", "prismjs": "^1.29.0", "quill": "^1.3.7", "rater-js": "^1.0.1", "sass": "^1.69.5", "shepherd.js": "^11.1.1", "simplebar": "^6.2.5", "sortablejs": "^1.15.0", "sweetalert2": "^11.6.13", "swiper": "^9.3.2", "toastify-js": "^1.12.0", "wnumb": "^1.2.0" } }
文件夹结构
resources目录下包含fonts、images、js、json、scss、views子目录,public目录下有build文件夹。
解决步骤
1. 将JS文件加入Vite入口配置
当前Vite配置的laravel插件input数组仅包含SCSS文件,未添加JS文件。Vite只会监听入口文件及其依赖的变化,需把你的JS主文件添加进去:
laravel({ input: [ 'resources/scss/bootstrap.scss', 'resources/scss/icons.scss', 'resources/scss/app.scss', 'resources/scss/custom.scss', // 添加你的JS入口文件,比如主逻辑文件 'resources/js/app.js' ], refresh: [ ...refreshPaths, 'resources/views/**', ], })
若有多个JS文件,全部添加到input数组即可。
2. 移除手动复制JS的逻辑
自定义的copy-specific-packages插件中,writeBundle钩子仅在vite build时触发,开发模式下不会执行,导致修改JS后无法自动同步到public目录。且Vite开发模式通过HMR(热模块替换)直接推送更新到浏览器,无需手动复制文件。
删除插件中复制JS的代码:
// 移除这一行 fs.copy(folder.src_assets + 'js', folder.dist_assets + 'js'),
3. 确保视图正确使用Vite指令
Blade视图中必须使用@vite指令引入资源,不能直接引用public/build下的静态文件:
{{-- 正确写法 --}} @vite(['resources/js/app.js', 'resources/scss/app.scss']) {{-- 错误写法:直接引用静态文件,开发模式下不会更新 --}} <script src="{{ asset('build/js/app.js') }}"></script>
4. 检查开发服务器状态
- 确保
npm run dev命令正在运行,终端无报错 - 打开浏览器控制台,查看是否有Vite连接错误(如端口被占用)
- 清除浏览器缓存或使用无痕模式测试,避免加载旧的JS缓存文件
5. 可选:调整Vite资源处理逻辑
若JS文件依赖图片、字体等静态资源,无需手动复制,Vite会自动处理资源引用路径。
内容的提问来源于stack exchange,提问作者NewbieIsHere
相关产品推荐
相关产品推荐

