Global object in node.js - javascript

I have in my website a class named classPerson which is in dir /foo. I need to use it in dir ./bar, but since /bar is not allowed to import from /foo i do the following:
/foo:
const classPerson = new classPerson();
Object.assign(window, { classPerson });
/bar:
const person = window.classPerson.
I need to achieve a similar thing in node.js. How can i do it (having no window)

Depending on your project setup, you can use either the built-in require() method or the es6 import module syntax.
in /foo.js
export class ClassPerson { ... } // add the export keyword to the class definition
export const classPersonInstance = new classPerson(); // add the export keyword to the class instance if you want to use the same instance
in /bar.js
const foo = require('./foo.js');
const instance = foo.classPersonInstance;
// or
import { classPersonInstance } from './foo.js';
NOTE
To be able to use the import syntax, you should do some additional configuration
Here is the nodejs documentation for ECMAScript Modules

Related

Building CJS module from ESM with mixed named and default export - how to omit 'default'?

I am trying to configure rollup to build commonjs module from existing esm.
I have set of separate standalone methods, exported with default and available to import directly from package like:
import method1 from 'lib/method1'
And I have single entry point for all of them standalone.js to let user code import them separately using destructuring or at once as lib.
import _method1 from './method1'
import _method2 from './method2'
import _method3 from './method3'
export const method1 = _method1;
export const method2 = _method2;
export const method3 = _method3;
export default {method1,method2,method3};
So this is usage example:
import method1 from 'lib/method1'
//or
import { method1 } from 'lib/standalone'
//or
import standalone from 'lib/standalone'
//standalone.method1();
All this works fine for esm and I want similar experience for cjs.
Rollups do everything almost correct but it's complaining about mixed named/default export and adding extra module.exports.default field:
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var condense$1 = require('./condense.js');
var condenseDeep$1 = require('./condenseDeep.js');
var eachDeep$1 = require('./eachDeep.js');
// ...
var condense = condense$1;
var condenseDeep = condenseDeep$1;
var eachDeep = eachDeep$1;
//...
var standalone = {
condense: condense$1,
condenseDeep: condenseDeep$1,
eachDeep: eachDeep$1,
//...
};
exports.condense = condense;
exports.condenseDeep = condenseDeep;
exports.default = standalone; // <-- this one, how to remove it?
exports.eachDeep = eachDeep;
//...
so in commionjs usage looks like:
const method1 = require('lib/method1');
//or
const { method1 } = require ('lib/standalone');
//or
const standalone = require('lib/standalone');
//standalone.method1();
//standalone.default <--- this is redundant and confusing
I tried output.exports: 'named' rollup option - other entry points which are using default only also started having module.exports.default = .. instead of expected module.exports = ..
I tried output.exports: 'default' - it's not working with mixed default/named exports, throwing error.
A default export is a named export, it's just named default. ESM is built so that if you don't specify a name, it uses the export named default from the JS file.
Using CJS, there's no concept of default exports, everything is named.
The point is, nothing is wrong here. You can't mix named and default exports and use them without specifying .default in CJS.
Maybe this gist thread will help you out.
EDIT: You could always hack it as this answer suggests, but it is a hack, and then you'll lose named exports.

How to export property of a interface/Object like Javascript in TypeScript

As we known, the commonJS module's exports is a JS Object commonly. We can access the specific method easily like const { methodA } = require('module').
How can we impl the .d.ts(types declaration file), allowing the typescript user to enjoy the similar import experience?
We hope to do like that:
// JavaScript
const sdk = require('module')
sdk.methodA(params)
// Or
const { methodA } = require('module')
methodA(params)
// Typescript also can be:
import sdk from 'module'
sdk.methodA(params)
// Or
import { methodA } from 'module'
methodA(params)
That is my current impl:
export * from './interface' // a .d.ts file that includes all interface, is it necessnary exported to users?
interface Instance {
methodA: (params: anthorInterface) => Promise<ResponseInterface>
}
declare const sdk: Instance
export default sdk
But the syntax import { methodA } from 'method' doesn't work, though, the default behavior works fine.
Could you give me any suggestions? Thank you a lot.

My class created doesn't export an object

I need to create the class ShoppingCart in the file ShoppingCart.js and export it to a test file and i get the error that my class is not a constructor
I know the problem is not in import export because before creating the js file i got the error that it couldn't find the module. I also tried creating a new instance of the class inside the file and it worked
file ShoppingCart.js
class ShoppingCart{
constructor(name){
this.name=name
}
}
module.exports = { ShoppingCart}
The code for my test file is
const ShoppingCart = require("./ShoppingCart")
new ShoppingCart()
when i run the test file i get
TypeError: ShoppingCart is not a constructor
You are currently exporting an object with a property of ShoppingCart:
module.exports = { ShoppingCart }
// ^^ object ^^
Just export ShoppingCart:
module.exports = ShoppingCart;
Or, when importing, reference the ShoppingCart property of the object:
const { ShoppingCart } = require("./ShoppingCart")
You're exporting an object with a ShoppingCart property.
Either:
Change your export to module.exports = ShoppingCart;, or
Change your require to const { ShoppingCart } = require("./ShoppingCart");
If you're using a modern version of Node.js, you might consider using ESM (ECMAScript Modules) instead (export/import):
export class ShoppingCart{
constructor(name){
this.name=name
}
}
and
import { ShoppingCart } from "./ShoppingCart.js";
new ShoppingCart();
That uses JavaScript's native modules rather than Node.js's CommonJS variant. Over the new couple of years, this will become the standard way of doing it. For now, to use ESM you use the --experimental-modules flag and a package.json containing type: "module". (Or, instead of the package.json type field, you can use the file extension .mjs.) Details here.

ES6 Imports inside Export default

I'm currently migrating the whole code of a NodeJS application from ES5 to ES6/7.
I'm having trouble when it comes to imports :
First, I understood that making an import directly call the file. For example :
import moduleTest from './moduleTest';
This code will go into moduleTest.js and execute it.
So, the real question is about this code :
import mongoose from 'mongoose';
import autopopulate from 'mongoose-autopopulate';
import dp from 'mongoose-deep-populate';
import { someUtils } from '../utils';
const types = mongoose.Schema.Types;
const deepPopulate = dp(mongoose);
export default () => {
// DOES SOMETHING USING types AND deepPopulate
return someThing;
};
export const anotherModule = () => {
// ALSO USE types and deepPopulate
};
Is this a good practice to have types and deepPopulate declared outside of the two exports ? Or should I declare them in each export ?
The reason of this question is that I'm having a conflict due to this practice (to simplify, let's say that dp(mongoose) will call something that is not declared yet)
You can only have one 'default' export to a module, or you can have multiple 'named' exports per module. Take a look at the following for a good description of handling exports in ES6: ECMAScript 6 Modules: The Final Syntax

ES6 module syntax: is it possible to `export * as Name from ...`?

See question title. I found a great reference for the forms of export available, but I have not seen what I'm looking for.
Is it possible to do something like the following?
// file: constants.js
export const SomeConstant1 = 'yay';
export const SomeConstant2 = 'yayayaya';
// file: index.js
export * as Constants from './constants.js';
I.e. this would provide a named export Constants inside of index.js containing all of the named exports from constants.js.
This answer seems to indicate it's not possible in TypeScript; is the same true for pure JavaScript?
(This example is a bit contrived; in reality I'm trying to have a prop-types.js module that uses named exports for internal use within the React package, but also exports the prop type definitions under PropTypes for external consumption. I tried to simplify for the sake of the question.)
No, it's not allowed in JS either, however there is a proposal to add it. For now, just use the two-step process with importing into a local variable and exporting that:
// file: constants.js
export const SomeConstant1 = 'yay';
export const SomeConstant2 = 'yayayaya';
// file: index.js
import * as Constants from './constants.js';
export {Constants};
Today in 2019, it is now possible.
export * as name1 from …;
The proposal for this spec has merged to ecma262. If you're looking for this functionality in an environment that is running a previous JS, there's a babel plugin for it! After configuring the plugin (or if you're using ecma262 or later), you are able to run the JS in your question:
// file: constants.js
export const SomeConstant1 = 'yay';
export const SomeConstant2 = 'yayayaya';
// file: index.js
export * as Constants from './constants.js';
// file: component.js
import { Constants } from './index.js';
const newVar = Constants.SomeConstant1; // 'yay'
// file: index.js
// note, this doesn't have to be at the top, you can put it wherever you prefer
import * as AllExportsFromThisModule from "./index.js"; // point this at the SAME file
export default AllExportsFromThisModule;
export const SOME_CONSTANT = 'yay';
export const SOME_OTHER_CONSTANT = 'yayayaya';

Categories

Resources