我有一个具有以下配置的应用程序。 Symfony(带有 laravel-mix)+ Vue + Vue Router。
问题:Webpack 找不到在路由中加载的 Vue 文件中应用的更改并更新我的 JS 文件(当我运行 npm run watch 时)。如果我更改了 App.vue 中的某些内容,则 webpack 会更新我的 app.js,但是如果我更新 Conversation.vue(如下文提供),它不会更新我的 app.js。我尝试过 laravel mix 提供的 laravel-mix-vue-auto-routing 但它什么也没做。 如果您想知道,Symfony 正用于操作应用程序的会话,就像 API 一样。
贝娄依赖配置
//webpack.mix.js
const path = require('path')
const mix = require('laravel-mix')
const glob = require('glob')
const webpack = require('webpack')
const { VuetifyPlugin } = require('webpack-plugin-vuetify')
const { PurgeCSSPlugin } = require('purgecss-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
mix.setPublicPath('public').webpackConfig({
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
},
plugins: [
new VuetifyPlugin({
styles: {
configFile: 'resources/sass/vuetify-config.scss'
}
}),
new webpack.DefinePlugin({
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false',
}),
new MiniCssExtractPlugin({
filename: "[name].css",
}),
mix.inProduction() ? new PurgeCSSPlugin({
paths: glob.sync(`${path.join(__dirname, 'public')}/**/*`, { nodir: true }),
}) : () => {} // Empty function to skip PurgeCSS in development
]
})
mix.js('resources/js/pages/app.js', 'public/js/pages/app.js').vue().version()
mix.sass('resources/sass/app.scss', 'public/css').version()
//router/index.js
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{
path: '/',
alias: ['/conversations'],
name: 'Conversations',
meta: { title: 'Conversations - Inbox' },
component: () => import('../components/Conversations/NoConversation.vue')
},
{
path: '/conversations/:id',
name: 'Conversation',
meta: { title: 'Conversations - Inbox' },
component: () => import('../components/Conversations/Conversation.vue'),
props: (route) => ({ conversationId: route.params.id })
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
//resources/js/pages/app.js
import router from '../router'
import { createApp } from 'vue'
import { pinia } from '../stores'
import { vuetify } from '../vuetify'
import { library } from '@fortawesome/fontawesome-svg-core'
import { fas } from '@fortawesome/free-solid-svg-icons'
import { far } from '@fortawesome/free-regular-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import App from '../components/App.vue'
import { useUserStore } from '../stores/user'
library.add(fas, far)
const app = createApp(App)
app.component('font-awesome-icon', FontAwesomeIcon)
app.use(pinia).use(router).use(vuetify)
await useUserStore().fetchData()
app.mount('#app')
resources/js/components/App.vue
<script setup>
import Header from './App/Header.vue'
import Layout from './Conversations/Layout.vue'
import NotFound from './App/NotFound.vue'
const { notFound } = defineProps({
notFound: Boolean
})
</script>
<template>
<v-app>
<v-main>
<NotFound v-if="notFound" />
<template v-else>
<Header />
<Layout>
<router-view />
</Layout>
</template>
</v-main>
</v-app>
</template>
src/Controller/IndexController.php
<?php
namespace App\Controller;
use App\Helper\ViewHelper;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class IndexController extends AbstractController
{
private ViewHelper $viewHelper;
public function __construct(ViewHelper $viewHelper)
{
$this->viewHelper = $viewHelper;
}
#[Route('/', name: 'homepage', methods: ['GET'])]
#[Route('/conversations', name: 'conversations', methods: ['GET'])]
#[Route('/conversations/{route}', name: 'catch_all', methods: ['GET'])]
public function index(): Response
{
$data = [
'title' => 'Inbox',
'component' => 'app',
];
return $this->render('views/index.html.twig', array_merge($data, $this->viewHelper->getCommonViewData()));
}
}
//package.json
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"prod": "npm run production",
"production": "mix --production",
"format": "prettier . --write"
},
"dependencies": {
"@fawmi/vue-google-maps": "^0.9.79",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@fortawesome/vue-fontawesome": "^3.0.6",
"@popperjs/core": "^2.11.8",
"@vueuse/core": "^10.7.1",
"axios": "^1.6.7",
"boxicons": "^2.1.4",
"glob": "^10.3.10",
"laravel-mix": "^6.0.49",
"mini-css-extract-plugin": "^2.8.0",
"mitt": "^3.0.1",
"moment": "^2.30.1",
"path": "^0.12.7",
"pinia": "^2.1.7",
"purgecss-webpack-plugin": "^5.0.0",
"vue": "^3.4.19",
"vue-auto-routing": "^1.0.1",
"vue-router": "^4.0.13",
"vuetify": "^3.5.5",
"webpack-plugin-vuetify": "^2.0.1"
},
"devDependencies": {
"@mdi/font": "^7.1.96",
"@rushstack/eslint-patch": "^1.7.2",
"@types/google.maps": "^3.54.4",
"@types/webpack-env": "^1.18.0",
"@vitejs/plugin-vue": "^5.0.4",
"@vue/compiler-sfc": "^3.2.45",
"@vue/eslint-config-prettier": "^9.0.0",
"autoprefixer": "^10.4.17",
"cross-env": "^7.0.3",
"eslint": "^8.49.0",
"eslint-plugin-vue": "^9.22.0",
"laravel-mix-vue3": "^0.7.0",
"postcss": "^8.4.35",
"resolve-url-loader": "^5.0.0",
"sass": "^1.57.1",
"sass-loader": "^13.2.0",
"tailwindcss": "^3.4.1",
"vue-loader": "^17.0.1",
"webpack": "^5.90.3"
}
修复
// webpack.mix.js
mix.setPublicPath('public').webpackConfig({
[...]
watchOptions: {
poll: true,
ignored: /node_modules/
},
[...]