NestJS MissingDriverError: Wrong driver: "undefined" given when TypeOrmModule is reading ormconfig.js file - nestjs

I am running a Nest JS application in development mode. The app module is like below. I kept the configuration details inside the ormconfig.js so that both TypeormModule and Typeorm CLI would be able to do the migrations.
#Module({
import: [
TypeormModule.forRoot()
]
})
ormconfig.js :
module.exports = {
"type": "sqlite",
"database": "db.sqlite",
"entities": ["**/*.entity.js"],
"synchronize": false
}
I am running the development server using cross-env NODE_ENV=development nest start --watch command. I am getting the error :
Wrong driver "undefined" given. Supported drivers are: "aurora-mysql", "aurora-postgres", "sqlite" etc.
I clearly know the error here i.e., Typeorm is failing to pick up configuration details from the ormconfig.js file. Other solutions like adding Typeorm.forRootAsync and loading config details directly in Typeorm.forRoot({...configDetails}) are out of scope here.
Do I need to do any specific configuration so that Typeorm would pick the config details from ormconfig.js?

The issue is resolved by using the below steps.
Pass the config object that is exported from ormconfig.js as the parameter of TypeormModule.forRoot() like below inside the appmodule file.
const dbConfig = require("PATH_TO_YOUR_CONFIG_FILE");
TypeormModule.forRoot(dbConfig)
If it still doesn't work, Delete the dist folder and re-run the yarn start command. The cache issue will be resolved with this step.

Related

TypeORM configuration

I'm writing a Typescript NodeJs server.
I use TypeORM and for work it needs a config file with two arrays of paths or functions to entities and migrations.
Right now it looks like
{
subscribers: ['build/subscriber/*.js'],
migrations: ['build/migration/*.js'],
}
When I'm starting my app it'll be transpile with tsc and create a build folder with js files. And in these case everything works fine.
But TypeORM have a CLI tool, and I want use it for creating migrations. But I don't want to transpile all projects just to create migration. I'd run the CLI command with ts-node and use ts files. But without transpiration "build/subscriber/*.js" doesn't exist.
Can I do something to use TypeORM CLI without transpiration the whole project?
P.s. If I change config paths to
{
subscribers: ['src/subscriber/*.ts'],
migrations: ['src/migration/*.ts'],
}
The project will stop running.
May there exists a way to see in code transpiled them or not to implement something like optional paths
{
subscribers: isTranspiled ?['build/subscriber/*.js'] : ['src/subscriber/*.ts'],
migrations: isTranspiled ? ['build/migration/*.js'] : ['src/migration/*.ts'],
}
We have the same problem and do the following:
// Hack for webpack
const migrations_path = __dirname.trim() === '/usr/src/app/dist' ? __dirname.trim() : path.join(__dirname, '..');
{
...
migrations: [migrations_path + '/typeorm/migrations/*.{js,ts}'],
}
You'll need to update for your own paths, but this is how we support the dist for production webpack build and for our src folder during hot reloading.

NodeJS not recognizing .env file

I have like 5 NodeJS services running, but I have a problem in one of those.
This is the nodemon.json file:
{
"watch": ["**/*.ts"],
"ext": "ts,json",
"ignore": ["./test/*.ts"],
"exec": "node -r ts-node/register -r dotenv/config Index.ts dotenv_config_path=$(pwd)/.env",
"env": {
"NODE_ENV": "development"
}
}
It's the same as the rest of services. When I run npm run dev I got error messages depending on which value is taking from the .env file, example:
const LOCAL_CONFIGURATION = {
PORT_APP: 8082,
MONGODB: {
SERVER: process.env.MONGO_DTE,
AUTH: {
auth: {
password:process.env.MONGO_PASSWORD,
user:process.env.MONGO_USER
}
},
},
MS_NOTIFICACION: "http://localhost:8089/notificacion",
ELASTIC_PATH: process.env.ELASTIC_PATH,
...COMMON,
};
The first error message is:
ConfigurationError: Missing node(s) option
That message is produced because it's not reading the value from process.env.ELASTIC_PATH, but if I put a hardcoed value like "http://with.the.correct.url" and it tries again to run, I get another error:
Error: Credentials must be provided when creating a service client
That error is because it's trying to read password:process.env.MONGO_PASSWORD and user:process.env.MONGO_USER
etc, so, there's a problem on reading the .env file. I know that .env file has those values, and the file is in UTF-8, without quotes, etc. The .env file is the same file as the other services, it works ok in the rest but I don't know why is not getting read here.
Any idea?
EDIT:
Plus, I put a console.log(process.env); in config.ts file and it shows values like this:
But there's no values from the .env for example, there in the picture there's a value called COMPUTERNAME so if I put console.log(process.env.COMPUTERNAME); I get: IBM-NOT87
Why is not getting the .env file?
Seems like you need to require/configure dotenv. Docs:
As early as possible in your application, require and configure dotenv.
require('dotenv').config()
To further expand on #JBallin answer
you should use this on your app.js
Or if that does not work then you will need to explicitly add it to the file you are wanting to use those Variables
Sharing image, as its sometimes easier to see expanded
code here =>
require('dotenv/config') // require the dotenv/config at beginning of file
const express = require('express')
const mongoose = require('mongoose')
require('dotenv').config({ path: "./sample.env" });
In the file you are using environment variables,
As early as possible, require the "dotenv" and in the config() method, specify the path of the .env file, even if it in your root directory or the same directory where node starts.
The code for requiring and specifying file in the same directory is in the first line in the answer.
Also, for further reading 📖 , you can visit https://github.com/motdotla/dotenv#path
You cat try this.
-> npm i dotenv
and in code add this piece of code
require('dotenv').config({
path: 'your path here'
})
Install dotenv package
npm install --s dotenv
And add this require("dotenv").config(); in index.js/ts file.

Using Environment Variables in nuxt.config.js

I'm using Nuxt & Axios but having trouble using environment variables when building the application from my local machine.
I have installed the #nuxtjs/dotenv module in an attempt to fix this issue but still having problems.
Note: The environment variables work fine when building the app within my hosting providers environment. It is only building from my local machine that gives me trouble. My IDE is VS Code.
Here is my axios setup inside nuxt.config.js:
module.exports = {
...
buildModules: [
'#nuxtjs/dotenv'
],
modules: [
// Doc: https://axios.nuxtjs.org/usage
'#nuxtjs/axios'
],
axios: {
baseURL: process.env.BASE_URL
},
...
}
My .env file has the following:
BASE_URL="https://some.api.com"
The .env variables are not being recognized when building the app:
nuxt build
Instead, it just sets the axios base url to the same host:port that the server runs on by default. Ex: localhost:4000
I found the following documentation from #nuxtjs/dotenv module: https://github.com/nuxt-community/dotenv-module#using-env-file-in-nuxtconfigjs. This instructs you to add the following to the top of nuxt.config.js:
require('dotenv').config()
This works for building locally; my variables from .env are recognized! However, because dotenv is a dev dependency, this causes the build to crash when deployed to my hosting provider because the module isn't recognized.
I know that I can define the environment variables directly in the build command as follows but I would prefer NOT to do so:
NUXT_ENV_BASE_URL=some.api.com nuxt build
Is there an easy way to get environment variables to work locally inside of nuxt.config.js during the build process that also works well when deploying to production??
Thank you!
Updated 2020-09-26
As of 2.13.0 I have removed #nuxtjs/dotenv. My nuxt.config.js now simply reads as below with the dotenv imports removed. I made no other code changes and the rest functions exactly the same for me.
env: {
DB_HOST: process.env.DB_HOST
},
My .env contains the following.
DB_HOST=http://localhost:5001/
Original answer
I installed the following as a dev dependency; #nuxtjs/dotenv. Then I added the following to my nuxt.config.js. I found this import statement in an article and tried it. Thankfully it worked for me.
import dotenv from "dotenv";
dotenv.config();
env: {
DB_HOST: process.env.DB_HOST
},
I created a file called .env with the following content
DB_HOST=http://localhost:5001/
In nuxt version v2.13.0, support for Runtime Config was added. This adds proper support to read environment variables at runtime. Previously they could be read but were compiled into the application.
The standard documentation is pretty good: https://nuxtjs.org/guide/runtime-config/ .
There is also a great blog post on how to migrate. You remove the use of #nuxtjs/dotenv.
https://nuxtjs.org/blog/moving-from-nuxtjs-dotenv-to-runtime-config/
For example, in your nuxt.config.js, you define.
// Public env variables that are exposed on the frontend.
publicRuntimeConfig: {
someAccessKeyId: process.env.SOME_ACCESS_KEY_ID,
},
// Private env variables that are not be exposed on the frontend.
privateRuntimeConfig: {},
Then in your vue code, you access it via.
const { someAccessKeyId } = this.$config

How to import a node module inside an angular web worker?

I try to import a node module inside an Angular 8 web worker, but get an compile error 'Cannot find module'. Anyone know how to solve this?
I created a new worker inside my electron project with ng generate web-worker app, like described in the above mentioned ng documentation.
All works fine until i add some import like path or fs-extra e.g.:
/// <reference lib="webworker" />
import * as path from 'path';
addEventListener('message', ({ data }) => {
console.log(path.resolve('/'))
const response = `worker response to ${data}`;
postMessage(response);
});
This import works fine in any other ts component but inside the web worker i get a compile error with this message e.g.
Error: app/app.worker.ts:3:23 - error TS2307: Cannot find module 'path'.
How can i fix this? Maybe i need some additional parameter in the generated tsconfig.worker.json?
To reproduce the error, run:
$ git clone https://github.com/hoefling/stackoverflow-57774039
$ cd stackoverflow-57774039
$ yarn build
Or check out the project's build log on Travis.
Note:
1) I only found this as a similar problem, but the answer handles only custom modules.
2) I tested the same import with a minimal electron seed which uses web workers and it worked, but this example uses plain java script without angular.
1. TypeScript error
As you've noticed the first error is a TypeScript error. Looking at the tsconfig.worker.json I've found that it sets types to an empty array:
{
"compilerOptions": {
"types": [],
// ...
}
// ...
}
Specifying types turns off the automatic inclusion of #types packages. Which is a problem in this case because path has its type definitions in #types/node.
So let's fix that by explicitly adding node to the types array:
{
"compilerOptions": {
"types": [
"node"
],
// ...
}
// ...
}
This fixes the TypeScript error, however trying to build again we're greeted with a very similar error. This time from Webpack directly.
2. Webpack error
ERROR in ./src/app/app.worker.ts (./node_modules/worker-plugin/dist/loader.js!./src/app/app.worker.ts)
Module build failed (from ./node_modules/worker-plugin/dist/loader.js):
ModuleNotFoundError: Module not found: Error: Can't resolve 'path' in './src/app'
To figure this one out we need to dig quite a lot deeper...
Why it works everywhere else
First it's important to understand why importing path works in all the other modules. Webpack has the concept of targets (web, node, etc). Webpack uses this target to decide which default options and plugins to use.
Ordinarily the target of a Angular application using #angular-devkit/build-angular:browser would be web. However in your case, the postinstall:electron script actually patches node_modules to change that:
postinstall.js (parts omitted for brevity)
const f_angular = 'node_modules/#angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js';
fs.readFile(f_angular, 'utf8', function (err, data) {
var result = data.replace(/target: "electron-renderer",/g, '');
var result = result.replace(/target: "web",/g, '');
var result = result.replace(/return \{/g, 'return {target: "electron-renderer",');
fs.writeFile(f_angular, result, 'utf8');
});
The target electron-renderer is treated by Webpack similarily to node. Especially interesting for us: It adds the NodeTargetPlugin by default.
What does that plugin do, you wonder? It adds all known built in Node.js modules as externals. When building the application, Webpack will not attempt to bundle externals. Instead they are resolved using require at runtime. This is what makes importing path work, even though it's not installed as a module known to Webpack.
Why it doesn't work for the worker
The worker is compiled separately using the WorkerPlugin. In their documentation they state:
By default, WorkerPlugin doesn't run any of your configured Webpack plugins when bundling worker code - this avoids running things like html-webpack-plugin twice. For cases where it's necessary to apply a plugin to Worker code, use the plugins option.
Looking at the usage of WorkerPlugin deep within #angular-devkit we see the following:
#angular-devkit/src/angular-cli-files/models/webpack-configs/worker.js (simplified)
new WorkerPlugin({
globalObject: false,
plugins: [
getTypescriptWorkerPlugin(wco, workerTsConfigPath)
],
})
As we can see it uses the plugins option, but only for a single plugin which is responsible for the TypeScript compilation. This way the default plugins, configured by Webpack, including NodeTargetPlugin get lost and are not used for the worker.
Solution
To fix this we have to modify the Webpack config. And to do that we'll use #angular-builders/custom-webpack. Go ahead and install that package.
Next, open angular.json and update projects > angular-electron > architect > build:
"build": {
"builder": "#angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./extra-webpack.config.js"
}
// existing options
}
}
Repeat the same for serve.
Now, create extra-webpack.config.js in the same directory as angular.json:
const WorkerPlugin = require('worker-plugin');
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
module.exports = (config, options) => {
let workerPlugin = config.plugins.find(p => p instanceof WorkerPlugin);
if (workerPlugin) {
workerPlugin.options.plugins.push(new NodeTargetPlugin());
}
return config;
};
The file exports a function which will be called by #angular-builders/custom-webpack with the existing Webpack config object. We can then search all plugins for an instance of the WorkerPlugin and patch its options adding the NodeTargetPlugin.

Pass config variables from package.json to Browserify

Is it possible to pass defined in 'config' section of package.json variables to browserify? All is running from 'script' section such:
"config": {
"API": "somePathToAPI",
"port": 9999
},
"scripts": {
"prewatch:js": "browserify app/js/app.js -o out/bundle.js -d",
"watch:js": "watchify app/js/app.js -o out/bundle.js -v -d",
"start": "npm run watch:js"
}...
The idea is to pass both API and port variables to Browserifys environment (for example proccess.argv or process.env properities accessible from window object).
I'm not sure if it's important but I try to achieve this on Windows 7 machine.
Or maybe this approach is wrong and You use some other technics to store Yours config variables?
All values in your package.json are exported to the environment. The variable names should be $npm_package_config_API and $npm_package_config_port.
You can see all the exported variables by running npm run env. (Depending on your version of npm, you may need to add the env script yourself: "scripts": { "env": "env" })
You can even override the variables in scripts too, by prefixing them with your package name and the variable's name. Check out the examples here: NPM Config Variables
You might also want to check out Per-Package Config Settings.
If you're just looking for a transform to keep the environment as literals in your code, checkout envify.
there is no way to access them in clientside js code, but on serverside code:
var port = process.env.npm_package_config_port;
var api = process.env.npm_package_config_API;
EDIT: You could create a cookie with port and API server-side and send it to the client.

Resources