nuxtjs/router use runtime config client side - javascript

we are using nuxt 2.14.12 and #nuxtjs/router 1.5.0
we are trying to use runtime config to make some HTTP request client side.
here is our router.js
export async function createRouter(ssrContext, createDefaultRouter) {
[...]
try {
const res = await axios.get(`${config.public.apiBaseUrl}/myslug`)
} catch (e) { }
[...]
}
here is the config file
[...]
const apiBaseUrl = `${process.env.NUXT_ENV_MY_API_URL || 'http://my-dev-domain.com'}`
[...]
export default {
apiBaseUrl,
},
private: {
apiBaseUrl,
},
[...]
here is our nuxt.config.js
export default {
[...]
publicRuntimeConfig: config.public,
privateRuntimeConfig: config.private,
[...]
buildModules: [
['#nuxtjs/router', { keepDefaultRouter: true }],
],
[...]
router: {
linkActiveClass: 'current-menu-item'
},
[...]
}
we use nuxt build in our CI and later at runtime we use nuxt start
at runtime, despite on server side the env variable NUXT_ENV_MY_API_URL is correctly set, on the client site the variable looks hardcoded (I think webpack replace it) and we get the value present on build time (http://my-dev-domain.com)
is there a way to use the runtime config on the client side?
thank you

Related

Cypress: import modules via alias

in my project i am using cypress with plain javascript. i am facing the challenge of importing the modules (page objects) via aliases instead of spaghetti code like ../../../../folder/page.js.
I don't use typescript or react.js and don't have a src folder/directory.
my tests run locally in the browser or via a docker image (pipeline).
I would like to transform from this:
import { LoginPage } from "../../pages/loginPage.js";
to something like this:
import { LoginPage } from "#Pages/loginPage.js";
but I always get an error:
Error: Webpack Compilation Error
./cypress/e2e/accountOverview/accountOverviewPageTest.spec.js
Module not found: Error: Can't resolve 'Pages/loginPage.js' in 'C:\Users\User\automated_frontend_tests\automated_frontend_tests\cypress\e2e\accountOverview'
resolve 'Pages/loginPage.js' in 'C:\Users\User\automated_frontend_tests\automated_frontend_tests\cypress\e2e\accountOverview'
Parsed request is a module
using description file: C:\Users\User\automated_frontend_tests\automated_frontend_tests\package.json (relative path: ./cypress/e2e/accountOverview)
Field 'browser' doesn't contain a valid alias configuration
Looked for and couldn't find the file at the following paths:
[C:\Users\User\automated_frontend_tests\automated_frontend_tests\cypress\e2e\accountOverview\node_modules]
[C:\Users\User\automated_frontend_tests\automated_frontend_tests\cypress\e2e\node_modules]
[C:\Users\User\automated_frontend_tests\automated_frontend_tests\cypress\node_modules]
[C:\Users\node_modules]
[C:\node_modules]
[C:\Users\User\automated_frontend_tests\automated_frontend_tests\node_modules\Pages\loginPage.js]
[C:\Users\User\automated_frontend_tests\node_modules\Pages\loginPage.js]
[C:\Users\User\node_modules\Pages\loginPage.js]
[C:\Users\User\automated_frontend_tests\automated_frontend_tests\node_modules\Pages\loginPage.js.js]
[C:\Users\User\automated_frontend_tests\node_modules\Pages\loginPage.js.js]
[C:\Users\User\node_modules\Pages\loginPage.js.js]
[C:\Users\User\automated_frontend_tests\automated_frontend_tests\node_modules\Pages\loginPage.js.json]
[C:\Users\User\automated_frontend_tests\node_modules\Pages\loginPage.js.json]
[C:\Users\User\node_modules\Pages\loginPage.js.json]
[C:\Users\User\automated_frontend_tests\automated_frontend_tests\node_modules\Pages\loginPage.js.jsx]
[C:\Users\User\automated_frontend_tests\node_modules\Pages\loginPage.js.jsx]
[C:\Users\User\node_modules\Pages\loginPage.js.jsx]
[C:\Users\User\automated_frontend_tests\automated_frontend_tests\node_modules\Pages\loginPage.js.mjs]
[C:\Users\User\automated_frontend_tests\node_modules\Pages\loginPage.js.mjs]
[C:\Users\User\node_modules\Pages\loginPage.js.mjs]
[C:\Users\User\automated_frontend_tests\automated_frontend_tests\node_modules\Pages\loginPage.js.coffee]
[C:\Users\User\automated_frontend_tests\node_modules\Pages\loginPage.js.coffee]
[C:\Users\User\node_modules\Pages\loginPage.js.coffee]
# ./cypress/e2e/accountOverview/accountOverviewPageTest.spec.js 5:17-46
I have tried several solutions, including:
//webpack.config.js
module.exports = {
resolve: {
alias: {
"#pages": path.resolve(__dirname, "cypress/pages/*"),
},
},
};
//testspec file
import { LoginPage } from "#pages/loginPage.js";
const loginPage = new LoginPage();
#Uzair Khan:
I tried your solution, but it still didn't work. The error message remains the same. It seems that the IDE does not search in the correct folder, but only in ...\node_modules\#page\loginPage.js which makes no sense.
If I enter const loginPage = new LoginPage(), the module LoginPage() cannot be found by the IDE either. Something is wrong with the solution. Do I still have to install any packages via NPM?
In your webpack.config.js file add resolve.alias which you want to make alias. It looks like something this below:
resolve: {
alias: {
'#page': path.resolve(__dirname, '{path you want to make alias}')
}
}
Since you are using cypress, you have to update the resolve path in cypress.config.js. Here is mine cypress.config.js
import { defineConfig } from 'cypress'
import webpack from '#cypress/webpack-preprocessor'
import preprocessor from '#badeball/cypress-cucumber-preprocessor'
import path from 'path'
export async function setupNodeEvents (on, config) {
// This is required for the preprocessor to be able to generate JSON reports after each run, and more,
await preprocessor.addCucumberPreprocessorPlugin(on, config)
on(
'file:preprocessor',
webpack({
webpackOptions: {
resolve: {
extensions: ['.ts', '.js', '.mjs'],
alias: {
'#page': path.resolve('cypress/support/pages/')
}
},
module: {
rules: [
{
test: /\.feature$/,
use: [
{
loader: '#badeball/cypress-cucumber-preprocessor/webpack',
options: config
}
]
}
]
}
}
})
)
// Make sure to return the config object as it might have been modified by the plugin.
return config
}
And import in other file via that alias you set in cypress.config.js. Here is mine for example:
import page from '#page/visit.js'
const visit = new page()
When('I visit duckduckgo.com', () => {
visit.page()
})
I think both answers are nearly there, this is what I have for src files:
const webpack = require('#cypress/webpack-preprocessor')
...
module.exports = defineConfig({
...
e2e: {
setupNodeEvents(on, config) {
...
// #src alias
const options = {
webpackOptions: {
resolve: {
alias: {
'#src': path.resolve(__dirname, './src')
},
},
},
watchOptions: {},
}
on('file:preprocessor', webpack(options))
...
path.resolve() resolves a relative path into an absolute one, so you need to start the 2nd param with ./ or ../.
Also, don't use wildcard * in the path, you just need a single folder that will be substituted for the alias in the import statement.
If in doubt, check the folder returned (in the terminal)
module.exports = defineConfig({
...
e2e: {
setupNodeEvents(on, config) {
const pagesFolder = path.resolve(__dirname, './cypress/pages')
console.log('pagesFolder', pagesFolder)

How to setup NextJS Middleware [duplicate]

I have the middleware.js file within /myproject/pages/middleware.js:
export function middleware(request) {
console.log(1);
return NextResponse.redirect(new URL('/', request.url));
}
// See "Matching Paths" below to learn more
export const config = {
matcher: ['/test'],
};
Now what I expect is when i go to the page /test then it should redirect me to /. However nothing happens and I see my standard 404 page.
Any ideas why?
NextJs version: 12.2.2
Latest versions of NextJS requires user to have a single middleware on the root folder.
Instead of {root}/pages/_middleware.js, try {root}/middleware.js
For next 13.0.2 / 13.0.1
if you are using appDir: true ( experimental )
if you want to hit middleware:
put middleware.ts in root project:
( as the same hierarchy as "app" folder, not inside app folder... )
make sure tsconfig has include: [..., "middleware.ts"]
make empty "pages" folder. ( based on issue )
will hit every request:
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest ) {
console.log('lol!!!')
}
export const config = {
matcher: '/',
}
if your pages and middleware are not on the same level, then it won't work.
here is an example of middleware working with Cookies.
import { NextResponse } from "next/server";
export default function middleware(req){
let verify = req.cookies.get("loggedin");
let url = req.url
if(!verify && url.includes('/dashboard')){
return NextResponse.redirect("http://localhost:3000/");
}
if (verify && url === "http://localhost:3000/") {
return NextResponse.redirect("http://localhost:3000/dashboard");
}
}

Error with WEB3js - NodeJs.utils in vite react ts app - How to resolve TypeError: callbackify is not a function

Hey I am playing around with web3 inside react as a client application (using vite react-ts) and trying to call web3.eth.net.getId() but this will throw me an error that callbackify is not a function I digged a little and found an old issue on the github which states that older versions of Nodejs.util (prior version 0.11) didn't have this function. So I checked the package.json where the error occurs (web3-core-requestmanager) it has "util":"^0.12.0", so callbackify should be available.
In fact when I am looking at their imports, they seem to be able to import it:
(following code is ./node_modules\web3-core-requestmanager\src\index.js
const { callbackify } = require('util');
but when they want to use it, callbackify is undefined
//RequestManager.prototype.send function
const callbackRequest = callbackify(this.provider.request.bind(this.provider));
I tried to play around with the dependencies and tried different versions of web3.js (1.7.3; 1.6.0; 1.5.1) all of them had the same util dependency (0.12.0).
My code in all this matter looks like this:
class Blockchain {
public blockchainBaseUrl: string;
public web3;
public provider;
public account: string = '';
public contract: any;
constructor() {
if (process.env.REACT_APP_BLOCKCHAIN_BASE_URL === undefined) {
throw new Error('REACT_APP_BLOCKCHAIN_BASE_URL is not defined');
}
this.provider = window.ethereum;
if (this.provider === undefined) {
throw new Error('MetaMask is not installed');
}
this.setUpInitialAccount();
this.addEthereumEventListener();
this.blockchainBaseUrl = process.env.REACT_APP_BLOCKCHAIN_BASE_URL;
this.web3 = new Web3(Web3.givenProvider || this.blockchainBaseUrl);
this.setContract();
}
async setContract() {
// error comes from the next line
const networkId = await this.web3.eth.net.getId();
this.contract = new this.web3.eth.Contract(
// #ts-ignore
Token.abi,
// #ts-ignore
Token.networks[networkId].address
);
}
}
I also was told that I should simply add a .catch() to web3.eth.net.getId() but this did nothing. Am I doing something wrong or is this a dependency problem? If anyone could point me in the right direction I would really appreciate it. Do I need to expose the util API to the browser somehow? To me, it seems that the API is simply not available.
This is should be the relevant part of my vite.config.ts:
import GlobalsPolyfills from '#esbuild-plugins/node-globals-polyfill';
import NodeModulesPolyfills from '#esbuild-plugins/node-modules-polyfill';
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react';
export default defineConfig({
plugins: [
react(),
],
optimizeDeps: {
esbuildOptions: {
plugins: [
NodeModulesPolyfills(),
GlobalsPolyfills({
process: true,
buffer: true,
}),
],
define: {
global: 'globalThis',
},
},
},
});
Here is my complete vite config
https://pastebin.com/zvgbNbhQ
Update
By now I think that I understand the issue - it seems that it is a VIte-specific problem and I need to polyfill the NodeJs.util API. I am already doing this (at least I thought). Perhaps someone can provide some guidance on what I am doing wrong with my config?
Update 2
I actually have now the util API inside the browser, but it is still giving me the same error. This is my new config:
https://pastebin.com/mreVbzUW I can even log it out:
Update 3
SO I am still facing this issue - I tried a different approach to polyfill I posted the update to the github issue https://github.com/ChainSafe/web3.js/issues/4992#issuecomment-1117894830
Had similar problem with vue3 + vite + we3
It's started from errors: process in not defined than Buffer is not defined and finally after I configure polyfill I came to callbackify is not defined
Did a lot of researches and finally solved this issue with next trick:
Rollback all polyfill configurations
Add to the head html file
<script>window.global = window;</script>
<script type="module">
import process from "process";
import { Buffer } from "buffer";
import EventEmitter from "events";
window.Buffer = Buffer;
window.process = process;
window.EventEmitter = EventEmitter;
</script>
vite.config.ts
import vue from '#vitejs/plugin-vue'
export default {
resolve: {
alias: {
process: "process/browser",
stream: "stream-browserify",
zlib: "browserify-zlib",
util: 'util'
}
},
plugins: [
vue(),
]
}
add these dependencies browserify-zlib, events, process, stream-browserify, util
Source https://github.com/vitejs/vite/issues/3817#issuecomment-864450199
Hope it will helps you

.env Nuxt JS doesn't resolve routes in generate option correctly

I'm trying to use Nuxt JS's 2.9.2 generate object to generate dynamic pages as static files using my .env file to pull a URL, I'm having difficuility in getting it to properly link up:
nuxt.config.js
require('dotenv').config();
import pkg from './package'
import axios from 'axios'
export default {
mode: 'universal',
env: {
blog_api: process.env.BLOG_API || "http://localhost:3000/articles/blogs.json"
},
/*
** Build directory
*/
generate: {
dir: 'dist-next',
routes: function () {
return axios.get(`${process.env.blog_api}`)
.then((res) => {
return res.data.blogs.map((blog) => {
return '/posts/view/' + blog.title
})
})
}
}
}
The above code, more specifically ${process.env.blog_api}, can't seem to resolve the routes, despite it working perfectly if I replace it with my own local domain.
.env
BLOG_API="http://my-local-domain.clone/articles/blogs.json"
EDIT:
Updated code with my config, http://my-local-domain.clone/articles/blogs.json is inside of static/articles
You should use dotenv module:
https://www.npmjs.com/package/dotenv
More Info about configuration with NUXT you have here:
https://samuelcoe.com/blog/nuxt-dotenv/
You probably want to set your env property in nuxt.config.js, for example:
module.exports = {
env: {
BLOG_API: process.env.BLOG_API_URL,
},
In your component, you can now use them :
makeAsyncCall({
to: process.env.BLOG_API,
})

Angular 5 External JSON config returning undefined

In my assets i've got a config.json file with an apiUrl
{
"apiUrl":"https://api.example.com"
}
I've got multiple environments, but one of them needs to be able to be altered after the build.
import * as config from '../assets/config.json';
export const environment = {
production: true,
appTheme: "blue-theme",
apiUrl: config.apiUrl
appName: "App",
};
in my typings.d.ts i've got
declare module "*.json" {
const value: any;
export default value;
}
When i do console.log(config) I get:
{
apiUrl:"https://api.example.com"
}
But when i do console.log(config.apiUrl) I get:
undefined
Can someone tel me what i'm doing wrong?
How to retrieve Json data
using by node
const config: any = require('../assets/config.json');
export const environment = {
production: true,
appTheme: "blue-theme",
apiUrl: config.apiUrl
appName: "App",
};
Using by http
How to extract JSON data from http.get in Angular 2 properly?
How to fetch JSON file in Angular 2

Categories