nodejs import url from string - node.js

I am new to nodejs REST api creation. I am using ES6 format. I have decided to create an environment based configurations and stored in different files.
So the issue I came across was
const myUrl = path.resolve(`lib/${process.env.NODE_ENV}.js`);
import { myVar } from myUrl;
I try importing files like shown above, but it doesnt work. I understand it can be easily solved by using
const myVar = require(myUrl)
But I want to know if there is any way to continue using import itself instead of require?
MDN has all ways of importing, but i could not find a way on how to import from a constructed url like above

The ES6 import format only allows imports from static string literals, as it is being evaluated at load time (before executing any code).
If you really want to load the module dynamically based on your environment, use the dynamic form of import (not require):
var promise = import("module-name");
However, maybe you would like to use the more standard way: store your environment configurations in .env files, use the dotenv library to load the configuration dynamically from the correct location - while the code that loads it is static and is the same for all environments, in a dedicated module, and then it can be statically imported by your app code.

Related

Is there a way to predefine common imports for all test files in Jest?

I am using Jest to test a React app. I keep repeating the same import statements for some common libraries/functionalities I need in every test. I was wondering if there was any way to tell Jest to import those libraries before every test.
I achieved it by importing the necessary libraries in setupTests.js, which, if existent, is called by default before every test file. In order to make the imported library available to the tests, I had to do the following:
Let's say I need mount from enzyme to be imported in every test.
// setupTests.js
import { mount } from 'enzyme';
global.mount = mount;
This way, I can directly use mount in any test file without needing to import it.

Unable to import from a relative path using node js

Currently my automation framework built on Cucumber+ Nodejs+ webdriverio. It has the following structure for data files
main/
..../data
......../region1.js
......../region2.js
In my step definition I need to import the data files so that my functions can use the data as per the region I intend to execute which I provide during run time
How should I mention my import command? for example, I tried the following but that does not work
import users from '../main/data/*';
Posting a solution which I came across
Step 1: Add an index.js file under /data folder
Step 2: Adding the following code in index.js
import * as region1 from "../region1"
import * as region2 from "../region2"
export {
region1,
region2
}
Now in the file that requires this data, add the following import line
import myValues from "./main/data"
You need to pass your required region from command line as an environment variable lets say as REGION
If you want to access a value from respective region file based on value passed in REGION, the following code will work
const myreqData = myValues[process.env.REGION].<respective node in the js]

How can I automatically 'audit' or 'rationalise' my imports in a NodeJS project?

I'd like to be able to go through my project and automatically change all instances in which an entire library is imported when only one export of that library is needed to only import the export(s) needed. Thus
import R from 'ramda'
const sillyValue = R.add(2,3)
const moreSilly = R.always('foo')
would be changed to
import {add, always} from 'ramda'
const sillyValue = add(2,3)
const moreSilly = always('foo')
Is there any sort of utility that I can run to do this automatically for all the modules in my project at once? I have WebStorm, but so far I haven't found any way to do it using the IDE ('Optimize Imports', while nice, doesn't seem to do what I want).
WebStorm doesn't have such inspection; you can try using ESLint for this, see eslint-plugin-import plugin, no-named-as-default-member rule

Importing node modules once for whole project

Scenario
So, I have initialised a Node project with npm. I have setup my package.json accordingly. I am using typescript, so I have also setup tsconfig.json.
I have a few dependencies (npm packages) that I will need to use multiple times in multiple files of my project.
index.ts is the root of my project. I can import these libraries in index.js and other files also.
Problem
Is there any way to include or import these libraries in the project only once so that I can use them in any file of the project without having to import a single thing anywhere.
I tried searching for various ways to do this using -
CommonJS module syntax, NodeJS module syntax, global modules - but none of it can provide me the way I want it.
For Ex -
Most of the answers or solutions I got were like this
Export all the libraries through a single file
import abc from 'abc';
import xyz from 'xyz';
module.exports = {
abc, xyz
};
Use these libraries in other files like
import modules from 'src/modules.ts'
var wantSome = modules.abc.getSome();
But, this still has an overhead of importing modules file and accessing it like modules.abc.
Do we have any way to make these imports available globally through out the project.
P.S. - This scenario is somewhat similar to ngModules in Angular 2+, where we can import whatever we want inside ngModules and it is then available to all the components under that module.
Doing this is going to cause you all sorts of problems in the long run.
you'll end up with one monolithic file containing all your exports, which will become onerous to maintain
if you decide to modularise your code, it will be more difficult since you won't explicitly know which modules a file uses
if you were able to include to the point where you simply use the modules with no reference, code clarity will suffer
name clashes might occur
The best I believe you'll get in node is to declare all the includes in a single module, and then destructure within your own file.
import abc from 'abc';
import xyz from 'xyz';
module.exports = {
abc, xyz
};
Then
import modules from 'src/modules.ts'
{ abc: { getSome } } = modules
But I strongly suggest using the standard patterns for importing. It will make your code much cleaner and easier to maintain
N/B - Thats a bad way to design your app.
In node, you can set global variables via the "global" or "GLOBAL" object:
You could import all your dependencies in your app entry file, and store them in a Global variable
index.js
import abc from 'abc';
import xyz from 'xyz';
global.abc = abc
global.xyz = xyz
someotherfile.js
//access abc import
global.abc
Export all the libraries through a single file
import abc from 'abc';
import xyz from 'xyz';
module.exports = {
abc, xyz
};
Use these libraries in other files like
import {abc, xyz} from 'src/modules.ts'
var wantSome = abc.getSome();

fs.readFileSync is not a function

I am using rn-nodeify for enabling the use of pdf2json in React Native. pdf2json uses fs for loading files using the method readFileSync. I am getting this error when I try to use the library:
fs.readFileSync is not a function. (In 'fs.readFileSync(_basePath + fieldName, 'utf8')', 'fs.readFileSync' is undefined)
I cannot find any support for this issue. Any pointers appreciated.
Edit: Please note that I am not trying to run this in a browser. This pertains to react-native i.e. it runs on a device, and the code should have access to the file system.
FWIW, I came across this problem while writing tests in ES6/latest JS - fixed this by changing the import from:
import { fs } from 'fs';
to
import fs from 'fs';
Notice the unnecessary {} - fs is the default export from the fs node module and should be imported in the latter way
For a better explanation on default & named exports please see this SO discussion

Resources