ES6 and importing issue with multiple exports - javascript

I'm trying to get an index.js working with create-index but I'm having issues getting everything to work.
I have the following:
/modules/utils.js
export function func1(){ ... }
export function func2(){ ... }
export function func3(){ ... }
/modules/index.js [auto created]
export { default as utils } from './utils.js';
/main.js
import utils from './modules';
utils.func1();
But I can't get access to just the utils no matter what i do. I've tried a fair few ways of importing from ./models but the best i can get is import * as modules from './modules' but then i can't actually use anything.
Not sure if I'm doing something stupid or if my use of an index.js is wrong in this situation.

Your utils.js module has no default export, therefor re-exporting it from the module index won't help anything.
You can use either
// main.js
import * as utils from './modules/utils';
utils.func1();
or
// modules/index.js
export * from './utils.js';
// main.js
import * as modules from './modules';
modules.func1();
or
// modules/index.js
import * as utils from './utils.js';
export { utils }
// export * as utils from './utils.js' is proposed and supported by transpilers
// main.js
import { utils } from './modules';
utils.func1();
(you could also default-export the utils from index.js, but that wouldn't really make sense)
If you want to have a utils object with the functions exported from utils.js as methods, then I would recommend either the first or the last approach. Of course if there is only a single file in the modules folder it might also be sensible to drop that and just put your utils module right in the root folder.

Related

Globally importing ReactJS components in all files

In React when you wanna import components from other files we use:
import ComponentName from 'somePlace';
That works fine, but I wanna know if there is a way to import the content of a file instead of the exports. I wanna put all import statements for components in a single file (e.g. imports.js) and have a statement like:
import './import.js' to all documents;
so all my components are automatically imported everywhere.
Is there a way to do that?
Globally import modules? Not really, no. And neither should you need to.
A hacky "solution" would be assigning all imports to the global context (e.g. window in the browser) so it's accessible that way. That's possible, but definitely not recommended. It'll also prevent your bundler (most likely Webpack) from optimizing a lot of code.
Apart from the technical aspect, there are other reasons not to do so. If you specify the imports in each file, you know exactly what imports that file needs and under what variables it is imported as for that file.
If you still want to simplify importing the same components over and over again, you can have this setup:
imports.js
// For default exports
import ComponentA from 'wherever';
export { ComponentA };
// For regular exports
//import { ComponentB } from 'wherever';
export { ComponentB } from 'wherever';
// For whole modules
//import * as wherever from 'wherever';
export * as wherever from 'wherever';
someOtherFile.js
// Either import as a namespace
import * as Imports from './imports';
console.log([
Imports.ComponentA,
Imports.ComponentB,
Imports.wherever.someFieldFromTheWhereverModule,
]);
// Or partial import
import { ComponentA, ComponentB } from './imports';

How to properly export/import modules for library usage in javascript

I want to write a javascript library with two files:
snabbpixi.js
export function init() {
}
pixiapi.js
export function createElement() {
}
I want to use this library like this:
import { init } from 'snabbpixi';
import { createElement } from 'snabbpixi/pixiapi';
If I don't do anything and set the package.json for library as:
{
"main": "src/snabbpixi.js"
}
second import doesn't work (import { createElement } from 'snabbpixi/pixiap')
If I compile this library and export as umd format using webpack it also doesn't work.
How can I configure my library so I can import like this:
import { createElement } from 'snabbpixi/pixiap'
I normally do this sort of thing in TypeScript rather than straight JavaScript, but hopefully this works in basically the same way...
Try creating a new file (typically named index.js), with contents like this:
export * from './snabbpixi'; // Adjust paths as needed for your particular case.
export * from './snabbpixi/pixiapi';
Then make index.js your main.
The import you would use would then be flattened-out, however, looking more like:
import { init, createElement } from 'snabbpixi';
When you are using import { Something } from 'somewhere' you are calling on a named export from a given file or directory.
If the two files are in different directories then you can add an index.js file to each directory and then use export { default as function } from './file'
To do this you would have to export the default file from pixiapi and snabbpixi.
If you have both files importing into your index.js then you will still want to export them as defaults. But then you would do the following..
import file1 from './file1'
import file2 from './file2'
export default {
file1,
file2,
}
This will allow you to use the named imports as well and keep them in the same directory

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';

How to export default modules in index.js barrels

I'm trying to export default modules using index.js barrels but can't seem to get it to work. It works fine with named exports but not default exports.
Simplified Project Structure
/hellos
/components
Hello.js
Hellos.js
index.js
index.js
App.js
/hellos/component/Hellos.js
...
export default Hellos
/hellos/component/index.js
export * from './Hello';
export * from './Hellos';
/hellos/index.js
export * from './components'
export * from './actions'
export * from './constants'
export * from './reducers'
App.js
import Hellos from './hellos'
console.log(Hellos) // <- undefined
The Hellos module imported just above is always undefined.
I can get it to work using either named exports or a direct import in App.js i.e. import Hellos from './hellos/component/Hellos' but I consider this bad practice and only wish to use import Hellos from '/hellos'.
I suspect the problem is with the index.js barrels but I can't work it out. Please help.
Use the following line:
export { default as MyModule } from 'src/MyModule'
Hope it suits your needs,
cheers
For those using babel
Use babel-plugin-transform-export-extensions plugin like this in your .babelrc:
"plugins": [
"babel-plugin-transform-export-extensions",
"transform-es2015-modules-commonjs"
]
And then install the plugin like this:
npm install --save-dev babel-plugin-transform-export-extensions
npm install --save-dev babel-plugin-transform-es2015-modules-commonjs
Then u can use export in index.js simply like this:
export simple from './simple';
export restClient from './jsonServer';
export * from './types';
For those using earlier babel versions, simply use the commonjs module.

ES6 import "module" don't give acces to function of "module"

I am trying to use ES6 imorts with babel and Node.js
import "./utils.js";
log("something"); //throw an error : log is not defined
My utils.js look like this :
function log(... params){
console.log(... params);
}
log("module utils executed");
//Is executed and display "module utils executed" in the console.
I have also tryed to use export function log(... params) and export default log(... params) but it doesn't works.
So I don't understand how this is suppose to works...
EDIT:
I know that an other way to import is to do import utils from "./utils.js"
But it's not what I want. I want to be able to use log() without prefixing it with the module variable name. Like in this blog post
there Different ES6 import and Node.js require Question Describe The Difference
In case you will use Node.js require:
your utils.js File will be
function log(params) {
console.log(params);
}
module.exports = {
log
};
The other File will import your Utils Module will be
var utils = require('./utils');
utils.log("test");
In case you will use ES6 Modules:
your utils.js File will be
var log = function (params) {
console.log(params);
}
var utils = {
log: log
}
export default utils;
The other File will import your Utils Module will be
import utils from 'utils';
utils.log("test");
UPDATE
According to your Comment, Yes you can do this But using ES6 Module
your utils.js File will be
function log(params) {
console.log(params);
}
function anotherLog(params) {
console.log(params);
}
export { log, anotherLog }
The other File will import your Utils Module will be
import { log } from 'utils';
log("test");
No, there is no way to import all exported members of a module into the current namespace. Importing a module for side effects (i.e. import 'utils') does nothing with the members of utils.
The closest you can get is something like this:
utils.js
export function log(...params) { ... }
export function foo(a) { ... }
main.js
import * as u from './utils';
u.log(1, 2, 3);
u.foo(4);
or
import { log, foo } from './utils';
log(1, 2, 3);
foo(4);
One of the design goals of the ES6 module spec is a static module structure, which allows resolution of imports at compile time (before executing anything). Allowing blanket imports would make static analysis more difficult.
EDIT (do not do this!)
As #Bergi pointed out in the comments, you can add functions to the global namespace as follows:
utils.js
function log(...params) { ... }
global.log = log;
main.js
import './utils'; // import for side effects, add properties to the global object
log(1, 2, 3); // the global object is in the scope chain, so this is resolved
However this is a bad idea. Global variables are slow to resolve and in general break the modularity you try to achieve by using modules in the first place.

Categories

Resources