ReferenceError: VUE_APP_CONFIG is not defined Jest unit tests failing - javascript

export interface VueAppConfig {
API_URL: string;
API_URL_V2: string;
}
declare const VUE_APP_CONFIG: VueAppConfig;
export const APP_CONFIG = { ...VUE_APP_CONFIG } as const;
In above code am getting reference error.

declare tells the compiler that the variable already exists somewhere. It's not actually creating the variable.
If you're trying to create the variable, remove declare.
Given the name (VUE_APP_CONFIG), I'm guessing you're trying to read an environment variable, where the VUE_APP_ prefix makes the variable avaiable in the production build. In that case, make sure to refer to it via process.env:
const VUE_APP_CONFIG = JSON.parse(process.env.VUE_APP_CONFIG) as VueAppConfig

Problem was: jest was not receiving this value am not sure why, but after updating jest.config.js to accept
globals: {
VUE_APP_CONFIG: true,
},
it all started working fine

Related

Using global from different modules

I have a modular project, where the main module (entrypoint) is written in javascript, meanwhile some auxiliary libs are in typescript.
The javascript module, when starts, assign some set of variables, using global.
The problem is I don't to share this variables with the typescript libs.
It runs, but I'm getting some error when publishing:
Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
The javascript set these variables as below:
static loadProperties() {
global.myProperties = new Map();
global.myProperties.set('SOME_VARIABLE', 'someValue');
}
The typescript lib uses it as following:
const someVariable: string = global.myProperties.get('SOME_VARIABLE');
But when running the npm run compile command, throws the exception mentioned before.
since you global really don't have any such attribute
I really don't recommend using global. but if you want to, here's how:
global.d.ts:
declare namespace NodeJS {
export interface Global {
myProperties: Map<unknown, unknown>
}
}
// and / or top-level module
declare var myProperties: Map<unknown, unknown>
In addition, your code has a syntax error:
static loadProperties() {
global.myProperties = new Map();
// global.myProperties.set('SOME_VARIABLE') = 'someValue';
global.myProperties.set('SOME_VARIABLE', 'someValue');
}

Access environment variables from client [duplicate]

This question already has answers here:
next.js environment variables are undefined (Next.js 10.0.5)
(8 answers)
Dynamic access of environment variables in NextJS not working
(1 answer)
Closed last year.
I'm making a lot of API calls from within my components using fetch. Everytime I had to write this logic to determine which environment I'm in So, I created a Utils class which returns the correct base url:
export default class Utils {
static get baseUrl() {
const inDev = process.env.NODE_ENV !== 'production';
const { NEXT_PUBLIC_DEV_URL, NEXT_PUBLIC_PROD_URL } = process.env;
return inDev ? NEXT_PUBLIC_DEV_URL : NEXT_PUBLIC_PROD_URL;
}
}
But now I'm getting this error when my component loads:
ReferenceError: process is not defined
I looked around and found that I need to mark my variables as NEXT_PUBLIC so I did but the problem still persists. What's the ideal way to handle this?
If you want to expose ENV variables to the client you can use publicRuntimeConfig inside your NextJS configuration (next.config.js). Here is how you could do it:
publicRuntimeConfig: {
myEnvVar: process.env.MY_ENV_VAR
}
And then in the file you would like to use your ENV variable:
import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig();
const envVar = publicRuntimeConfig.myEnvVar // store in it a 'const' or do whatever you want with it,;
Your class can actually look like this :-
export default class Utils {
static get baseUrl() {
return process.env.NEXT_PUBLIC_URL;
}
}
The NEXT_PUBLIC prefix should work well for inlining the values which are replaced at build time and sent to the browser as per docs.
In your .env.development (or whatever your dev environment file is called) file, you can have NEXT_PUBLIC_URL pointing to http://localhost:8000 and in your production you will probably have production env variables setup using a GUI (like in Netlify or Vercel), so there NEXT_PUBLIC_URL can be https://blablasite.com.
Either way, NEXT_PUBLIC prefix will ensure that at build time those values are picked up and inlined before sending the same to browser.

nestjs issue with variable in .env file

Im using NestJS framework to build a rest api, i have a issue getting the environment variables.
I have a .env with a variable "SMB_SHARE" with a path string, when i pass this variable to a class constructor of a smb2 libray, this throw an error, the string provided by the environment variable is invalid.
The environment variable is this:
SMB_SHARE=\\10.00.0.000\some_path
When i use console log in the code the variable is ok, is a string and has the correct string value. But when i pass it to the constructor, it throw the error.
I pass the string directly to the constructor, and it work fine, the others environment variables of the constructor are setted correctly (like the username and password). Only the SMB_SHARE variable is throwing the error.
I dont have idea what is the problem here. Can someone help me with this issue?
I show some examples:
constructor(private config: ConfigService) {
console.log('VAR', config.get<string>('SMB_SHARE'));
//This show the correctly string variable value
const share = config.get<string>('SMB_SHARE');
this.sambaClient = new SMB2({
share: '\\\\10.00.0.000\\some_path', //WORK
//share: share, FAIL
//share: config.get<string>('SMB_SHARE'), FAIL
//share: process.env.SMB_SHARE, FAIL
domain: '',
username: config.get<string>('SMB_USERNAME'),
password: config.get<string>('SMB_PASSWORD'),
debug: true,
autoCloseTimeout: 0,
})
}
The .env file is like this:
SMB_SHARE=\\\\10.00.0.000\\some_path
SMB_USERNAME=user
SMB_PASSWORD=secret
More than likely, what is happening is JavaScript is escaping the extra \. This is unescaped when the print happens, so it looks proper (i.e. console.log(process.env.SMB_SHARE) will print \\\\10.0.0.0\\some_path, but in reality, the variable is now \\\\\\\\10.0.0.0\\\\some_path). I ended up creating a mock of this using a text file called ./temp/.env and making use of the fs module from Node (which is what dotenv uses, which is what #nestjs/config uses. You can see below the cat (print) of the file, and the two different methods while using node to read the file
~/Documents/code
▶ cat ./temp/.env
HOST=\\\\127.0.0.1:3000\\path
~/Documents/code
▶ node
Welcome to Node.js v12.18.2.
Type ".help" for more information.
> const { readFileSync } = require('fs');
undefined
> readFileSync('./temp/.env').toString()
'HOST=\\\\\\\\127.0.0.1:3000\\\\path\n\n'
> console.log(readFileSync('./temp/.env').toString())
HOST=\\\\127.0.0.1:3000\\path
The solution here, would be to change your .env file to be the exact string you're wanting to pass on to the configuration (probably \\10.0.0.0\some_path)
you have to implement the config module.
start with
npm i --save #nestjs/config
then add the configModule in your appModule:
import { ConfigModule } from '#nestjs/config';
#Module({
imports: [ConfigModule.forRoot()],
})
export class AppModule {}

Typescript to Javascript export

I have a sample typescript objects as
declare const S3 = "https://s3.amazonaws.com/xxx/icons";
declare const SVG = "svg-file-icons";
declare interface MyIcons {
"image/jpeg": string;
"image/jpg": string;
}
export const FILE_ICONS_SVG: MyIcons = {
"image/jpeg": `${S3}/${SVG}/jpg.svg`,
"image/jpg": `${S3}/${SVG}/jpg.svg`
};
I am declaring this object in a share NPM Package to maintain consistency in all my projects. But TSC compilation gives me something like this.
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FILE_ICONS_SVG = {
"image/jpeg": `${S3}/${SVG}/jpg.svg`,
"image/jpg": `${S3}/${SVG}/jpg.svg`
};
As it is evident that S3 and SVG are not defined in the compiled js file and thus gives errors on usage.
How can this be fixed??
Using declare does not really "declare" something.
declare is only used to tell the type-system that something with the declared name and type exists.
If you want to define a constant that should exist outside of the type-system, aka exist at runtime, you have to remove the declare keyword.
declare'd things do not have any impact on the runtime
Why does declare exist?
If you think about how the web works, you have a html file. In that html you can include scripts. Those scripts may be completely independent from one another, but also use stuff from other scripts.
So if you have one file that attaches something to the window for example in one file, and have another file that then uses this object, the typescript type-system has no way of knowing that that object exists, so you can tell the type-system of its existence by using declare
So it should be
const S3 = "https://s3.amazonaws.com/xxx/icons";
const SVG = "svg-file-icons";

How can I reference a type in lib.dom.d.ts in another declaration file?

I'm pretty new to TypeScript and trying to make automated tests where I dependency-inject IndexedDB into my code, but the library I'm using to mock IDB doesn't have a .d.ts, so I tried to roll my own simple declaration file to get around this, which looked something like this:
declare let fakeIndexedDB: IDBFactory;
declare module 'fake-indexeddb' {
export var fakeIndexedDB;
}
However, when I tried using this type, I got the error:
type 'typeof import("fake-indexeddb")' is missing the following properties from type 'IDBFactory': cmp, deleteDatabase, open
Mousing over in VSCode, it looks like the type of IDBFactory is this type from lib.dom.d.ts:
declare var IDBFactory: {
prototype: IDBFactory;
new(): IDBFactory;
};
But what I wanted to import was the interface type directly above it. How would I say in my declaration file that I want to reference the interface in lib.dom.ts, not the var that uses it? I can see that jsdom was able to make a class in their .d.ts that references DOM types with both an interface and var, but they also don't use "declare module".
Problem
The problem with this code:
declare let fakeIndexedDB: IDBFactory;
declare module 'fake-indexeddb' {
export var fakeIndexedDB;
}
is that the type of the exported fakeIndexedDB is any. It's a different variable than the one declared above it. Basically, fake-indexeddb defined like that is a module that exports a single variable called fakeIndexedDB of unspecified type.
Solution
What you should do instead is this:
declare module 'fake-indexeddb' {
const fakeIndexedDB: IDBFactory;
export = fakeIndexedDB;
}
Whether to use export =, export or export default depends on how the actual JavaScript library is built. The above syntax is recommended if fake-indexeddb exports a single member and it's meant to work well when imported using the require function. See if it works, and if not, consult the source code.

Categories