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();
Related
I try to convert some references on my node projects to Node 19. In particular, the feature "imports" on the file package.json made me wonder on how to import files with an alias.
Example: For a project with source folder src with folders fruits and vegetables, I add the configuration on json content first-order key-values.
"imports": {
"#fruits/*": "./src/fruits/*.js",
"#fruits/*.js": "./src/fruits/*.js",
"#vegetables/*": "./src/vegetables/*.js",
"#vegetables/*.js": "./src/vegetables/*.js",
},
With that, I am able to use import * from "#fruits/fruits.js" or import * from "#vegetables/vegetables.js"
By experience, I learned that I cannot user it more than 1 level of folder-tree level. It means, in case there is still a folder src/fruits/pseudo, I am unable to use import * from "#fruits/pseudo/pseudofruits.js". Is this correct or should I be able to import pseudofruits from the alias?
Your understanding is correct that you can only import files one level deep with configuration you have. One workaround in this situation is to use the relative path instead like:
import * as pseudofruits from "../../fruits/pseudo/pseudofruits.js";
I wrote myself a small package which I use to share different React components between my projects.
The "exports" field in my package.json looks like this:
Since this is a TypeScript project, the transpiled .js in the output directory are specified below.
"exports": {
".": "./lib/index.js"
}
My index.ts file looks like this:
export * from "./Grids";
Then inside my Grids folder i have another index.ts file with the following content:
export * from "./UniversalGrid";
And finally inside the UniversalGrid folder, there is another index.ts file, in which the actual components is getting exported:
export * from "./UniversalGrid";
Now when I want to use the component in my app, I am shown two import suggestions, namely:
import {UniversalGrid} from "#privateComponents/react-components"
and
import {UniversalGrid} from "#privateComponents/react-components/lib/Grids/UniversalGrid"
The first approach (import from /react-components), works without problems.
However, with the second possible import statement (import from /react-components/lib/Grids/UniversalGrid) the following occurs:
Module not found: Error: Package path ./lib/Grids/UniversalGrid is not exported from package C:\Users\<user>\WebstormProjects\PKD\node_modules\#privateComponents\react-components
However, this way the component can be imported without any problems, and also when I select "Jump to definition" I am led to the correct file.
Now I have two questions, first, why is this happening?
And second, how can I import/export my components separately.
Say: Grid1 should be imported from /Grids/Grid1.
Grid 2 should be imported from /Grids/Grid2.
But none of the modules should be imported directly from the /Grids folder.
Thank you very much in advance!
Just dont export Grid in Grids/index.ts, change your transpiled to this
"exports": {
".": "./lib/index.js",
"./Grids/Grid1": "./lib/Grids/Grid1/index.js",
"./Grids/Grid2": "./lib/Grids/Grid2/index.js"
...
},
Now you can import Grid1 from /Grids/Grid1 not from /Grids
created a new project in expressjs. I want to create my own class. So I created a file MyClass.js in /routes/.
class MyClass {
constructor() {
}
}
export default MyClass;
And in /routes/index.js i added:
import MyClass from './MyClass';
And I have an error:
import MyClass from './MyClass;
^^^^^^
SyntaxError: Cannot use import statement outside a module
[...]
What I'm doing wrong?
Your project is not set up properly to interpret the file that has the error as an ESM module file. It is, instead, being interpreted as a CommonJS module (where you use require(), not import) which is the nodejs default.
There are a number of ways to tell nodejs that your file is supposed to be an ESM module.
You can give it a file extension of .mjs.
You can add "type": "module" to your package.json file.
You can use the --input-type=module command line argument when starting node.js if this file is your top level file you're executing.
See nodejs doc here on this subject.
FYI, you could just switch to the CommonJS syntax of using require() and module.exports instead of import and export, but I assume what you really want to do is to tell nodejs that you want to use ESM modules so you can use the more modern import and export syntax.
Well first of all to export your class you suppose to use exports or module.export
and to import it you suppose to use require('') not import.
Those features are only available with .mjs or if you will setup babel though soome es6 features are yet to land in
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.
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