Serving app with Client-Side Routing in NestJs - api

I have a sample react app using react-router-dom with one route "/reset/:token"
when I run my app in development server and navigate to my route everything works fine
but in server static using ServeStaticModule when I navigate to my route I get "Cannot GET /reset/5T4665" and 404
status code
Here is my code:
App.module
#Module({
imports: [
ConfigModule.forRoot({
envFilePath: 'config/' + `.${process.env.NODE_ENV}.env`,
isGlobal: true,
}),
MongooseModule.forRoot(`${process.env.MONGO_URI}`),
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'),
renderPath: '/',
}),
BullModule.forRoot({
redis: {
host: 'localhost',
port: 6379,
},
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Any helps would be appreciated

I fix it by adding Asterisk in field renderPath
ServeStaticModule.forRoot({
rootPath: join(__dirname, '..', 'public'),
renderPath: '/*',
}),
Source : https://create-react-app.dev/docs/deployment/#serving-apps-with-client-side-routing

Related

How to configure Svelte Kit to request assests from a CDN in production?

I deployed my Svelte Kit app on K8s and noticed that things like Favicons weren't loading. After some investigation, it turns out that Nginx Ingress Controller is not designed to serve those files:
The Ingress Controller is not designed to serve static content. If you'd like to serve static content, consider having a separate Service for it.
See #257 (comment) — Github issue comment, 2018.
thus, splitting my statics assets from the rest of my Svelte Kit app is needed... but I'm a bit lost on how to correctly do that: After building my app I can see the static folder there, then I should just upload that to a CDN, but what about Svelte itself? Is changing %svelte.assets% good enough to signal the location of static assets in Svelte Kit?
This is my current Svelte Kit configuration:
/* jshint esversion: 11 */
// Imports
import preprocess from 'svelte-preprocess';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';
import svg from '#poppanator/sveltekit-svg';
// Adapters
import adapter from '#sveltejs/adapter-node';
// Custom require function as replacement for the require from the commonJS in ES Module
// Custom __dirname as replacement for the __dirname from the commonJS in ES Module
const __dirname = dirname(fileURLToPath(import.meta.url)); // jshint ignore:line
const options = JSON.stringify(process.env.OPTIONS || '{}');
/** #type {import('#sveltejs/kit').Config} */
const config = {
preprocess: [
preprocess({
postcss: true,
preserve: ['ld+json', 'module'],
typescript: true,
}),
],
kit: {
adapter: adapter({ ...options, out: './.svelte-kit/nodejs/build/' }),
prerender: {
crawl: true,
enabled: true,
onError: 'fail',
entries: ['*'],
},
vite: () => ({
resolve: {
alias: {
$stores: resolve(__dirname, './src/stores'),
$components: resolve(__dirname, './src/lib/shared/components'),
$ui: resolve(__dirname, './src/lib/shared/ui'),
$layouts: resolve(__dirname, './src/lib/layouts'),
$shared: resolve(__dirname, './src/lib/shared'),
$models: resolve(__dirname, './src/lib/models'),
$data: resolve(__dirname, './src/lib/data'),
$core: resolve(__dirname, './src/lib/core'),
$utils: resolve(__dirname, './src/lib/utils'),
$environment: resolve(__dirname, './src/environments'),
},
},
envPrefix: ['VITE_', 'SVELTEKIT_STARTER_'],
plugins: [svg({ type: 'src', svgoOptions: svg.OptimizeOptions })],
}),
},
};
export default config;

Cannot connect NestJS Bull to Elasticache (Redis)

I stuck when connecting NestJS Bull to AWS Elasticache on deployment
On local I easily connect to Redis by
import { Module } from '#nestjs/common';
import { BullModule } from '#nestjs/bull';
#Module({
imports: [
BullModule.forRoot({
redis: {
host: 'localhost',
port: 6379,
password: 'secret',
},
}),
],
})
export class AppModule {}
I even try on https://app.redislabs.com/ a official Redis cloud. It still working.
But on deployment with Elasticache. There is no error on startup but the queue is not worked as expected
My code last year was worked, But now no response
import Redis from 'ioredis';
#Module({
imports: [
BullModule.forRoot({
createClient: () => {
return config.get('redis.cluster.host')
? new Redis.Cluster([
{
port: +config.get('redis.cluster.port'),
host: config.get('redis.cluster.host'),
},
])
: new Redis(+config.get('redis.standalone.port'), config.get('redis.standalone.host'));
},
}),
FeeQueue,
],
providers: [],
exports: [],
})
export class QueuesModule {}
Could you have time to help me. Thanks
I don't know if it'll be the same for you, but I just ran into a similar issue. The queue wasn't working, but no error logged. After a lot of testing, I finally got it to log an error saying that enableReadyCheck and maxRetriesPerRequest can't be used for bclients and subscibers. So I unset them:
BullModule.forRoot({
createClient: (type) => {
const opts =
type !== 'client'
? { enableReadyCheck: false, maxRetriesPerRequest: null }
: {}
return config.get('redis.cluster.host')
? new Redis.Cluster([{ host, port }], opts)
: new Redis({ host, port, ...opts});
},
})

How to configure #nuxtjs/auth with Auth0

I created a Nuxt application that uses Auth0 as the login provider. When you log in, you get redirected to the callback page and then the auth module takes over and saves the login information in the state.
All works perfectly in Dev mode, but as soon as I generate code for production, the auth module no longer reacts to the callback and you are not logged in.
Generating in target server or static has no effect.
I'm set to mode=universal.
I tried to enable SSR or specifically disable it, to no effect.
I'm using
"nuxt": "^2.15.4"
"#nuxtjs/auth": "^4.9.1",
I've been fighting this thing for a week, and I've seen numerous threads that talk about this, but no one provided a solution.
Is this really a problem that was not dealt with in Nuxt? That pretty much kills the usefulness of the platform if it can't handle auth in production...
Does anyone have a way to solve this?
I'm willing to post my code, if it will help resolve this.
EDIT: here is my nuxt.config.js file:
export default {
mode: 'universal',
target: 'server',
css: [],
plugins: [
{ src: '~/plugins/vue-debounce.js' },
{ src: '~/plugins/modal-popup.js', ssr: false },
{ src: '~/plugins/editor.js', ssr: false },
],
components: true,
buildModules: ['#nuxtjs/eslint-module', '#nuxtjs/fontawesome'],
fontawesome: {
component: 'fa',
suffix: true,
icons: {
solid: ['faCaretDown', 'faCaretRight', 'faCaretLeft'],
regular: ['faFileAlt'],
},
},
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth',
],
axios: {
baseURL: 'http://localhost:9000/api/',
headers: {
common: {
Accept: 'application/json',
},
},
},
auth: {
strategies: {
auth0: {
domain: '<my domain>.eu.auth0.com',
client_id: '<client id>',
audience: 'https://<my domain>.eu.auth0.com/api/v2/',
},
},
redirect: {
callback: '/callback/',
logoutRedirectUri: '/login'
},
},
build: {
transpile: [],
},
}
Here is a repo that I've created that explains in depth how to setup the most setup auth0 connection flow: https://github.com/kissu/so-nuxt-docs-theme-auth-auth0
Please pay attention to the README.md and then, check how it works with your auth setup. Here is my section
nuxt.config.js
auth: {
redirect: {
callback: "/",
home: "/",
login: "/login",
logout: "/"
},
localStorage: false,
strategies: {
local: false,
auth0: {
domain: process.env.AUTH0_DOMAIN,
clientId: process.env.AUTH0_CLIENT_ID,
scope: ['openid', 'profile', 'offline_access'],
accessType: 'offline',
responseType: 'code',
grantType: 'authorization_code',
codeChallengeMethod: 'S256',
}
},
},
As for the target, if you're limiting the access to your app straight from the beginning, the best way to go is still
target: 'static',
ssr: false,
That way, it will not require any NodeJS server and will be SPA only. Indeed, there is no need to generate protected pages (by auth0) since the guy needs to be logged-in. And, it will not generate them because of the way #nuxt/auth works.
I found the problem.
I had implemented a non-standard header in Axios, like so:
axios: {
baseURL: 'http://localhost:9000/api/',
headers: {
common: {
Accept: 'application/json',
authentication: "<UUID code>"
},
},
}
I did it as a temporary way to secure the communication with the server, until I had Auth0 running, and I forgot to remove it.
As soon as I got rid of this header, it started working as expected.
I'm not sure why this would cause the fact that it worked in developer mode and not in generated code, but removing the line made it work in both.

Workbox Webpack Plugin and Webpack Dev Server issue

I'm starting to use webpack-workbox-plugin to inject service worker into application. My project is an ASP.NET Core web application that runs over IIS Express.
This is my development webpack config file:
const MODULE_BUILD_DIR = path.resolve(__dirname, './wwwroot/dist/assets/');
const workboxPlugin = require('workbox-webpack-plugin');
process.env.NODE_ENV = "development";
const config = {
mode: "development",
target: "web",
devtool: "cheap-module-source-map",
context: __dirname, // string (absolute path!)
entry: [
'#babel/polyfill',
'font-awesome/scss/font-awesome.scss',
'./wwwroot/js/main.js',
],
output: {
path: MODULE_BUILD_DIR,
filename: '[name].bundle.js',
chunkFilename: '[id].chunk.js',
},
// ...
plugins: [
// ...
new workboxPlugin.GenerateSW({
swDest: 'sw.js',
clientsClaim: true,
skipWaiting: true,
}),
],
devServer: {
contentBase: path.resolve(__dirname, './'),
historyApiFallback: false,
inline: true,
open: false,
port: 9099,
hot: true,
https: true,
},
// ...
}
And this is the function i call over my main.js:
export default function setServiceWorker() {
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then((registration) => {
console.log('SW registered: ', registration);
}).catch((registrationError) => {
console.log('SW registration failed: ', registrationError);
});
});
}
}
But when i run application, client doesn't find sw.js file becuse it's allocated over webpack dev server path, so not in IIS Express app path.
DevTool messages:
A bad HTTP response code (500) was received when fetching the script.
---
SW registration failed: TypeError: Failed to register a ServiceWorker
for scope ('https://localhost:44357/') with script ('https://localhost:44357/sw.js'):
A bad HTTP response code (500) was received when fetching the script.
What could be a solution for it?
Thank you
Solved using clean-webpack-plugin and write-file-webpack-plugin:
plugins: [
new CleanWebpackPlugin(),
new WorkboxPlugin.GenerateSW({
swDest: 'sw.js',
clientsClaim: true,
skipWaiting: true,
}),
new WriteFilePlugin(),
],
but not sure it's the best way

Cannot GET / on localhost:8080 when using npm run hot

I'm using laravel vuejs spa and would like to use npm run hot so that the browser gets refreshed automatically.
Here is my webpack.mix file
const path = require('path')
const mix = require('laravel-mix')
// const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
mix.config.vue.esModule = true
mix
.js('resources/assets/js/app.js', 'public/js')
.styles([
'resources/assets/css/app.css',
'resources/assets/css/style.css'
], 'public/css/app.css')
.sourceMaps()
.disableNotifications()
if (mix.inProduction()) {
mix.version()
mix.extract([
'vue',
'vform',
'axios',
'vuex',
'jquery',
'popper.js',
'vue-i18n',
'vue-meta',
'js-cookie',
'bootstrap',
'vue-router',
'sweetalert2',
'vuex-router-sync',
'#fortawesome/fontawesome',
'#fortawesome/vue-fontawesome'
])
}
mix.webpackConfig({
plugins: [
// new BundleAnalyzerPlugin()
],
resolve: {
extensions: ['.js', '.json', '.vue'],
alias: {
'~': path.join(__dirname, './resources/assets/js')
}
},
output: {
chunkFilename: 'js/[name].[chunkhash].js',
publicPath: mix.config.hmr ? '//localhost:8080' : '/'
}
})
I configured mysite.com on my localhost and when i visit mysite.com im able to view the site. But it does not get refreshed when i make changes. I followed few articles on the internet and found that it would be on localhost:8080.
Now when i visit to localhost:8080 all i see is a blank page with error Cannot GET /
Does anyone know how to solve this and make the browser refreshed whenever i make changes in my project.