I have the following folder structure
I want to import both MessageList.tsx and MessageSent.tsx inside my Chat.tsx
// Chat.tsx
import React from 'react'
import {MessageList, MessageSent} from "./components/"
type Props = {}
const Chat= (props: Props) =\> {
return (
<div\>Chat</div>
)
}
export default Chat`
// MessageSent.tsx
import React from 'react'
type Props = {}
const MessageList = (props: Props) => {
return (
<div>MessageList</div>
)
}
export default MessageList
MessageList.tsx is similar to MessageSent,tsx, only the name of the components is different
However, when I try to do the import of these two components {MessageList, MessageSent} I get the following error:
** Cannot find module './components/' or its corresponding type declarations.**
Why is that?
Tried different paths besides "./components/", even with full path.
You can either import the components one by one
import MessageSent from "./components/MessageSent"
import MessageList from "./components/MessageList"
or create an index directory file (index.ts)
import MessageSent from './MessageSent'
import MessageList from './MessageList'
export { MessageSent, MessageList }
To be able to import from components you need index.ts file in components folder.
// index.ts
export * from './MessageList';
export * from './MessageSent';
Add a new file named index.ts inside your components folder
Then write this in the index.ts
export * from './MessageList.tsx';
export * from './MessageSent.tsx';
Given the following file structure:
myFiles
├── index.js
├── getTrue.js
└── dependentGetFalse.js
And the following code
// index.js
export { getTrue } from './getTrue'
export { dependentGetFalse } from './dependentGetFalse'
// getTrue.js
export const getTrue = () => true
// dependentGetFalse.js
import { getTrue } from '.'
export const dependentGetFalse = () => !getTrue()
Where there's (what I assume to be) a circular import between dependentGetFalse.js and index.js.
What problems will arise from this? Or is it ok to have?
If your codes run flawless and you are comfortable with them, It is ok to have this circular situation
It's best to avoid using '.' imports.
Try this:
// dependentGetFalse.js
import { getTrue } from './getTrue'
export const dependentGetFalse = () => !getTrue()
index.js is useful when you try to import something from outside of this folder.
I have a shared folder that I expose as an npm module.
inside that share folder I have a components folder with index.js that exports them as default:
export { default as AqMegaMenu } from "./megaMenu/AqMegaMenu.vue";
export { default as AqDetailsCard } from "./AqDetailsCard.vue";
export { default as AqDoughnutChart } from "./charts/AqDoughnutChart.vue";
...
My entry file for the library is main.js and i'd like to expose my entire components through it, so I import them in other projects like this:
import {Comp1, Comp2} from "#my/shared"
Currently I export them one by one in main.js:
export { default as AqDetailsCard } from "./components/AqDetailsCard.vue";
...
But i was wondering if there is a way to export the entire components directory using it's index.js
and still be able to import it in other projects like i showed above.
You may try something like this
import camelCase from 'lodash/camelCase'
const requireModule = require.context('./components', true, /\.vue$/)
const modules = {}
requireModule.keys().forEach(filename =>
{
const moduleName = camelCase(fileName.match(/([^\\\/]+)\.vue$/)[1]);
modules[moduleName] = requireModule(fileName)
})
export default modules
With ES6, I can import several exports from a file like this:
import {ThingA, ThingB, ThingC} from 'lib/things';
However, I like the organization of having one module per file. I end up with imports like this:
import ThingA from 'lib/things/ThingA';
import ThingB from 'lib/things/ThingB';
import ThingC from 'lib/things/ThingC';
I would love to be able to do this:
import {ThingA, ThingB, ThingC} from 'lib/things/*';
or something similar, with the understood convention that each file contains one default export, and each module is named the same as its file.
Is this possible?
I don't think this is possible, but afaik the resolution of module names is up to module loaders so there might a loader implementation that does support this.
Until then, you could use an intermediate "module file" at lib/things/index.js that just contains
export * from 'ThingA';
export * from 'ThingB';
export * from 'ThingC';
and it would allow you to do
import {ThingA, ThingB, ThingC} from 'lib/things';
Just a variation on the theme already provided in the answer, but how about this:
In a Thing,
export default function ThingA () {}
In things/index.js,
export {default as ThingA} from './ThingA'
export {default as ThingB} from './ThingB'
export {default as ThingC} from './ThingC'
Then to consume all the things elsewhere,
import * as things from './things'
things.ThingA()
Or to consume just some of things,
import {ThingA,ThingB} from './things'
The current answers suggest a workaround but it's bugged me why this doesn't exist, so I've created a babel plugin which does this.
Install it using:
npm i --save-dev babel-plugin-wildcard
then add it to your .babelrc with:
{
"plugins": ["wildcard"]
}
see the repo for detailed install info
This allows you to do this:
import * as Things from './lib/things';
// Do whatever you want with these :D
Things.ThingA;
Things.ThingB;
Things.ThingC;
again, the repo contains further information on what exactly it does, but doing it this way avoids creating index.js files and also happens at compile-time to avoid doing readdirs at runtime.
Also with a newer version you can do exactly like your example:
import { ThingsA, ThingsB, ThingsC } from './lib/things/*';
works the same as the above.
You now can use async import():
import fs = require('fs');
and then:
fs.readdir('./someDir', (err, files) => {
files.forEach(file => {
const module = import('./' + file).then(m =>
m.callSomeMethod();
);
// or const module = await import('file')
});
});
Great gugly muglys! This was harder than it needed to be.
Export one flat default
This is a great opportunity to use spread (... in { ...Matters, ...Contacts } below:
// imports/collections/Matters.js
export default { // default export
hello: 'World',
something: 'important',
};
// imports/collections/Contacts.js
export default { // default export
hello: 'Moon',
email: 'hello#example.com',
};
// imports/collections/index.js
import Matters from './Matters'; // import default export as var 'Matters'
import Contacts from './Contacts';
export default { // default export
...Matters, // spread Matters, overwriting previous properties
...Contacts, // spread Contacts, overwriting previosu properties
};
// imports/test.js
import collections from './collections'; // import default export as 'collections'
console.log(collections);
Then, to run babel compiled code from the command line (from project root /):
$ npm install --save-dev #babel/core #babel/cli #babel/preset-env #babel/node
(trimmed)
$ npx babel-node --presets #babel/preset-env imports/test.js
{ hello: 'Moon',
something: 'important',
email: 'hello#example.com' }
Export one tree-like default
If you'd prefer to not overwrite properties, change:
// imports/collections/index.js
import Matters from './Matters'; // import default as 'Matters'
import Contacts from './Contacts';
export default { // export default
Matters,
Contacts,
};
And the output will be:
$ npx babel-node --presets #babel/preset-env imports/test.js
{ Matters: { hello: 'World', something: 'important' },
Contacts: { hello: 'Moon', email: 'hello#example.com' } }
Export multiple named exports w/ no default
If you're dedicated to DRY, the syntax on the imports changes as well:
// imports/collections/index.js
// export default as named export 'Matters'
export { default as Matters } from './Matters';
export { default as Contacts } from './Contacts';
This creates 2 named exports w/ no default export. Then change:
// imports/test.js
import { Matters, Contacts } from './collections';
console.log(Matters, Contacts);
And the output:
$ npx babel-node --presets #babel/preset-env imports/test.js
{ hello: 'World', something: 'important' } { hello: 'Moon', email: 'hello#example.com' }
Import all named exports
// imports/collections/index.js
// export default as named export 'Matters'
export { default as Matters } from './Matters';
export { default as Contacts } from './Contacts';
// imports/test.js
// Import all named exports as 'collections'
import * as collections from './collections';
console.log(collections); // interesting output
console.log(collections.Matters, collections.Contacts);
Notice the destructuring import { Matters, Contacts } from './collections'; in the previous example.
$ npx babel-node --presets #babel/preset-env imports/test.js
{ Matters: [Getter], Contacts: [Getter] }
{ hello: 'World', something: 'important' } { hello: 'Moon', email: 'hello#example.com' }
In practice
Given these source files:
/myLib/thingA.js
/myLib/thingB.js
/myLib/thingC.js
Creating a /myLib/index.js to bundle up all the files defeats the purpose of import/export. It would be easier to make everything global in the first place, than to make everything global via import/export via index.js "wrapper files".
If you want a particular file, import thingA from './myLib/thingA'; in your own projects.
Creating a "wrapper file" with exports for the module only makes sense if you're packaging for npm or on a multi-year multi-team project.
Made it this far? See the docs for more details.
Also, yay for Stackoverflow finally supporting three `s as code fence markup.
Similar to the accepted answer but it allows you to scale without the need of adding a new module to the index file each time you create one:
./modules/moduleA.js
export const example = 'example';
export const anotherExample = 'anotherExample';
./modules/index.js
// require all modules on the path and with the pattern defined
const req = require.context('./', true, /.js$/);
const modules = req.keys().map(req);
// export all modules
module.exports = modules;
./example.js
import { example, anotherExample } from './modules'
If you are using webpack. This imports files automatically and exports as api namespace.
So no need to update on every file addition.
import camelCase from "lodash-es";
const requireModule = require.context("./", false, /\.js$/); //
const api = {};
requireModule.keys().forEach(fileName => {
if (fileName === "./index.js") return;
const moduleName = camelCase(fileName.replace(/(\.\/|\.js)/g, ""));
api[moduleName] = {
...requireModule(fileName).default
};
});
export default api;
For Typescript users;
import { camelCase } from "lodash-es"
const requireModule = require.context("./folderName", false, /\.ts$/)
interface LooseObject {
[key: string]: any
}
const api: LooseObject = {}
requireModule.keys().forEach(fileName => {
if (fileName === "./index.ts") return
const moduleName = camelCase(fileName.replace(/(\.\/|\.ts)/g, ""))
api[moduleName] = {
...requireModule(fileName).default,
}
})
export default api
I've used them a few times (in particular for building massive objects splitting the data over many files (e.g. AST nodes)), in order to build them I made a tiny script (which I've just added to npm so everyone else can use it).
Usage (currently you'll need to use babel to use the export file):
$ npm install -g folder-module
$ folder-module my-cool-module/
Generates a file containing:
export {default as foo} from "./module/foo.js"
export {default as default} from "./module/default.js"
export {default as bar} from "./module/bar.js"
...etc
Then you can just consume the file:
import * as myCoolModule from "my-cool-module.js"
myCoolModule.foo()
Just an other approach to #Bergi's answer
// lib/things/index.js
import ThingA from './ThingA';
import ThingB from './ThingB';
import ThingC from './ThingC';
export default {
ThingA,
ThingB,
ThingC
}
Uses
import {ThingA, ThingB, ThingC} from './lib/things';
Nodejs ? Do like this:
Create a folder with index.js, in index file, add this:
var GET = require('./GET');
var IS = require('./IS');
var PARSE = require('./PARSE');
module.exports = { ...GET, ...IS, ...PARSE};
And, in file GET.js, or IS.js export as normal:
module.exports = { /* something as you like */}
ANd now, you need only including index.js like:
const Helper = require('./YourFolder');
Helper will include all of function in YourFolder.
Good day!
This is not exactly what you asked for but, with this method I can Iterate throught componentsList in my other files and use function such as componentsList.map(...) which I find pretty usefull !
import StepOne from './StepOne';
import StepTwo from './StepTwo';
import StepThree from './StepThree';
import StepFour from './StepFour';
import StepFive from './StepFive';
import StepSix from './StepSix';
import StepSeven from './StepSeven';
import StepEight from './StepEight';
const componentsList= () => [
{ component: StepOne(), key: 'step1' },
{ component: StepTwo(), key: 'step2' },
{ component: StepThree(), key: 'step3' },
{ component: StepFour(), key: 'step4' },
{ component: StepFive(), key: 'step5' },
{ component: StepSix(), key: 'step6' },
{ component: StepSeven(), key: 'step7' },
{ component: StepEight(), key: 'step8' }
];
export default componentsList;
You can use require as well:
const moduleHolder = []
function loadModules(path) {
let stat = fs.lstatSync(path)
if (stat.isDirectory()) {
// we have a directory: do a tree walk
const files = fs.readdirSync(path)
let f,
l = files.length
for (var i = 0; i < l; i++) {
f = pathModule.join(path, files[i])
loadModules(f)
}
} else {
// we have a file: load it
var controller = require(path)
moduleHolder.push(controller)
}
}
Then use your moduleHolder with dynamically loaded controllers:
loadModules(DIR)
for (const controller of moduleHolder) {
controller(app, db)
}
I was able to take from user atilkan's approach and modify it a bit:
For Typescript users;
require.context('#/folder/with/modules', false, /\.ts$/).keys().forEach((fileName => {
import('#/folder/with/modules' + fileName).then((mod) => {
(window as any)[fileName] = mod[fileName];
const module = new (window as any)[fileName]();
// use module
});
}));
if you don't export default in A, B, C but just export {} then it's possible to do so
// things/A.js
export function A() {}
// things/B.js
export function B() {}
// things/C.js
export function C() {}
// foo.js
import * as Foo from ./thing
Foo.A()
Foo.B()
Foo.C()
I am currently using ES6 in an React app via webpack/babel.
I am using index files to gather all components of a module and export them. Unfortunately, that looks like this:
import Comp1_ from './Comp1.jsx';
import Comp2_ from './Comp2.jsx';
import Comp3_ from './Comp3.jsx';
export const Comp1 = Comp1_;
export const Comp2 = Comp2_;
export const Comp3 = Comp3_;
So I can nicely import it from other places like this:
import { Comp1, Comp2, Comp3 } from './components';
Obviously that isn't a very nice solution, so I was wondering, if there was any other way. I don't seem to able to export the imported component directly.
You can easily re-export the default import:
export {default as Comp1} from './Comp1.jsx';
export {default as Comp2} from './Comp2.jsx';
export {default as Comp3} from './Comp3.jsx';
There also is a proposal for ES7 ES8 that will let you write export Comp1 from '…';.
Also, bear in mind that if you need to export multiple functions at once, like actions you can use
export * from './XThingActions';
Too late but I want to share the way that I resolve it.
Having model file which has two named export:
export { Schema, Model };
and having controller file which has the default export:
export default Controller;
I exposed in the index file in this way:
import { Schema, Model } from './model';
import Controller from './controller';
export { Schema, Model, Controller };
and assuming that I want import all of them:
import { Schema, Model, Controller } from '../../path/';
default export
// Default export (recommended)
export {default} from './module'
// Default export with alias
export {default as d1} from './module'
all export
// In >ES7, it could be
export * from './module'
// In >ES7, with alias
export * as d1 from './module'
function name export
// export by function names
export { funcName1, funcName2, …} from './module'
// export by aliases
export { funcName1 as f1, funcName2 as f2, …} from './module'
destructured object export
// export destructured object
export const { myVar, myFunction } = myObjectWithEverything
// export destructured object, with renaming
export const { v1: myVar, f1: myFunction } = myBigObject
with array
// it works with array as well
export const [ funcName1, funcName2 ] = myBigArray
More infos: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
Folder structure:
components|
|_ Nave.js
|_Another.js
|_index.js
Nav.js comp inside components folder
export {Nav}
index.js in component folder
export {Nav} from './Nav';
export {Another} from './Another';
import anywhere
import {Nav, Another} from './components'
I've been searching for years how to export modules as both, named exports, and default exports in modular JavaScript. After tons of experimenting, the solution I found is quite simple and efficient.
// index.js
export { default as Client } from "./client/Client.js";
export { default as Events } from "./utils/Events.js";
// Or export named exports
export { Client } from "./client/Client.js";
export { Events } from "./utils/Events.js";
export * as default from "./index.js";
This would allow each exported module to be imported in two ways:
// script.js
import { Client } from "index.js";
new Client();
import module from "index.js";
new module.Client();
// You could also do this if you prefer to do so:
const { Client } = module;
You can mess around with this to have it suit your needs, but it works for me. Hope it helps!
What worked for me was adding the type keyword:
export type { Comp1, Comp2 } from './somewhere';
Install #babel/plugin-proposal-export-default-from via:
yarn add -D #babel/plugin-proposal-export-default-from
In your .babelrc.json or any of the Configuration File Types
module.exports = {
//...
plugins: [
'#babel/plugin-proposal-export-default-from'
]
//...
}
Now you can export directly from a file-path:
export Foo from './components/Foo'
export Bar from './components/Bar'
Good Luck...