es6 how to import already defined in another js package - javascript

I have a package that I use somewhat like this:
import { something } from 'somewhere';
But then I have another package that I import, and I need to define the same something name which is defined in it.
import myConsts from 'SomewhereElse';
const { something, another } = myConsts;
I get an eslint error (and rightly so) something already defined.
Here's a real example:
import { connect } from 'react-redux';
// following lines from react-native-kontaktio sample code...
import Kontakt from 'react-native-kontaktio';
const { connect, configure, startScanning } = Kontakt;
I tried
import { connect as kontaktConnect, configure, startScanning } from 'react-native-kontaktio'
but get Possible promise rejection ... (reactNativeKontaktio.connect) is not a function.
If I try to change the
import { connect as reduxConnect } from 'react-redux';
I'll have to change the export as follows. Won't that break my code elsewhere?
// export default connect(mapStateToProps, mapDispatchToProps)(AppMain);
export default reduxConnect(mapStateToProps, mapDispatchToProps)(AppMain);
How can I overcome this? Can I ignore the warning in some cases? There is no Polymorphism in Ecma6 right?
This is NOT a question about two classes with the same name, but about two classes with a method or a constant of the same name.
The answer there seems to be applicable here, to use:
// instead of: import myConsts from 'SomewhereElse';
import { something as somethingElse, another } from 'SomewhereElse';
But then, when I use... somethingElse().then(()=> ... I get an error Possible promise rejection ... (SomewhereElse.something) is not a function
This also is NOT a [question about fixing the general is already defined eslint error] (Javascript standardjs - how to fix 'is already defined'?), since I am not talking about writing MY code, but rather how to import and use someone else's two packages when they have this clash problem.

No I think you can't ignore the warning, because 2 variables with the same name are present in the same scope.
You may need to import in this way:
import { connect as somethingElse} from 'react-redux';
To avoid to variables with the same name.
I hope it will help you

Related

SyntaxError: ambiguous indirect export: default Error when importing my own class

I have written a validation class and want to include it in my VueJS 3 project. Unfortunately I get the following error: SyntaxError: ambiguous indirect export: default
This is my code:
// ..classes/formValidationClass.js
export class FormValidator {
...
}
// some vue file with a form
import FormValidation from "..classes/formValidationClass"
export default {...}
Question:
What does this error mean and what do I have to do to correct the error?
Use brackets {} around your import Name
// ..classes/formValidatorClass.js // Comment: => suggestion change your file name to similar your class name
export class FormValidator {
...
}
// some vue file with a form
// import FormValidation from "..classes/formValidationClass"
import { FormValidator as FormValidation} from "../classes/formValidatorClass"; // Comment: => use brackets around your import name. if you want use FormValidation you can use also a alias (`originalName as newName`)
export default {...}
I found that none of the tsconfig, package.json fixes would never work for me. Hopefully the following helps someone in the future.
I was consistently getting this error when working with Vite projects and not Webpack projects. I would not be able to import anything, named or otherwise.
On one Svelte code base I ran the Svelte CLI sync command and it mentioned a type import was breaking the importsNotUsedAsValues or preserveValueImports and that I should explicitly mark the import as a type.
The import statement in question:
import { TUser } from '../models/Users/Users';
TUser exported as:
export type TUser = { ... }
Errors
Would cause the following errors:
Error: This import is never used as a value and must use 'import type' because 'importsNotUsedAsValues' is set to 'error'. (ts)
Error: 'TUser' is a type and must be imported using a type-only import when 'preserveValueImports' and 'isolatedModules' are both enabled. (ts)
Solution
Doing the following fixed the issue for me.
import type { TUser } from '../models/Users/Users';
My story: WebStorm generated .js files right next to .ts files (because I once enabled the Recompile on changes option), so my app tried to import from .js files instead of .ts one. That was the reason for the import problems.
This is the compiled code on the local dev server:
For the sake of helping anyone bumping into this error and arriving at this page, the word default in export default function myFunction() can cause this error. Or in other words: remove the word default may help.
In my case I had the curly braces where I shouldn't have. I had a JSON file and import { users } from ... where instead I should have no curly braces like so:
import users from './users.json';
console.log("users", users);

ECMAScript import { } from './somwhere.js'

I'm trying to fully understand JavaScript import and exports. According to the syntax diagram on https://tc39.es/ecma262/#sec-exports it's valid to have an empty block which I assume means import nothing so what is it for? Example:
import { } from './somewhere.js'
It will run the code in somewhere.js. That might be useful for initializing something, but if that's all you need, you can get the same effect with:
import './somewhere.js'
So i don't really see a reason to write the example you're asking about.
If i had to guess, i'd assume the reason it's allowed is that a definition allowing N named imports (eg, import { foo, bar, baz } from './somewhere.js") would very easily have a base case of import { } from './somewhere.js, and there just wasn't a reason to ban the empty case.
Let's take code bellow as our example
./somewhere.js
console.log('imported');
export const PI = 3;
Importing code above using import { } from './somewhere.js' will result in logging into console. The same would be true for import './somewhere.js'.

How to get around airbnb eslint import/prefer-default-export rule when using index.js for exports

For cases like this,
/ACollectionOfTinyComponent/index.js
import Container from './Container';
export {
Container,
};
So the index.js becomes a directory to include other small parts without having to write each Component Name out all the time.
So in this case, we can import a component in another component like following:
import {Container} from './ACollectionOfTinyComponent'
//then use Container in the code here
Is this a bad practice? Since if I have airbnb linter enable then I got error linting of
Prefer default export import/prefer-default-export
it asks me to add default but that will cause compile error
I found out that because I added only ONE import & export for the index.js. But if I add more than one its fine!
For example, if I do
import Container from './Container';
import Ezeewei from './Ezeewei';
export {
Container,
Ezeewei,
};
Note that I added one more import of Ezeewei.
Then the linting rule will pass!
it asks me to add default but that will cause compile error
You must be using the wrong syntax for exporting a default.
export { name1 as default, … };
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Syntax
import {Container} ... Is this a bad practice?
Yes. If you have a single entry point into a component (like a a class), you should export it as the default rather than a named export. The designers of the language gave default imports and exports a special syntax to promote it as the primary use case.
http://2ality.com/2014/09/es6-modules-final.html#default-exports-are-favored

Should I use both `import 'rxjs/Rx'` and `import { Observable } from '#rxjs/Observable'`

import { Injectable } from '#angular/core';
import { Headers, Http, Response } from '#angular/http';
import { Observable } from '#rxjs/Observable';
import 'rxjs/Rx';
import 'rxjs/add/observable/throw';
#Component({});
export shellModule{}
This is a piece of code form my Angular app that I copied from somewhere (I have removed the definitions in the exported module. I am using it to make a service to call APIs.
In the imports in this particular file, why is it that Observable is imported separately even though the entire rxjshas been imported. If a particular module is being imported in its entirety, why is a particular object from it imported separately? I tried asking this question at the forum from where I took it, but there was no answer. I want to understand if this somehow helps with optimization of code.
In general:
In Typescript, the way modules are handled would require you to either load in the entire library with the import * as rx from 'rxjs/Rx', or a specific exported module within the library to use it, so the the compiler loads in the types.
Reducing your imports to only the specific modules you need sets up your app to use tree shaking from Angular's AOT compilation. This is not done by the typescript compiler, but by a tool called rollup. So, it can help with optimizing code later, but it doesn't automatically do so.
As far as compilation overhead, bringing in the whole library might slow down the compiler a bit... but this isn't a very strong point except for massively complex libraries.
I, personally, prefer importing in specific modules because it makes the calling code a little cleaner since I don't need to use that global name to get to the specific name. rx.Observable vs Observable. A good example of this is the lodash library (rxjs is a bit more complex...)
Honestly, importing entire libraries like the line you have there: import 'rxjs/Rx' doesn't make sense to me. You should only import specific exported modules. Try removing it, seeing what errors you get, and then using the * as rx syntax instead.
As far as rxjs goes - it is a little wonky when you want to import specific operators like this question does - so the way to get specific operators is with: import 'rxjs/add/observable/from' - but that also requires a tinkering with your webpack set up as outlined in the referenced question's answer.
Let's see what the rxjs/Rx module exports:
export { Subject, AnonymousSubject } from './Subject';
export { Observable } from './Observable';
export { Operator } from './Operator';
export { Observer } from './Observer';
export { Subscription } from './Subscription';
export { Subscriber } from './Subscriber';
export { AsyncSubject } from './AsyncSubject';
export { ReplaySubject } from './ReplaySubject';
export { BehaviorSubject } from './BehaviorSubject';
...
import './add/observable/bindCallback';
import './add/observable/bindNodeCallback';
import './add/observable/combineLatest';
...
So it exports RxJs classes and also imports operators from the add folder. So as you can see it loads everything in the library. It doesn't export any global object though. So you need to use named export like this:
import * as Rx from 'rxjs/Rx'
to be able to use an exported class:
Rx.Observable.of(12, 3);
This emulates what you would have if you loaded the library using the bundle - a global Rx object:
<script src="rxjs/bundles/Rx.js">
If you want to use Observable without Rx global object, you need to import it separately:
import { Observable } from '#rxjs/Observable';
Observable.of(1);
Importing both
import { Observable } from '#rxjs/Observable';
import 'rxjs/Rx';
is not a good practice, but may be used if you don't want to import every operator separately.
Also see How to correctly import operators from the rxjs package.

In VSCode when exporting functions: "Individual declarations must be all exported or all local"

I recently upgraded to Visual Studio Code 0.5.0 and some new errors cropped up that weren't there before.
I have a bunch of functions that are declared locally and then exported. Since the upgrade, however, hovering over each of the local function names produces the error Individual declarations in merged declaration functionName must be all exported or all local.
This is an example local function that is exported.
var testParamsCreatorUpdater = function (lTestParams, creatorID){
lTestParams.creator = creatorID;
return lTestParams;
};
module.exports.testParamsCreatorUpdater = testParamsCreatorUpdater;
I realize I can change this to...
module.exports.testParamsCreatorUpdater = function (lTestParams, creatorID){
lTestParams.creator = creatorID;
return lTestParams;
};
And prepend module.exports. to every testParamsCreatorUpdater() call.
But why is the first snippet wrong? As I understand it, require() makes everything in the module.exports object available to whatever required it.
I had this issue in Webstorm , I Restarted it and it went away
I think at a JavaScript level it cannot differentiate between:
var testParamsCreatorUpdater = ...
and
module.exports.testParamsCreatorUpdater = ...
as the names are the same. I got the exact same error (leading me to this post) in TypeScript when I tried this:
import { AuditService } from '../services/audit.service';
import { Audit } from '../models/audit.model';
#Component({
selector: 'audit',
templateUrl: './audit.component.html',
})
export class Audit {
constructor(private auditService: AuditService) {
}
}
So TypeScript did not like that I imported a module called Audit and exported a class also called Audit.
You are exporting a variable in this file which is imported in the same file module (locally).
I think it's related to the feature of merged declaration for TypeScript ref. I have not done the detailed research for Typescript but it seems that it can include Javascript in the Typescript file.
I guess the way testParamsCreatorUpdater was declared in the Javascript was detected to be error by VSCode because it thinks the two declarations cannot be merged.
So DuckDuckGo got me here searching for the exact same error, but in 2022. I didn't find the exact reason so posting as an update and for completeness.
import { Something, SomethingElse } from './some/path';
import { ref } from 'vue';
// Many lines of code
function doTheStuff() {
// The declarations were previously just local variables ...
// const Something = ref<Something>();
// const SomethingElse = ref<SomethingElse>();
}
// ... but then I decided to export them and got the error
export const Something = ref<Something>();
export const SomethingElse = ref<SomethingElse>();
You simply can not import Something as a type and then export Something variable as a value of a kind (here a vue reference object). However, you can name a local variable the same name as the type, like I originally had. It is the import/export combination where things got broken. Solution for me was to locally rename the types:
import {
Something as SomethingType,
SomethingElse as SomethingElseType
} from './some/path';
import { ref } from 'vue';
// ...
// No naming conflict anymore
export const Something = ref<SomethingType>();
export const SomethingElse = ref<SomethingElseType>();

Categories

Resources