Export a class import an object - javascript

Here is my code (vanillaJS):
// app.js
import Block from './models/index';
console.log(typeof(Block));
let block = new Block();
// /models/block.js
export default class Block {
constructor() {
}
};
// /models/index.js
import Block from './block';
export default {
Block
};
The console.log in app.js tell me that Block is an object.
I want to import Block as a class not an object.
What did I do wrong?
Is it possible?
Good day.

Here
// /models/index.js
import Block from './block';
export default {
Block
};
you indeed export an object (with property Block). To export class just do:
// /models/index.js
import Block from './block';
export default Block
// or in one line: export { default } from './block'

As already explained, { Block } - the thing you exported - is an object indeed. However, I would recommend not to default-export anything from models/index.js as the solution.
I think you were looking for named exports here:
// /models/index.js
import Block from './block';
export { // <- this is not an object literal
Block // short for: `Block as Block`
};
// or in one line:
export { default as Block } from './block';
// app.js
import { Block } from './models/index';
// ^ ^
console.log(typeof(Block));
let block = new Block();

Related

Calling a function from a class to another generate an error in Next.js [duplicate]

I am trying to determine if there are any big differences between these two, other than being able to import with export default by just doing:
import myItem from 'myItem';
And using export const I can do:
import { myItem } from 'myItem';
Are there any differences and/or use cases other than this?
It's a named export vs a default export. export const is a named export that exports a const declaration or declarations.
To emphasize: what matters here is the export keyword as const is used to declare a const declaration or declarations. export may also be applied to other declarations such as class or function declarations.
Default Export (export default)
You can have one default export per file. When you import you have to specify a name and import like so:
import MyDefaultExport from "./MyFileWithADefaultExport";
You can give this any name you like.
Named Export (export)
With named exports, you can have multiple named exports per file. Then import the specific exports you want surrounded in braces:
// ex. importing multiple exports:
import { MyClass, MyOtherClass } from "./MyClass";
// ex. giving a named import a different name by using "as":
import { MyClass2 as MyClass2Alias } from "./MyClass2";
// use MyClass, MyOtherClass, and MyClass2Alias here
Or it's possible to use a default along with named imports in the same statement:
import MyDefaultExport, { MyClass, MyOtherClass} from "./MyClass";
Namespace Import
It's also possible to import everything from the file on an object:
import * as MyClasses from "./MyClass";
// use MyClasses.MyClass, MyClasses.MyOtherClass and MyClasses.default here
Notes
The syntax favours default exports as slightly more concise because their use case is more common (See the discussion here).
A default export is actually a named export with the name default so you are able to import it with a named import:
import { default as MyDefaultExport } from "./MyFileWithADefaultExport";
export default affects the syntax when importing the exported "thing", when allowing to import, whatever has been exported, by choosing the name in the import itself, no matter what was the name when it was exported, simply because it's marked as the "default".
A useful use case, which I like (and use), is allowing to export an anonymous function without explicitly having to name it, and only when that function is imported, it must be given a name:
Example:
Export 2 functions, one is default:
export function divide( x ){
return x / 2;
}
// only one 'default' function may be exported and the rest (above) must be named
export default function( x ){ // <---- declared as a default function
return x * x;
}
Import the above functions. Making up a name for the default one:
// The default function should be the first to import (and named whatever)
import square, {divide} from './module_1.js'; // I named the default "square"
console.log( square(2), divide(2) ); // 4, 1
When the {} syntax is used to import a function (or variable) it means that whatever is imported was already named when exported, so one must import it by the exact same name, or else the import wouldn't work.
Erroneous Examples:
The default function must be first to import
import {divide}, square from './module_1.js
divide_1 was not exported in module_1.js, thus nothing will be imported
import {divide_1} from './module_1.js
square was not exported in module_1.js, because {} tells the engine to explicitly search for named exports only.
import {square} from './module_1.js
More important difference is: export default exports value, while export const/export var/export let exports reference(or been called live binding). Try below code in nodejs(using version 13 or above to enable es module by default):
// a.mjs
export let x = 5;
// or
// let x = 5;
// export { x }
setInterval(() => {
x++;
}, 1000);
export default x;
// index.mjs
import y, { x } from './1.mjs';
setInterval(() => {
console.log(y, x);
}, 1000);
# install node 13 or above
node ./index.mjs
And we should get below output:
6 5
7 5
8 5
...
...
Why we need this difference
Most probably, export default is used for compatibility of commonjs module.exports.
How to achieve this with bundler(rollup, webpack)
For above code, we use rollup to bundle.
rollup ./index.mjs --dir build
And the build output:
// build/index.js
let x = 5;
// or
// let x = 5;
// export { x }
setInterval(() => {
x++;
}, 1000);
var y = x;
setInterval(() => {
console.log(y, x);
}, 1000);
Please pay attention to var y = x statement, which is the default.
webpack has similar build output. When large scale of modules are added to build, concatenateing text is not sustainable, and bundlers will use Object.defineProperty to achieve binding(or called harmony exports in webpack). Please find detail in below code:
main.js
...
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
...
// 1.js
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],[
/* 0 */,
/* 1 */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "x", function() { return x; });
let x = 5;
// or
// let x = 5;
// export { x }
setInterval(() => {
x++;
}, 1000);
/* harmony default export */ __webpack_exports__["default"] = (x);
/***/ })
]]);
Please find the difference behavior between /* harmony export (binding) */ and /* harmony default export */.
ES Module native implementation
es-modules-a-cartoon-deep-dive by Mozilla told why, what and how about es module.
Minor note: Please consider that when you import from a default export, the naming is completely independent. This actually has an impact on refactorings.
Let's say you have a class Foo like this with a corresponding import:
export default class Foo { }
// The name 'Foo' could be anything, since it's just an
// Identifier for the default export
import Foo from './Foo'
Now if you refactor your Foo class to be Bar and also rename the file, most IDEs will NOT touch your import. So you will end up with this:
export default class Bar { }
// The name 'Foo' could be anything, since it's just an
// Identifier for the default export.
import Foo from './Bar'
Especially in TypeScript, I really appreciate named exports and the more reliable refactoring. The difference is just the lack of the default keyword and the curly braces. This btw also prevents you from making a typo in your import since you have type checking now.
export class Foo { }
//'Foo' needs to be the class name. The import will be refactored
//in case of a rename!
import { Foo } from './Foo'
From the documentation:
Named exports are useful to export several values. During the import, one will be able to use the same name to refer to the corresponding value.
Concerning the default export, there is only a single default export per module. A default export can be a function, a class, an object or anything else. This value is to be considered as the "main" exported value since it will be the simplest to import.
When you put default, its called default export. You can only have one default export per file and you can import it in another file with any name you want. When you don't put default, its called named export, you have to import it in another file using the same name with curly braces inside it.

Creating a File that Imports & Immediately Exports Components Again

Not sure why this isn't working. I used to have
// file 1
import Box from '#/components/Box'
import Popup from '#/components/Popup'
const MDXComponents = {
Box,
Popup
}
// using MDXComponents somewhere in file 1
Now I want to outsource the MDXComponents object, as it is getting too big. So I created a new file:
// file 2
import Box from '#/components/Box'
import Popup from '#/components/Popup'
export default {
Box,
Popup
}
And then back in file 1 I do:
// file 1
import * as MDXComponents from './file2'
// using MDXComponents somewhere in file 1
It doesn't let me do this, but I am not sure why?
When you do this:
export default {
Box,
Popup
};
You set the default export to a new object that has 2 properties. You'd need to import like so:
import MDXComponents from './file2';
// And then destructure the object like any normal object.
// You can't do import {} in this case, you get the full object.
const { Box } = MDXComponents;
When you do this:
export {
Box,
Popup
};
You create two named exports that you can import like so:
// import all named exports
import * as MDXComponents from './file2';
// or just one individually
import { Box } from './file2';
For this use-case there's also a shortcut:
export { default as Box } from '#/components/Box';
export { default as Popup } from '#/components/Popup';
// If a module has named exports (not just a default export)
// and you want to export them all:
export * from 'some-module';
// Or just some:
export { someOtherThing } from '#/components/Box';
export { default as Popup, someOtherThing } from '#/components/Popup';

Does having two exports increase bundle size

If I have the following code
class x {
...
}
export CreateFragmentContainer(x,graphqlQuery)
Will the bundle size of my project if I do an another export of class x without the fragmentContainer such as the below?
export class x {
...
}
export CreateFragmentContainer(x,graphqlQuery)
Also, will the answer to this question change depending on the framework used?
The bundle size increases only if you import both at the same time, or when you have a default export + named exports, but just use the default export.
What i mean:
export default class {
...
}
export const a = '1';
----
Import Something from './myfile'
vs
export default class {
...
}
export const a = '1';
----
Import { a } from './myfile'
Method 2 has lower bundle size.
No, it does not depend on the framework, it is a "language feature".

how to use a function from another js file in reactjs?

i have a file something.js which has a function:
someFunction: function(arg1, arg2){
//code blocks
}
In my app.js file i want to call this function in the app class. I have imported the something.js file like this import { someFunction } from './something.js';. Now i am trying to use it in a function in the app class
var res = someFunction("abc", 2);
console.log(res);`
i am getting a error Uncaught TypeError: (0 , _something.someFunction) is not a function
Some help would be appreciated.
You need to write it like this:
something.js file -
module.exports = {
A: funtion(){
},
B: funtion(){
}
}
Then import it like this:
import {A} from 'something';
Or use it like this:
something.js file -
export A(){
}
export B(){
}
Then import it like this:
import {A} from 'something';
Read this article: https://danmartensen.svbtle.com/build-better-apps-with-es6-modules
In order to import something, you need to export it from the other module.
For example, you could export class YourComponent extends React.Component in something.js.
Then in the other file you can import { YourComponent } from './something'
You could, for example, in something.js do something like
const MyClass = {
methodName() { return true; }
}
export { MyClass as default } // no semi-colon
Then in the other file you could
import WhateverIWant from 'something';
WhateverIWant.methodName(); // will return true
Edit:
An in-depth explanation with lots of examples is available here.
You could either do: in your something.js file: module.exports = function(){}..
and in your app.js file:
const functionName = require('./path_to_your_file');
Or export somethingFunction = {} and in app.js:
import { somethingFunction } from './path_to_your_file'
Or last: export default somethingFunction = {} and in app.js:
import whateverNameYouChoose from './path_to_your_file'
Let me know if that did the trick! :)
In your something.js file, you can add export someFunction near the bottom of the file. This will then allow you to import that function using the import { someFunction } from './something.js'; you have earlier.

ES6 export default function

can I export more than one function per file ?
it seems like when I do that , the second function ovverides the first one ,
example :
in my index.js file :
export default function aFnt(){
console.log("function a");
}
export default function bFnt(){
console.log("function b");
}
then when I import it in my file :
import aFnt from "./index";
console.log("aFnt : ",aFnt);
the result of the console.log is bFnt
what exactly is the case here ? do I have to create a new file per function ? that is not very practical , any solution or workaround ?
madox2's answer totally works if you want to import named functions.
If you still want to import the default, there's another technique:
function a() {}
function b() {}
export default { a, b }
and when you import:
import myObject from './index.js';
myObject.a(); // function a
myObject.b(); // function b
I hope this helps!
You can use named export instead of default:
export function aFnt(){
console.log("function a");
}
export function bFnt(){
console.log("function b");
}
and import it like:
import {aFnt, bFnt} from "./index";
there are couple of ways to export and import objects/functions
export function first() {}
export function second() {}
in other file
import { first, second} from './somepath/somefile/';
if you want to use default, in general if there is only one export in a file it should be a default export. but if you for some reasons want two functions as default then you have to club them as a object and export that object as default
function first() {}
function second() {}
const funcs= {"first":first,"second":second}
export default funcs;
in other file
import funcs from './somepath/somefile/';
funcs.first();funs.second();
this should be it.

Categories