Accessing non-existent property of module exports inside circular dependency - javascript

i'm having an circular dependency warnings in my node project that caused by index.js file that i wrote to combine some exports, the file look like this: path: utils/index.js.
const mysql = require('./mysqlDB');
const logger = require('./logger');
const ServerError = require('./ServerError');
module.exports = {
mysql,
logger,
ServerError
}
so I can import those in other files like this (lets said its called user.js):
const { logger, mysql, ServerError } = require('../utils');
so now if im requring user.js in another file thats include also things from utils.js
im getting the circular dependency warnings and errors after that...
when i deleted the index.js file that I wrote and requried the utils directly int my user.js file the warnings gone.
I'm not sure what I do wrong.
Thanks.

Related

How to correct: SyntaxError: Named export 'mongo' not found

Trying to run a simple script to create a user with mongoose using nodejs. So basically just running node my_script.js which is the official way as per Run Node.js scripts from the command line
I have tried importing in the following ways:
import Connection from 'mongoose';
const { mongo } = Connection;
import mongoose from "mongoose"
import mongoose from "node_modules/mongoose/index.js"
const mongoose = require("mongoose")
Also tried adding the following lines to package.json:
"type": "module",
"esModuleInterop": true,
Complete error seen below for most of the import cases above:
import mongoose, { mongo } from "mongoose";
^^^^^
SyntaxError: Named export 'mongo' not found. The requested module 'mongoose' is a CommonJS module, which may not support all module.exports as named exports.CommonJS modules can always be imported via the default export, for example using:
import pkg from 'mongoose';
const { mongo } = pkg;
at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
at async ModuleJob.run (internal/modules/esm/module_job.js:143:5)
at async Loader.import (internal/modules/esm/loader.js:165:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5)
From mongoose index.js file I do not see any other export besides:
const mongoose = module.exports = exports = new Mongoose({
[defaultMongooseSymbol]: true
});
Found this github issue Misleading error that module does not provide export
#32137 but still not sure how to make this import to work.
This "appears" to be the fix which is the only thing that happened after I took a break.
I had 2 files: B.js and A.js
from A.js:
import foo from "./B.js";
import mongoose from "mongoose";
I decided to run B.js on it's own to see if it would give me the same error(it had a mongoose import as well), it turn's out there was another different error:
foo.pre(save, function(next) {
^ ReferenceError: save is not defined
Ok nothing biggy, corrected it and node B.js worked fine when running it, hence decided to test with node A.js, which worked just fine to my surprise!
This turned out to be completely counterintuitive, as the error mentioned initially was not pointing to this.

Nodejs - import stuff from mjs file into js file OR how to use require in mjs file?

I am new to JS and Node. From what I been reading it seems like ES6 import is not supported in Node so I am forced to use experiment mode (renaming my file to mjs)
This works for the most part unless the mjs file needs to use require. My current solution is to break out the chunk of code that depends on require to a seperate .js file and import that js file
foo.mjs
import readFileSync from './util.js'
...
//orignally just do require('fs') and do fs.readFileSync()
const configFile = readFileSync(configFilePath);
util.js
const fs = require('fs');
const path = require('path');
function readFileSync(filePath) {
console.log(__dirname)
console.log(path.resolve(__dirname, filePath))
return fs.readFileSync(path.resolve(__dirname, filePath), 'utf8');
}
module.exports = readFileSync
Is there a way I can avoid doing this? My app.js has lots of require and I don't want to break out all those parts into separate js files.
I tried changing require to import
// const express = require('express');
import * as express from 'express';
but when run node --experimental-modules app.mjs
I get an error
TypeError: express is not a function
I think I need to either
find a way to use require in mjs
or find a way to import stuff in mjs into a js file
You have three decent options:
Use Babel or TypeScript to get interoperability between the two types of modules
Write a little wrapper to redefine require in ESM code
Use import() (dynamic import) in your CJS to import ESM code
The wrapper to use require in ESM code:
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
const cjsFile = require('./test') // test is regular .js file using module.exports
Dynamic imports:
// foo.mjs:
export const foo = () => true
// index.js:
import('./foo.mjs').then(x => console.log(x.foo()))
Large projects with mixed module types frequently use Babel and/or TypeScript, both of which handle the mixed types just fine. Babel would be simpler to learn and get set up. But if you don't have a ton of code to deal with, the createRequire method works just fine.
As for the issue with Express, it failed because the default export is what you want: import express from 'express', not import * as express....

overwrite config file in nodejs - best practice?

Wondering what would be the best practice for my case.
I have a variable I need to set its value on app load and access this value many times across my code. what is the best way to get this value?
Right now I'm just overriding a config file property. Does a global variable is better? Is there another way to do this?
The priority standard for configs IMHO is:
command line parameter
environment var
local config file
global config file
if no cli parameter found, fall to look into environment vars, then local config file, then global
I do this.
Put the variable in .env file:
# .env
APP_PORT=4000
In my app source code, I create a file named constants.js:
// constants.js
import { load as loadEnvVars } from 'dotenv'; // run `npm i dotenv` to install
// load the .env file content to process.env
loadEnvVars();
// export the variables I need
export const APP_PORT = process.env.APP_PORT || 3000;
I import that file when I need it like this:
// server.js
import Express from 'express';
// import the constant
import { APP_PORT } from './constants';
const app = Express();
app.listen(APP_PORT, () => console.log('server deployed');

include bundle compiled with webpack to use in another js file

I have the following structure of my app:
index.js
const app = require("./app")
exports.api = app(...)
app.js
//all the imports goes here
//and exporting the main function
module.exports = app => {...}
Now I need to bundle app.js with webpack but index.js must stay intact
The question is, after bundling the app.js, how can I require it's main function app from index.js?
After webpacking app.js I'm getting error in index.js that says "app is not a function" which makes sense since app.js content is now wrapped in webpack staff.
Any suggestions are much appreciated.
Your "app" bundle needs to be exported as a commonjs.
module.exports = {
//...
output: {
library: 'app',
libraryTarget: 'commonjs',
}
};
The return value of your entry point will be assigned to the exports object using the output.library value. As the name implies, this is used in CommonJS environments.
So, in your index.js you can require('./dist/bundle-name.js').
seems to be a hack, but I made it work by adding an intermediate file and adjusting app.js and index.js like below:
index.js
const app = require("./bundle").app //changed to named import
exports.api = app(...)
bundle.js //an intermediate file which is now an entry point for webpack
import app from "./app"
exports.app = app
app.js
//all the imports goes here
//and exporting the main function
export default app => {...} //changed to default export
If anyone has explanation on why it works this way and how to simplify it without adding that bundle.js file, you are very welcome to comment!

Require a single function

i am trying to export a file that has some configuration of my jwt, so i need to get those in my router
my exported function:
module.exports = {
'secret': 'sdasda',
'expirationTime': 60*60*24*4
};
requiring the function
var jwtConfig = require('../config/jwt');
and i get this error: Cannot find module './config/jwt'
the config folder is 1 path above, and the jwt file is inside :S
Any tip?

Categories

Resources