Migrating es5 to es6 export default - javascript

I am trying to migrate a code from es5 to es6, I am quite new in both, if someone could help me, I will be very thankful.
es5 version:
lib.js
module.exports = {
foo1: function () {
this.foo2() {
...
}
},
foo2: function () {
...
}
}
main.js
const Lib = require("./lib");
Lib.foo1( { ... });
es6 version - I am trying:
lib.ts
export default {
foo1() {
this.foo2(() => {
...
});
},
foo2(){ ... }
}
main.ts
import * as Lib from "./lib";
Lib.foo1({ ... })
The problem is in my main.ts foo1 can not be resolved.
Any idea or recommendation?
Thank!

It should be just
import Lib from "./lib";
Otherwise, if you use * as notation you could access default export with Lib.default, but this is unnecessary.

I don't understand the following part of your code:
foo1: function () {
this.foo2() {
...
}
}
That seems invalid.
Anyway, do not introduce your own pseudo-module like structure. It's not necessary. lib.js is already a module.
lib.js
export function foo1() {
foo2();
}
export function foo2() { ... }
main.js
import {foo, foo2} from './lib';

Related

Why this es6-module export is not working/recognized?

I'm getting mad with module import/export syntax...
Say on a file I want to import a module like this:
import { AccordionMenu } from '../node_modules/lr-js-modules/accordion-menu';
Now, how should I export from accordion-menu? My current code is an old school js class like this:
AccordionMenu = function(options){
[...]
}
AccordionMenu.prototype = { ... }
Then I was exporting like this:
export { AccordionMenu as default };
It doesn't work. Compiler says
export 'AccordionMenu' (imported as 'AccordionMenu') was not found in '../node_modules/lr-js-modules/accordion-menu' (possible exports: default)
I then tried several variants, but none worked to me. From mdn docs, as far as I can tell, all teh variants should work, but it's evident that I'm doing something wrong.
Can you help please?
The error message is quite clear: you exported default but your import tries to access an export AccordionMenu.
You should use either
export function AccordionMenu(options) { … }
// same as:
// function AccordionMenu(options) { … }
// export { AccordionMenu as AccordionMenu }
AccordionMenu.prototype = { … };
with
import { AccordionMenu } from '../node_modules/lr-js-modules/accordion-menu';
// same as:
// import { AccordionMenu as AccordionMenu } from '../node_modules/lr-js-modules/accordion-menu';
or, if that function is the only (or main) export of that module, use a default export
export default function AccordionMenu(options) { … }
// same as:
// function AccordionMenu(options) { … }
// export { AccordionMenu as default }
AccordionMenu.prototype = { … };
with
import AccordionMenu from '../node_modules/lr-js-modules/accordion-menu';
// same as:
// import { default as AccordionMenu } from '../node_modules/lr-js-modules/accordion-menu';
but the mix doesn't work.

share a js-class between .vue files

Back in my day we had this crazy thing called include or import or whatever. It meant that you wrote some code in one file and then reused it in different files. So you would create a class in file x, include this file in another file y and instantiate an object from this. Basically this means, that you were able to call a function form file y even though it is written in file x.
How can something like this be done in vue.js? I understand that the new hip way to do it is called "components api". Online I only found really convoluted examples that had some coupling with the dom, something I don't need.
Or should I use mixins? Mixins seem to be working at least, but they have a scope problem.
Here is the file I want to share (x.vue):
<script>
export default
{
data ()
{
return {
a: 'test'
}
}
,mounted ()
{
}
,methods:
{
test ()
{
console.log( "test : " + this.a );
}
}
}
</script>
The y.vue:
<script>
import x from './x.vue'
export default {
name:"whatever"
,components:
{
x
}
,mounted()
{
x.a = "it is working";
x.test();
}
}
</script>
The web-browser tells me that a is not a function. does anyone know where the mistake is? Or should i just create a js class and try to import that?
Thanks for any help.
I believe you're looking for mixins:
https://v2.vuejs.org/v2/guide/mixins.html
They Allow you to share functions, data, hooks and all other from another file.
This would be an approach in your case.
mixins.js:
export default {
methods: {
sayHello () {
console.log( "test : " + this.a);
}
}
};
component.vue:
<script>
import mixins from "#/path/to/mixins/mixins";
export default {
name: "whatever",
mixins: [mixins],
data ()
{
return {
a: 'HELLO'
}
},
created() {
this.sayHello();
}
}
</script>
For further information: Mixins
EDIT: Looks like there is something that matches your needs!
mixins.js:
export default {
name: 'Mixin',
methods: {
sayHello() {
console.log("Hello")
}
}
}
component.js:
export default {
name: 'whatever',
mixins: [Mixin],
created() {
this.$super(Mixin).sayHello();
}
}
EDIT2: As you requested, an simple example to pass arguments.
mixins.js:
export default {
methods: {
sayHello(foo, bar) {
console.log(foo + bar)
}
}
}
component.js:
export default {
name: 'whatever',
mixins: [Mixin],
data () {
return {
baz: 'Say'
}
},
created() {
this.sayHello(this.baz, " Hello");
}
}
Mixins are not useful in this case as there cannot be more than one instance of a mixin. It is like copy and pastes the code from the mixin into the other file.
Sharing code between Vue components can be done by many savers with standard js classes. All that is needed is that the class is declared with export default class.

How can I export all functions from a file in JS?

I'm creating a unit converter, and I want to put all of the conversion functions into their own file. Using ES6 export, is there any way to export all of the functions in the file with their default names using only one line? For example:
export default all;
The functions are all just in the file, not within an object.
No, there's no wildcard export (except when you're re-exporting everything from another module, but that's not what you're asking about).
Simply put export in front of each function declaration you want exported, e.g.
export function foo() {
// ...
}
export function bar() {
// ...
}
...or of course, if you're using function expressions:
export var foo = function() {
// ...
};
export let bar = () => {
// ...
};
export const baz = value => {
// ...
};
I think there are a lot of solutions to this. And as has been answered, there's no wildcard export. But, you can 'wildcard' the import. So, I much prefer the one putting export before each of the functions you want to expose from the file:
//myfile.js
export function fn1() {...}
export function fn2() {...}
and then import it like so:
import * as MyFn from './myfile.js'
Afterwards you could use it like so:
MyFn.fn1();
MyFn.fn2();
You can also use module.exports as follows:
function myFunction(arg) {
console.debug(arg);
}
function otherFunction(arg) {
console.error(arg);
}
module.exports = {
myFunction: myFunction,
otherFunction: otherFunction,
};
Then you can import it:
import {myFunction, otherFunction} from "./Functions.js";
In my use case, I do have three reusable functions in one file.
utils/reusables.js
export const a = () => {}
export const b = () => {}
export const c = () => {}
In order to point the root folder instead of individual file names, I created a file called index.js which will comprise of all the functions that are listed in individual files.
utils/index.js
export * from './reusables'
Now, when I want to use my a function, I will have to simply import it like this
import { a } from '../utils'
Rather than calling it from its individual files
import { a } from '../utils/reusables'
You could also export them at the bottom of your script.
function cube(x) {
return x * x * x;
}
const foo = Math.PI + Math.SQRT2;
var graph = {
options: {
color:'white',
thickness:'2px'
},
draw: function() {
console.log('From graph draw function');
}
}
export { cube, foo, graph };
You can also aggregate submodules together in a parent module so that they are available to import from that module.
// In parentModule.js
export { myFunction, myVariable } from 'childModule1.js';
export { myClass } from 'childModule2.js';
// In top-level module
import { myFunction, myVariable, myClass } from 'parentModule.js'
For Node.js environment, what I did to export functions was this.
UserController.js
module.exports = {
signUp: () => {
return "user"
},
login: () => {
return "login"
}
}
UserRouter.js
const UserController = require('./UserController')
then login and signUp functions could be used inside UserRouter as UserController.signUp() and UserController.login()
I think there's a missing common solution, which is exporting in index.js file:
myModule/myFunctions.js
export const foo = () => { ... }
export const bar = () => { ... }
then in myModule/index.js
export * from "./myFunctions.js";
This way you can simply import and use it with:
import { foo, bar } from "myModule";
foo();
bar();
functions.js
function alpha(msj) {
console.log('In alpha: ' + msj);
}
function beta(msj) {
console.log('In beta: ' + msj);
}
module.exports = {
alpha,
beta
};
main.js
const functions = require('./functions');
functions.alpha('Hi');
functions.beta('Hello');
Run
node main.js
Output
In alpha: Hi
In beta: Hello
In case anyone still needs an answer to this in modern JavaScript:
const hello = () => "hello there"
const bye = () => "bye bye"
export default { hello, bye }
What I like to do is to export all functions within an object:
//File.js
export default {
testFunction1: function testFunction1(){
console.log("Hello World")
},
//a little bit cleaner
testFunction2: () => {
console.log("Nothing here")
}
}
Now you can access the functions with calling the key value of the object:
//differentFile.js
import file from 'File.js'
file.testFunction1()
//Hello World
file.testFunction2()
//Nothing here

Jest: Mock ES6 Module with both default and named export

I have an ES6 module with both a default and a named export:
/** /src/dependency.js **/
export function utilityFunction() { return false; }
export default function mainFunction() { return 'foo'; }
Its being used by a second ES6 module:
/** /src/myModule.js **/
import mainFunction, { utilityFunction } from './dependency';
// EDIT: Fixed syntax error in code sample
// export default myModule() {
export default function myModule() {
if (!utilityFunction()) return 2;
return mainFunction();
}
I'm trying to write a unit test for myModule.js using Jest. But when I try to mock both the named and the default import, Jest appears to only mock the named import. It continues to use the actual implementation of the default import, and doesn't allow me to mock it, even after I call .mockImplementation(). Here's the code I'm trying to use:
/**
* Trying to mock both named and default import.
* THIS DOESN'T WORK.
*/
/** /tests/myModule.test.js **/
import mainFunction, { utilityFunction } from '../src/dependency';
import myModule from '../src/myModule';
jest.mock('../src/dependency');
mainFunction.mockImplementation(() => 1);
utilityFunction.mockImplementation(() => true);
describe('myModule', () => {
it('should return the return value of mainFunction when the result of utilityFunction is true', () => {
expect(myModule()).toEqual(1); // FAILS - actual result is 'foo'
});
});
This behavior seems really strange to me, because when mocking JUST default imports or JUST named imports, this API works fine. For example, in the case where myModule.js only imports a default import, this is pretty easily done:
/**
* Trying to mock just the default import.
* THIS WORKS.
*/
/** /src/myModule.js **/
import mainFunction from './dependency';
// EDIT: Fixed syntax error in code sample
// export default myModule() {
export default function myModule() {
return mainFunction();
}
/** /tests/myModule.test.js **/
// If only mainFunction is used by myModule.js
import mainFunction from '../src/dependency';
import myModule from '../src/myModule';
jest.mock('../src/dependency');
mainFunction.mockImplementation(() => 1);
describe('myModule', () => {
it('should return the return value of mainFunction', () => {
expect(myModule()).toEqual(1); // Passes
});
});
In the case where only the named 'utilityFunction' export is used, its also pretty easy to mock the import:
/**
* Trying to mock both named and default import.
* THIS WORKS.
*/
/** /src/myModule.js **/
import { utililtyFunction } from './dependency';
// EDIT: Fixed syntax error in code sample
// export default myModule()
export default function myModule() {
return utilityFunction();
}
/** /tests/myModule.test.js **/
// If only utilityFunction is used by myModule.js
import { utilityFunction } from '../src/dependency';
import myModule from '../src/myModule';
jest.mock('../src/dependency');
utilityFunction.mockImplementation(() => 'bar');
describe('myModule', () => {
it('should return the return value of utilityFunction', () => {
expect(myModule()).toEqual('bar'); // Passes
});
});
Is it possible to mock both the named and default import using Jest? Is there a different syntax that I can use to achieve the result I want, where I import both named and default values from a module and am able to mock them both?
The other solution didn't work for me. This is how I did:
jest.mock('../src/dependency', () => ({
__esModule: true,
utilityFunction: 'utilityFunction',
default: 'mainFunction'
}));
Another way to do it:
jest.unmock('../src/dependency');
const myModule = require('../src/dependency');
myModule.utilityFunction = 'your mock'
You have a syntax error ... the function keyword is omitted from the default export in myModule.js. Should look like this:
import mainFunction, { utilityFunction } from './dependency';
export default function myModule() {
if (!utilityFunction()) return 2;
return mainFunction();
}
I'm not sure how you got the test to run otherwise, but I just tried this out locally and it passed.

es2015 re-export module and override single export function of the re-exported module

I want to re-export a whole module and override only a specific function of the re-exported module. But it seems exporting the override function doesn't get processed when the same function is already re-rexported.
(http://www.ecma-international.org/ecma-262/6.0/#sec-module-semantics-static-semantics-early-errors, 'It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.')
The motivation behind my approach is to minimize explicit re-exporting a very big or long module, if I only want to override a specific function or method in the re-exported module.
Is there any way to implement my approach in es6/es2015?
My code so far:
module-a.js
export class MyFirstStandardClass {
sendMeMessages() {
return `hello, I'm a standard implementation`;
}
}
export function talkToMe() {
return `standard talking: how are you doing?`;
}
module-b.js
import * as StandardModule from 'module-a';
export function talkToMe(condition = true) {
if (condition) {
return `project conditional talking: ${StandardModule.talkToMe()}`;
}
return `project without a condition!`;
}
export * from 'module-a';
module-c.js
import * as MyModule from 'module-b';
import React, { Component } from 'react';
export default class App extends Component {
componentWillMount() {
console.log(MyModule);
this.myFirstStandardInstance = new MyModule.MyFirstStandardClass();
}
render() {
return (
<div>
<label>
Class
</label>
<div>
{ this.myFirstStandardInstance.sendMeMessages() }
</div>
<label>
Function
</label>
<div>
{ MyModule.talkToMe(true) } // returns 'standard talking: how are you doing?'; expected 'project conditional talking: standard talking: how are you doing?'
</div>
</div>
);
}
}
It seems my first solution should work. According to the ECMAScript spec local exports should have priority. (http://www.ecma-international.org/ecma-262/6.0/#sec-getexportednames)
It's an issue in the Babel transpiler. More info: https://github.com/systemjs/systemjs/issues/1031#issuecomment-171262430
Issue in Babel: https://phabricator.babeljs.io/T6967
You can select which modules from module-a to export on one line. So in your module-b.js you can do:
// export all modules excluding `talkToMe`
export { MyFirstStandardClass, someOtherModule } from 'module-a';
export function talkToMe(condition = true) {
// ...
}
Or you can export default object and choose what to exclude/override with Object.assign():
import * as StandardModule from 'module-a';
const overridenExports = {
talkToMe: function(condition = true) {
// ...
}
}
const myModule = Object.assign({}, StandardModule, overridenExports);
export default myModule;
and import default like:
import MyModule from 'module-b';

Categories

Resources