Is it possible to import modules from all files in

2018-12-31 14:58发布

问题:

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?

回答1:

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


回答2:

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


回答3:

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.



回答4:

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()


回答5:

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


回答6:

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;


回答7:

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()