在使用 webpack 之前,我的 vue 路由工作得很好。然而,我开始遇到一堆加载器问题,因此决定使用 webpack。然而,在我的 webpack 运行后,主页加载正常,但我所有的路由现在都是 404。所有被注释掉的东西都是我已经尝试过的,但没有工作。我相信我的 webpack 配置文件有问题,但我无法弄清楚。任何想法或帮助将不胜感激。谢谢您的宝贵时间。
<template>
<div class="base-app">
<div class="mapbox" id="mapbox">
<router-view />
</div>
</div>
</template>
<script>
// import Login from './components/login.vue';
// import Tract from './components/tract.vue';
export default {
name: "App",
// components: {
// Login,
// Tract
// }
};
</script>
import { createWebHistory, createRouter } from "vue-router";
import Index from "./components/index.vue";
import Login from "./components/login.vue";
import Tract from "./components/tract.vue";
const routes = [
{
path: "/",
component: Index
},
{
path: "/login",
component: Login
},
{
path: "/tract/:id",
component: Tract
}
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
import { createApp } from 'vue';
import App from './App.vue';
// import login from './components/login.vue';
// import tract from './components/tract.vue';
import router from './router.js';
import "./assets/styles/normalize.css";
import "./assets/styles/app.css";
const app = createApp(App);
// app.component('login', login);
// app.component('tract', tract);
app.use(router);
app.mount('#app');
const { VueLoaderPlugin } = require("vue-loader");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const htmlWebpackPlugin = require("html-webpack-plugin");
const autoprefixer = require("autoprefixer");
const path = require("path");
module.exports = {
entry: {
main: "./src/main.js",
},
output: {
filename: 'main.bundle.js',
path: path.resolve(__dirname, 'dist/')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.vue$/,
loader: "vue-loader",
},
{
test: /\.s?css$/,
use: [
"style-loader",
{
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false,
},
},
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: () => [autoprefixer()],
}
},
},
"sass-loader",
],
},
{
test: /\.m?js/,
resolve: {
fullySpecified: false,
},
}
],
},
plugins: [
new VueLoaderPlugin(),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "[name].[contenthash:8].css",
chunkFilename: "[name].[contenthash:8].css",
}),
new htmlWebpackPlugin({
template: path.resolve(__dirname, "public", "index.html"),
favicon: "./public/favicon.ico",
}),
],
resolve: {
extensions: [ '.tsx', '.ts', '.js', '.vue' ],
alias: {
'vue': '@vue/runtime-dom'
}
},
devtool: 'source-map'
};
module.exports = {
devServer: {
disableHostCheck: true,
devMiddleware: {
writeToDisk: false
}
}
}
{
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"startdev": "webpack-dev-server --mode development --config ./webpack.config.cjs",
"start": "NODE_ENV=production webpack --config ./webpack.config.cjs"
},
"dependencies": {
"@aws-amplify/ui-vue": "^3.1.20",
"aws-amplify": "^5.3.3",
"axios": "^0.22.0",
"bootstrap": "4.6.0",
"chart.js": "^4.4.0",
"core-js": "^3.34.0",
"jquery": "^3.6.0",
"mapbox-gl": "^2.6.0",
"popper.js": "^1.16.1",
"postcss-loader": "^7.3.3",
"vue": "^3.0.0",
"vue-chartjs": "^5.2.0",
"vue-router": "4"
},
"devDependencies": {
"@babel/core": "^7.23.5",
"@babel/preset-env": "^7.23.5",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"autoprefixer": "^10.4.16",
"babel-loader": "^9.1.3",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.8.1",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.4",
"mini-css-extract-plugin": "^2.7.6",
"postcss": "^8.4.32",
"sass": "^1.69.5",
"sass-loader": "^13.3.2",
"source-map-loader": "^4.0.1",
"style-loader": "^3.3.3",
"vue-loader": "^17.3.1",
"vue-template-compiler": "^2.7.15",
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
},
}
您应该删除
webpack.config.js
并仅使用 vue.config.js
{
"name": "marc-diff-checker",
"version": "1.0.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"resolutions": {
"coa": "2.0.2"
},
"dependencies": {
"vue": "^3.2.16",
"vue-router": "^4.0.12"
},
"devDependencies": {
"@babel/eslint-parser": "^7.13.14",
"@mdi/font": "^7.0.96",
"@vue/cli-plugin-babel": "^5.0.8",
"@vue/cli-plugin-eslint": "^5.0.8",
"@vue/cli-plugin-router": "^5.0.8",
"@vue/cli-service": "^5.0.8",
"@vue/eslint-config-standard": "^8.0.1",
"eslint": "^7.32.0",
"eslint-plugin-html": "^6.0.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.1.0",
"eslint-plugin-vue": "^9.6.0",
"eslint-webpack-plugin": "^3.2.0",
"postcss-import": "^12.0.1",
"postcss-url": "^7.3.2",
"sass": "1.32.8",
"sass-loader": "^10.1.0",
"stylelint": "^13.9.0",
"stylelint-config-standard": "^20.0.0",
"stylelint-scss": "^3.18.0",
"stylelint-webpack-plugin": "^1.2.3"
}
}
'use strict';
const path = require('path');
const pk = require('./package.json');
module.exports =
{
devServer:
{
port: 8080,
client:
{
//logging: 'info',
overlay:
{
errors: true,
warnings: true,
runtimeErrors: false,
},
}
},
lintOnSave: process.env.NODE_ENV !== 'production' ? 'error' : false,
css:
{
sourceMap: process.env.NODE_ENV === 'development',
/*
loaderOptions:
{
postcss:
{
postcssOptions:
{
// without this Webpack complains that there is no PostCSS config inside the Vuetify/dist folder
config: path.resolve(__dirname, '.postcssrc.js'),
}
},
}
*/
},
productionSourceMap: true,
configureWebpack: config =>
{
let parent;
let dir = path.resolve(__dirname);
const parsed = path.parse(dir);
while (parsed.root !== dir)
{
dir = path.dirname(dir);
parent = dir + (parsed.root !== dir ? path.sep : '') + 'node_modules';
config.resolve.modules.push(parent);
config.resolveLoader.modules.push(parent);
}
config.devtool = process.env.NODE_ENV === 'development' ? 'inline-source-map' : false; // other modes often break hot-reload and/or breakpoints
if (!config.performance) config.performance = {};
config.performance.hints = false;
},
chainWebpack: config =>
{
config.resolve.symlinks(false);
config.resolve.alias.set('src', path.resolve(__dirname, 'src'));
// !!!!!!! -- https://github.com/vuejs/vue-cli/issues/2978#issuecomment-441426094
config.output.devtoolModuleFilenameTemplate(info =>
{
const resPath = path.normalize(info.resourcePath).split(path.sep).join('/');
const isVue = resPath.match(/\.vue$/) && resPath.match(/^src/);
//const isScript = info.query.match(/type=script/);
//const hasModuleId = info.moduleId !== '';
const isGenerated = info.allLoaders;
const generated = `webpack-generated:///${resPath}?${info.hash}`;
const vuesource = `vue-source:///${resPath}`;
return isVue && !isGenerated ? vuesource : generated;
});
config.output.devtoolFallbackModuleFilenameTemplate('webpack:///[resource-path]?[hash]');
// plugin options must be wrapped inside Array - otherwise error "non-callable @@iterator"
if (process.env.NODE_ENV === 'development')
{
config.plugin('stylelintVue')
.use(require('stylelint-webpack-plugin'),
[
{
context: path.resolve(__dirname, 'src'),
configFile: path.resolve(__dirname, 'stylelint.config.js'),
files: '**/*.{vue,css,scss}',
globbyOptions: { extension: false }, // otherwise "fastGlob" does not find anything if the folder contains brace(s)
quiet: false,
emitErrors: true
}
]);
}
config.plugin('define')
.tap(args =>
{
args[0]['process.env'].BUILD_TIME = JSON.stringify((new Date()).toISOString());
args[0]['process.env'].VERSION = JSON.stringify(pk.version);
return args;
});
return config;
}
};
import { createApp, h } from 'vue';
import App from './App.vue';
import router from './router.js';
const myApp = createApp({
name: 'RootApp',
render()
{
return h(App);
}
});
if (process.env.NODE_ENV === 'development')
{
myApp.config.errorHandler = (err, vm, info) =>
{
// err: error trace
// vm: component in which error occurred
// info: Vue specific error information such as lifecycle hooks, events etc.
console.error(vm.$options._componentTag + ': ' + info, err);
events.$emit(SNACKBAR_FAILURE, vm.$options._componentTag + '\n' + info + '\n' + err.message + '\n' + err.stack);
};
window.onerror = function(message, source, lineno, colno, error)
{
alert('Error at ' + lineno + ':' + colno + ' in "' + source + '"\n' + message + '\n' + error);
};
}
///myApp.config.globalProperties.$ajax = AJAX;
myApp.config.productionTip = false;
myApp.config.performance = false; // process.env.NODE_ENV !== 'production';
myApp.config.devtools = process.env.NODE_ENV !== 'production';
myApp.use(router);
myApp.mount('#app');
import { createRouter, createWebHistory } from 'vue-router';
import BadRoute from './views/BadRoute';
import Login from './views/auth/LoginPage';
const createHistory = createWebHistory;
const router = createRouter({
scrollBehavior: () => ({
left: 0,
top: 0
}),
history: createHistory(process.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: Login,
meta:
{
public: true
}
},
// Always leave this as last one,
// but you can also remove it
{
path: '/:catchAll(.*)*',
component: BadRoute,
meta:
{
title: 'NOT FOUND',
public: true
}
}
],
});
router.afterEach((to, from) =>
{
let title = to.meta.title;
if (typeof title === 'function') title = title(to);
if (title)
{
document.title = title;
}
else document.title = 'File History Diff';
});
// https://stackoverflow.com/a/63263736 - ignore NavigationDuplicated errors but keep other errors
const originalPush = router.push;
router.push = function push(location, onResolve, onReject)
{
if (onResolve || onReject)
{
return originalPush.call(this, location, onResolve, onReject);
}
return originalPush.call(this, location).catch((err) =>
{
if (err && err.name === 'NavigationDuplicated')
{
return err;
}
return Promise.reject(err);
});
};
export default router;
<template>
<v-app>
<CustomHeader />
<v-main>
<router-view v-if="$route.meta.public || ($route.meta.admin ? $root.isAdmin : ($root.user || {}).uid)" :key="$root.refresh" v-slot="{Component}" class="pa-4">
<transition name="fade" appear mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</v-main>
<CustomFooter />
<v-overlay :value="$root.spin > 0" z-index="998">
<v-progress-circular indeterminate size="64" />
</v-overlay>
</v-app>
</template>
<script>
import CustomHeader from './views/layout/MainHeader.vue';
import CustomFooter from './views/layout/MainFooter.vue';
import events, { USER_CHANGED } from './events.js';
export default
{
name: 'App',
components:
{
CustomHeader,
CustomFooter,
},
created()
{
events.$on(USER_CHANGED, this.reload);
},
beforeUnmount()
{
events.$off(USER_CHANGED, this.reload);
},
methods:
{
reload()
{
this.$root.refresh++;
},
}
};
</script>
<style lang="scss">
.fade-enter-active,
.fade-leave-active
{
transition: all 0.15s cubic-bezier(0.55, 0, 0.1, 1);
}
.fade-enter,
.fade-leave-active
{
opacity: 0;
transform: translate(-2em, 0);
}
.must_login
{
filter: blur(7px);
}
</style>