使用ES6,我可以像这样从文件中导入几个导出:

import {ThingA, ThingB, ThingC} from 'lib/things';

但是,我喜欢每个文件有一个模块的组织方式。我最终得到了这样的导入:

import ThingA from 'lib/things/ThingA';
import ThingB from 'lib/things/ThingB';
import ThingC from 'lib/things/ThingC';

我希望能够做到这一点:

import {ThingA, ThingB, ThingC} from 'lib/things/*';

或者类似的东西,按照大家理解的约定,每个文件包含一个默认导出,每个模块与其文件同名。

这可能吗?


当前回答

如果你使用webpack。这将自动导入文件并导出为api命名空间。

所以不需要更新每一个文件添加。

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;

对于Typescript用户;

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

其他回答

我可以借鉴用户atilkan的方法并稍加修改:

对于Typescript用户;

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
});

}));

目前的答案提出了一个解决方案,但这是bug我为什么不存在,所以我创建了一个通天塔插件,它做到了这一点。

使用以下方法安装:

npm i --save-dev babel-plugin-wildcard

然后将它添加到你的.babelrc:

{
    "plugins": ["wildcard"]
}

有关详细的安装信息,请参阅回购


这允许你这样做:

import * as Things from './lib/things';

// Do whatever you want with these :D
Things.ThingA;
Things.ThingB;
Things.ThingC;

同样,repo包含了关于它到底做什么的进一步信息,但是这样做避免了创建index.js文件,并且也发生在编译时,以避免在运行时进行readdirs。

同样,在一个更新的版本中,你可以完全像你的例子一样:

 import { ThingsA, ThingsB, ThingsC } from './lib/things/*';

工作原理与上述相同。

Nodejs吗?这样做:

用index.js创建一个文件夹,在索引文件中添加以下内容:

var GET = require('./GET');
var IS = require('./IS');
var PARSE = require('./PARSE');
module.exports = { ...GET, ...IS, ...PARSE};

并且,在GET.js或IS.js文件中正常导出:

module.exports = { /* something as you like */}

现在,你只需要像这样包含index.js:

const Helper = require('./YourFolder');

Helper将包括你文件夹中的所有功能。

美好的一天!

我不认为这是可能的,但我认为模块名称的解析取决于模块加载器,所以可能有一个加载器实现支持这一点。

在此之前,你可以在lib/things/index.js中使用一个中间的“模块文件”,它只包含

export * from 'ThingA';
export * from 'ThingB';
export * from 'ThingC';

它可以让你这么做

import {ThingA, ThingB, ThingC} from 'lib/things';

如果你不导出A, B, C中的默认值,而只是导出{},那么这是可能的

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