Everytime I want to access a specific route in Express I get the followwing error in my browser while also having a default and blank Vue HTML without content. Everything works in Vue debug mode but after building everything, only the Home page and the 404 page works.
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.
In Express I have the following code:
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
this.app.use(express.static(`${__dirname}/html`));
this.app.get('/*', (req, res) => res.sendFile(`${__dirname}/html/index.html`));
In my router.ts in vue I have the following code:
import { defineAsyncComponent } from "vue";
import { createRouter, createWebHistory } from "vue-router";
import Natives from '../views/Natives.vue';
const router = createRouter({
routes: [
{
path: "/",
name: "Home",
component: defineAsyncComponent(() => import('../views/Home.vue')),
meta: {
name: "Home",
},
},
{
path: "/gta",
name: "GTA V",
component: defineAsyncComponent(() => import("../views/GTA.vue")),
meta: {
name: "GTA"
}
},
{
path: "/gta/natives",
name: "Natives",
component: Natives,
meta: {
name: "GTANatives",
},
},
{
path: '/gta/natives/:hash',
name: 'Native',
component: defineAsyncComponent(() => import("../views/DetailedNative.vue")),
meta: {
name: "DetailedNative"
}
},
{
path: "/:pathMatch(.*)*",
name: "Page not found!",
component: defineAsyncComponent(() => import("../views/NotFound.vue")),
meta: {
name: "NotFound",
},
},
],
history: createWebHistory(),
});
I appreciate any help.
EDIT:
So I found out when this happens. So basically if there are more than two routes for example /gta/native or simply /a/b this error appears even if the page doesn't exist. But I still can't figure out how and why.
It seems mime module does not have a type mapping for vue ext.
You can check from https://github.com/broofa/mime/tree/main/types
https://expressjs.com/en/4x/api.html#express.static
Since express.static middleware support setHeaders option, you can set the header by self.
const express = require('express')
const app = new express();
app.use(express.static(__dirname + '/public', {
setHeaders: (res, path, stat) => {
if (/\.vue/i.test(path))
res.setHeader('Content-Type', 'application/javascript')
}
}))
app.listen(55555, '0.0.0.0', () => {
const http = require('http');
http.get('http://127.0.0.1:55555/test.vue', res => console.log(res.headers['content-type']))
});
Test output
$ node app
application/javascript
So I found the answer somehow. Everything was caused because I had a "corrupted" vite.config.ts. After removing base: './', everything worked flawlessly.
Related
I am using the nodemailer-express-handlebars extension to send nodemailer mail using .hbs (handlebars) extension files. I currently have the following folder structure:
-driver-adapter
-adapters
-nodemailer
-handlebars
regiterTemplate.hbs
-nodemailer-adapter.ts
But when I do the typescript build and try to send emails I get the following error
{
"data": {
"errno": -2,
"code": "ENOENT",
"syscall": "open",
"path": "/app/dist/infrastructure/driven-adapters/adapters/nodemailer/handlebars/resetPassword.hbs"
}
}
Going into the dist/ folder I see that I don't have the .hbs files and that's why it can't find them.
I am sharing the code that I am using for the generation and sending of the mail, I would like to understand why it is not taking the .hbs files when doing the build
export class NodeMailerAdapter implements ISendEmail {
private readonly transporter: Mail
constructor () {
const hbsConfig = {
viewEngine: {
extName: '.hbs',
partialsDir: path.join(__dirname, './handlebars/'),
layoutsDir: path.join(__dirname, './handlebars/'),
defaultLayout: ''
},
viewPath: path.join(__dirname, './handlebars/'),
extName: '.hbs'
}
this.transporter = nodemailer.createTransport({
host: CONFIG_NODEMAILER.host,
port: 2525,
auth: {
user: CONFIG_NODEMAILER.user,
pass: CONFIG_NODEMAILER.pass
}
})
this.transporter.use('compile', hbs(hbsConfig))
}
async sendMail (message: IMessage): Promise<string> {
const baseUrl = CONFIG_URL_BASE_TOKEN.baseUrl
const token = 'HERE_IS_TOKEN'
console.log(message)
const email = {
to: {
name: message.to.name,
address: message.to.email
},
from: {
name: CONFIG_EMAIL_SENDER.name,
address: CONFIG_EMAIL_SENDER.email
},
subject: message.subject,
template: 'resetPassword',
context: { baseUrl,token }
}
return await this.transporter.sendMail(email).catch(error => {
return error
})
}
}
According to the Nextjs documentation I can make 301 redirect adding the following code to next.config.js
But the problem is that I am using next-routes and the solution is not working.
module.exports = {
async redirects() {
return [
{
source: '/about',
destination: '/',
permanent: true,
},
]
},
}
But the problem that it's not working with next-routes.
I need to redirect users from 'contact-us' to '/new/contact-us' page
My file with routing:
routes
.add('index', '/', 'index')
.add('contact-us', '/new/contact-us')
and next.config.js file
const withImages = require('next-images');
module.exports = withImages({
webpack: config => {
if (config.resolve.alias) {
const aliases = {
app: 'src',
};
for (const [alias, value] of Object.entries(aliases)) {
config.resolve.alias[alias] = path.resolve(__dirname, value);
}
}
if (process.env.NODE_ENV !== 'production') {
}
return config;
},
});
Please help how can I make 301 redirect?
I have a nuxt project. And located in the .nuxt file there is a router.js file when i want to add my own code to it like this:
routes: [{
path: "/ingelogd",
component: _0716b7e1,
name: "ingelogd",
meta: {requiresAuth: true}
}]
router.beforeEach((to, from, next)=> {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const isAuthenticated = firebase.auth().currentUser;
if(requiresAuth && !isAuthenticated) {
next("/reserveren")
} else {
next()
}
})
it automatically updates the code to this:
routes: [{
path: "/ingelogd",
component: _0716b7e1,
name: "ingelogd",
}]
Is there someone who knows what the problem is please let me know.
You shouldn't edit any file in your .nuxt directory, here is the docs about it.
You should use router middlewares to execute this kind of logic, take a look!
You should not modify any file in the .nuxt directory. In this situation you should work with middleware,
in middleware folder in the project root add file named auth.js with a content like :
export default function ({ app,route }) {
app.router.beforeEach((to, from, next)=> {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const isAuthenticated = firebase.auth().currentUser;
if(requiresAuth && !isAuthenticated) {
next("/reserveren")
} else {
next()
}
})
}
Then, in your nuxt.config.js add :
router: {
middleware: 'auth'
}
I am fairly new to Nuxt and Vue. I have worked with React and Express before but I'm not sure if I'm missing a step specific to the Nuxt configuration.
I'm trying to GET data from an endpoint on my Express server, and it's working fine locally, but once I've deployed it, I'm having one of a couple of different errors. At first I was getting
Access to XMLHttpRequest at 'http://localhost:3000/ENDPOINT' from
origin 'https://APPNAME.herokuapp.com' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the
requested resource.
I was able to get past this by installing the cors and #nuxtjs/proxy npm packages, adding app.use(cors()) to my server and adding a changeOrigin property to proxy in nuxt.config.js.. Now I'm getting a 404 when it tries to GET APPNAME.herokuapp.com/ENDPOINT.
I created a new test app using npx create-nuxt-app, choosing express as the custom server framework and setting up a test endpoint in server/index.js
app.get('/test', (req, res) => {
res.status(200).send('reached test')
})
In my nuxt view, I added a method:
runTest () {
this.$axios.$get('/test')
.then(success => console.log('success text:', success))
}
Again, this runs fine locally, but once deployed, I got the CORS issue until I added the cors package and changeOrder. Now getting the 404, it seems like I can't access my server's endpoints. Does anyone know anything about this?
Thanks in advance for any help!
UPDATE:
My nuxt.config.js file:
module.exports = {
mode: 'universal',
/*
** Headers of the page
*/
head: {
titleTemplate: '%s - ' + process.env.npm_package_name,
title: process.env.npm_package_name || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
]
},
/*
** Customize the progress-bar color
*/
loading: { color: '#fff' },
/*
** Global CSS
*/
css: [
],
/*
** Plugins to load before mounting the App
*/
plugins: [
],
/*
** Nuxt.js dev-modules
*/
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'#nuxtjs/eslint-module',
'#nuxtjs/vuetify'
],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://axios.nuxtjs.org/usage
'#nuxtjs/axios',
'#nuxtjs/proxy'
],
proxy: {
'/api/': {
target: 'http://localhost:3000/',
pathRewrite: {
'^/api/': ''
},
changeOrigin: true
}
},
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {
},
/*
** vuetify module configuration
** https://github.com/nuxt-community/vuetify-module
*/
vuetify: {
customVariables: ['~/assets/variables.scss'],
theme: {
dark: true,
themes: {}
}
},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend (config, ctx) {
}
}
}
My server file:
const express = require('express')
const consola = require('consola')
const cors = require('cors')
const { Nuxt, Builder } = require('nuxt')
const app = express()
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js')
config.dev = process.env.NODE_ENV !== 'production'
async function start () {
// Init Nuxt.js
const nuxt = new Nuxt(config)
const { host, port } = nuxt.options.server
await nuxt.ready()
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
app.use(cors())
app.get('/test', (req, res) => {
res.status(200).send('reached test')
})
// Give nuxt middleware to express
app.use(nuxt.render)
// Listen the server
app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
})
}
start()
This is mostly default nuxt scaffolding on my test app.
Thanks
My project uses Vue2 and Vue Router. I want to be able to load the component Stats by typing in the URL http://example.com/stats.
URL http://example.com/stats does not work, I'm redirected to / and it loads the App component
<router-link :to="/stats">Go to stats</router-link> works perfectly
I would like to know whether it is a Vue Router issue or a server configuration issue. I'd like to mention the fact that I experience this issue both in my localhost and my server using nGinx.
How could I fix this?
app.js:
const routes = [
{ path: '/', component: App },
{ path: '/stats', component: Stats },
{ path: "*", component: PageNotFound },
{ path: '/admin', meta: { requiresAdmin: true }, component: Admin},
{ path: "/not-authorized", component: NotAuthorized },
];
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
routes,
})
const app = new Vue({
el: '#app',
router,
data () {
return {}
},
});
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAdmin)) {
if (!Store.state.isAdmin) {
axios.post('/isAdmin').then((response) => {
if(response.data.isAdmin){
next();
}
else {
next({
path: '/not-authorized',
})
}
});
}
else {
next();
}
}
else {
next();
}
}
else {
next(); // make sure to always call next()!
}
});
Have you configured your web-server to return the same page regardless of the URL?
That way your app can load, and the URL is preserved so routing can take over and select the right component once it's loaded.
This answer https://stackoverflow.com/a/7027686/7816087 suggests the following config for nginx:
location / {
try_files $uri /base.html;
}
Go to your Laravel routes and put this:
Route::any('{all}', function () {
return view('index'); // if your main view is "index"
})
This will ensure that deep linking is working properly on all request handled by Laravel.
Here is what I did
Route::get('/stats', 'HomeController#home');