How to export default modules in index.js barrels - javascript

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.

Related

React export {...} from shorhand usage

When using
export { module } from 'path'
This doesn't work specially with default exports
but when importing then exporting no problem
in index.js
import module from path
export {module}
I'm i missing something
If you want to re-export a default export as a named one, you can use the following syntax
export {default as module} from './path
Alternatively, if you want to export all named export in a single export, you can use
export {* as module} from './path'
Simply because this syntax does not deal with default exports only named ones

ES6 and importing issue with multiple exports

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.

Auto-completion in Webstorm for my custom npm module (ES6/Babel)

When I use material-ui package I get nice auto-completion in Webstorm (ctrl+space):
I thought it might have something to do with the fact the package includes an index.es.js file:
import _AppBar from './AppBar';
export { _AppBar as AppBar };
import _AutoComplete from './AutoComplete';
export { _AutoComplete as AutoComplete };
import _Avatar from './Avatar';
export { _Avatar as Avatar };
import _Badge from './Badge';
export { _Badge as Badge };
import _BottomNavigation from './BottomNavigation';
...
So I generated my own index.es.js in my custom npm module and put it next to the transpiled index.js:
import {ActionTypes as _ActionTypesElements} from './reducers/elements/elements';
export { _ActionTypesElements as ActionTypes };
import {ActionTypes as _ActionTypesAppState} from './reducers/appState/appState';
export { _ActionTypesAppState as ActionTypesAppState };
import _appStateActions from './reducers/appState/appState_actions';
export { _appStateActions as appStateActions };
...
And yet I get no auto-complete:
Any idea why?
Found the answer:
Had to add a jsnext:main field to the package.json of the npm module:
package.json:
...
"module": "./index.js",
"jsnext:main": "./index.es.js",
...
Webstorm recognizes the package's inner exports.
In WebStorm 2019.3, here are the steps I follow to force Code Completion (including auto-import) to work for a custom, self-published NPM package:
Ensure that the project, itself, has a package.json file at the root of the project, and that package.json includes the desire package in the "dependency" object. For example:
{
"name": "testproject",
"version": "1.0.0",
"dependencies": {
"#yourname/yourpackage": "latest"
}
}
In WebStorm, select File > Invalidate Caches / Restart...
To enable auto-import for package contents, ensure that the JavaScript file in which the package is being used has AT LEAST ONE export statement. For example, in the following code, an export is present, so Code Completion auto-imports the package function isNil():
export function init () {
isNil
}
By comparison, the following code does not contain an export statement, so isNil() is not automatically imported:
function init () {
isNil
}
For me, all three of the preceding steps are necessary for Code Completion to work for my own NPM packages in WebStorm.

Babel/webpack dependencies

I have a private library I've converted to using es6 and webpack. How do I include this library in a way that I can import the entire source tree?
The library looks like this:
portedlibrary
src/dir1/Class1.js
src/dir1/Class2.js
And my application looks like this:
Application
src/app.js
src/app2.js
node_modules/portedlib/src/dir1/Class1.js
node_modules/portedlib/src/dir1/Class2.js
For internal imports, I can use relative pathing: import {app2} from './app2
For library imports, I import a single file: import moment from 'moment'
How do I import individual classes from portedlibrary?
When I try to import a class via import {Class1} from 'portedlib' I get the following error:
Module not found: Error: Can't resolve 'portedlibrary' in ...
Re-export each of the default exports as a named export in another file (e.g. index.js so you can reference the lib by its name):
// node_modules/portedlib/index.js
export { default as Class1 } from './src/dir1/Class1'
export { default as Class2 } from './src/dir1/Class2'
And then import them:
import { Class1, Class2 } from 'portedlib'

Re-export default in ES 6 modules

In ES6, is it possible to shorten the following code. I have an App.js file and an index.js.
index.js
import App from './App';
export default App;
Something like this
index.js
export default App from './App.js'
If you use proposal-export-default-from Babel plugin (which is a part of stage-1 preset), you'll be able to re-export default using the following code:
export default from "./App.js"
For more information see the ECMAScript proposal.
Another way (without this plugin) is:
export { default as App } from "./App.js"
The above is a very common practice when separate files, each with its own export, have all something in common, for example, utils, so if, for example, one would want to import 3 utility functions, instead of having to write multiple imports:
import util_a from 'utils/util_a'
import util_b from 'utils/util_b'
import util_c from 'utils/util_c'
One could import any of the utilities in a single-line:
import { util_a, util_b , util_c } from 'utils'
By creating an index.js file in the /utils folder and import all the defaults of all the utilities there and re-export, so the index file will serve as the "gateway" for all imports related to that folder.
This is a bit of repetition from the previous answers, but to clarify the difference in two options:
1. Default export
(This appears to be what OP wants)
// index.ts
export { default } from './App'
Then, in a different file:
import App from './index'
2. Named export
export { default as App } from './App'
Then, in another file:
import { App } from './index'
Bonus: named → default export
If ./App uses a named export, but you want to re-export it as a default export, you can do that too:
export { App as default } from './App'
Then, in another file:
import App from './index'
These will work with react as vsync's answer states.
Bonus #2: export everything
Say you have a file that exports multiple items:
// App.ts
export const first = 1
export const second = 2
const final = 3
export default final
You can then re-export them directly:
// index.ts
export * from './App'
You can now import these easily:
import final, { first, second } from './index'
Bonus #3: * import
You can import all variables exported by another file as a single variable.
// index.ts
import * as App from './App'
App.first === 1 // true
import App from './App';
export default App;
⬇
Babel 7 (with #babel/preset-react) can transform the below:
export { default as App } from './App.js';
Related discussions:
TC39 proposal:
https://github.com/tc39/proposal-export-default-from#common-concerns
The only working solution is :
import App from './App';
export default App;
If you export your module like this
export { default as App } from './App.js';
Then it's not a default export anymore and you'll get an error if you try to import it as a default import.
import App from './App';
export default (App);
This work for me in default 'create-react-app' application

Categories

Resources