how to use environment variables in nx monorepo libs, exporting to multiple Nextjs apps - environment-variables

I'd like to load some environment variables into functions within my libs, and then be able to re-export this to several different Nextjs applications. i.e.
Within libs/api
export const getDatabaseConnection = () => {
const host = process.env.DB_HOST
const username = process.env.DB_USERNAME
...
return newDatabaseConnection
}
Within apps/myNextJSApp:
import { getDatabaseConnection } from '#myProject/api'
...
const databaseConnection = getDatabaseConnection()
...
When I run nx run myNextJSApp:serve it's unable to pull the environment variables from the .env within the root directory, however if I run nx run api:test it's completely happy. I think I could pull the environment variables from each app individually, and then pass them as params into my library functions, but this seems kind of tedious, and I was hoping theres a blanket solution to this where I could build my library modules with the environment variables, and export them to my NextJS apps.

Environment variables don't suppose to share by multiple apps. And it's better that you don't do it either. Every app you're creating should have its environment file. And don't read the environment from your libs directly. You must load the environment variable in your app and pass it to the lib.
For example, pass the needed config to the libs function:
// libs/api
export const getDatabaseConnection = ({host, username}) => {
const host = host
const username = usename
...
return newDatabaseConnection
}
// apps/nextjs
import { getDatabaseConnection } from '#myProject/api'
...
const databaseConnection = getDatabaseConnection({
host: process.env.DB_HOST,
username: process.env.DB_USERNAME
})
This way, your code is more reusable and maintainable.
And as I said, don't ever share your environment variables between apps.

Related

Vite+SvelteKit - Environment variables hyper-protection

I am trying to make a POC and I'm such making a really simple use-case.
In there, I use a src/lib/db.ts who, for our interest, contains this code
console.log(import.meta.env.MONGO_URI, import.meta.env.SSR);
giving
undefined true
Of course, my .env file contains a definition for MONGO_URI, I tried with VITE_MONGO_URI and could see the value.
I know a way to expose it is to use VITE_MONGO_URI but my point is exactly not to expose it on the client-side.
I checked and the file db.ts is not bundled with the client, even the import.meta.env.SSR being true shows that the bundler knows it's happening on the server.
Question: How to access my private environment variables server-side ?
EDIT: As specified by Shriji Kondan, the API for this purpose has been created now : here
You could use dotenv on the server side, assuming you are using node-adapter, you can have a file _constants.ts in your app
import 'dotenv/config';
export const MONGO_URI = process.env.MONGO_URI;
and then import this variable into your script.
It's not very awesome to put secrets on client-side code. It should be either utilities.ts with a performed action SUPER_SECRET_API_KEY="$ecret#p1Key" in .env file, then request it via in src/lib/utilities/utility.js as explained here :
import { SUPER_SECRET_API_KEY } from '$env/static/private';
export function performApiAction() {
const apiInstance = initialiseApi({key: SUPER_SECRET_API_KEY});
}
or from page.server.ts via form actions as stated here which is preferable way but it's more complex.

How to read config file in electronjs app

It's my first time using Electron JS and nodejs. I've built a small app that reads some records from a database and updates them. Everything is working fine. I have a config file with the database credentials but when I build a portable win app, I cannot figure out how to read the config file that I would like to place next to the exe. I would like to have easy access to the file, so I could run the same app on different databases.
Can anyone tell me if what I want is possible and how? I already tried to get the exe location but I couldn't. I also read a lot of topics here but nothing seems to solve my problem (I might be doing something wrong).
I'm using electron-builder to build my app.
Thanks in advance.
Edit #1
My Config file is
{
"user" :"X",
"password" :"X",
"server":"X",
"database":"X",
"options":
{
"trustedconnection": true,
"enableArithAbort" : true,
"trustServerCertificate": true
}
}
This is what I've and works when I run the project with npm start
const configRootPath = path.resolve(__dirname,'dbConfig.json');
dbConfig = JSON.parse(fs.readFileSync(configRootPath, { encoding: 'utf-8' }));
However, when I build it, the app is looking for the file in another location different from the one where the executable is.
Use of Electron's app.getPath(name) function will get you the path(s) you are after, irrespective of which OS (Operating System) you are using.
Unless your application writes your dbConfig.json file, it may be difficult for your user to understand exactly where they should place their database config file as each OS will run and store your application data in a different directory. You would need to be explicit to the user as to where to place their config file(s). Alternatively, your application could create the config file(s) on the user's behalf (automatically or through a html form) and save it to a location 'known' to the application.
A common place where application specific config files are stored is in the user's application data directory. With the application name automatically amended to the directory, it can be found as shown below.
const electronApp = require('electron').app;
let appUserDataPath = electronApp.getPath('userData');
console.log(appUserDataPath );
In your use case, the below would apply.
const electronApp = require('electron').app;
const nodeFs = require('fs');
const nodePath = require('path');
const configRootPath = nodePath.join(electronApp.getPath('userData'), 'dbConfig.json');
dbConfig = JSON.parse(nodeFs.readFileSync(configRootPath, 'utf-8'));
console.log(configRootPath);
console.log(dbConfig);
You can try electron-store to store config.
Electron doesn't have a built-in way to persist user preferences and other data. This module handles that for you, so you can focus on building your app. The data is saved in a JSON file named config.json in app.getPath('userData').

How to define credentials and environment variables in jenkins shared library

Currently I am having the following code in my Jenkins file
environment {
GITHUB_USER = credentials('GITHUB_USER')
GITHUB_TOKEN= credentials('GITHUB_TOKEN')
DOCKER_USER = credentials('DOCKER_USER')
ARTIFACTORY_USER = credentials('ARTIFACTORY_USER')
}
Since this code is being used in several place I want this code to be in shared library
Like vars/commonCredentials.groovy
What's the best way to archive this and how can I use this in my Jenkins file?

Environment variable not working with Mapbox token on NextJS

I have a Mapbox map which I am trying to pass an environment variable in to using the built-in .env.local integration in NextJS 9.4. As per the Next docs, I am using a .env.local file and in order to expose the env variable to the browser, I am prefixing it with NEXT_PUBLIC_. However, the access token is not being passed through with this setup. When I pass the token in directly, it does work, so I know this is some sort of problem with the .env.local file not passing that particular env variable, even though it does with other tokens.
.env.local:
NEXT_PUBLIC_MAPBOX_TOKEN=my_mapbox_access_token
OTHER_API_TOKEN=my_other_api_token
map.js:
// Works
mapboxgl.accessToken = "my_mapbox_access_token";
// Doesn't work
mapboxgl.accessToken = process.env.NEXT_PUBLIC_MAPBOX_TOKEN;
other.js:
// Also works
class OtherAPI extends RESTDataSource {
constructor() {
super();
this.baseURL = "https://rest.otherapi.com/";
}
willSendRequest(request) {
request.headers.set(
"X-Application-Key",
process.env.OTHER_API_TOKEN
);
}...
So the Mapbox token works when it is passed directly, and the environment variables work when used with other APIs, but for some reason the env variables are not working with the Mapbox API. I've tried with and without the NEXT_PUBLIC_ prefix. What am I doing wrong?
Possibly this
You are using dotenv
Please see this discussion on GitHub:
https://github.com/vercel/next.js/discussions/12754

Electron - restart app / refresh environment variables

I'm currently working on an Electron app which uses a third party software. At some point I'm checking if that software is installed on the user's computer (it has to be in PATH), and if it's not there I just run the installation. As I said, the installation will append a directory to the PATH variable. After this happens, I need to restart the app in order to have access to the updated variables.
I already tried to use relaunch, just as in the docs, but it doesn't refresh the variables:
app.relaunch()
app.exit(0)
If I restart the app manually, then everything works ok.
Does anyone have some ideas ? Thanks.
My solution just works for production:
In production, your application could not get your PC's environment variable. So, when you create mainWindow in main.js, you should read environment variables and pass it to process.env variable. After you relaunch the application, it will reload env again as you expected.
Library in use:
https://github.com/sindresorhus/shell-env
https://github.com/sindresorhus/shell-path
import shellEnv from 'shell-env';
import os from 'os';
import shellPath from 'shell-path';
const isDevelopment = process.env.NODE_ENV === 'development';
function createMainWindow() {
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
},
width: 800,
height: 1000,
});
// ...
if (!isDevelopment) {
// TODO: if we're running from the app package, we won't have access to env vars
// normally loaded in a shell, so work around with the shell-env module
// TODO: get current os shell
const { shell } = os.userInfo();
const decoratedEnv = shellEnv.sync(shell);
process.env = { ...process.env, ...decoratedEnv };
console.log('DEBUG process.env', process.env);
// TODO: If we're running from the app package, we won't have access to env variable or PATH
// TODO: So we need to add shell-path to resolve problem
shellPath.sync();
}
// ...
}
After relaunching the application, the environment variables will be updated.
app.relaunch()
app.exit(0)
Notice: Without check !isDevelopment, after relaunching, the application won't be displayed. I have no idea.

Resources