使用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/*';
或类似的东西,理解的约定是每个文件包含一个默认导出,并且每个模块的名称与其文件相同。
这可能吗?
答案 0 :(得分:184)
我不认为这是可能的,但是模块名称的解析取决于模块加载器,所以可能有一个加载器实现支持这个。
在此之前,您可以使用中间"模块文件"在lib/things/index.js
只包含
export * from 'ThingA';
export * from 'ThingB';
export * from 'ThingC';
它可以让你做
import {ThingA, ThingB, ThingC} from 'lib/things';
答案 1 :(得分:103)
只是答案中已经提供的主题的变体,但是如何:
在on cast(d.[Full Date] as date) = cast(s.[Payment Date] as date)
,
Thing
在export default function ThingA () {}
,
things/index.js
然后消费其他地方的所有东西,
export {default as ThingA} from './ThingA'
export {default as ThingB} from './ThingB'
export {default as ThingC} from './ThingC'
或者仅仅消费一些东西,
import * as things from './things'
things.ThingA()
答案 2 :(得分:58)
目前的答案提示了一种解决方法,但它告诉我为什么这不存在,所以我创建了一个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
再次,repo包含有关它究竟是什么的更多信息,但这样做可以避免创建readdir
文件,也可以在编译时发生,以避免在 import { ThingsA, ThingsB, ThingsC } from './lib/things/*';
处执行{{1}}运行时。
使用更新版本,您可以完全像您的示例:
{{1}}
与上述相同。
答案 3 :(得分:4)
丑陋的笨蛋!这比需要的要困难。
这是使用下面...
中的spread({ ...Matters, ...Contacts }
的好机会:
// 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);
然后,到run babel compiled code from the command line(从项目根目录/):
$ 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' }
如果您不想覆盖属性,请更改:
// imports/collections/index.js
import Matters from './Matters'; // import default as 'Matters'
import Contacts from './Contacts';
export default { // export default
Matters,
Contacts,
};
输出将是:
$ npx babel-node --presets @babel/preset-env imports/test.js
{ Matters: { hello: 'World', something: 'important' },
Contacts: { hello: 'Moon', email: 'hello@example.com' } }
如果您专用于DRY,则导入的语法也会更改:
// imports/collections/index.js
// export default as named export 'Matters'
export { default as Matters } from './Matters';
export { default as Contacts } from './Contacts';
这将创建2个命名导出,没有默认导出。然后更改:
// imports/test.js
import { Matters, Contacts } from './collections';
console.log(Matters, Contacts);
输出:
$ npx babel-node --presets @babel/preset-env imports/test.js
{ hello: 'World', something: 'important' } { hello: 'Moon', email: 'hello@example.com' }
// 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);
请注意上一个示例中的destructuring import { Matters, Contacts } from './collections';
。
$ npx babel-node --presets @babel/preset-env imports/test.js
{ Matters: [Getter], Contacts: [Getter] }
{ hello: 'World', something: 'important' } { hello: 'Moon', email: 'hello@example.com' }
给出以下源文件:
/myLib/thingA.js
/myLib/thingB.js
/myLib/thingC.js
创建/myLib/index.js
来捆绑所有文件会破坏导入/导出的目的。首先,将所有内容全局化,而不是通过index.js“包装文件”通过导入/导出使全局化。
如果要使用特定文件,请在自己的项目中使用import thingA from './myLib/thingA';
。
只有在为npm打包或在多年的多团队项目中打包时,才需要为模块创建带有导出功能的“包装文件”。
到此为止吗?有关更多详细信息,请参见docs。
此外,对于Stackoverflow来说,它最终支持三个`s作为代码围栏标记。
答案 4 :(得分:2)
我已经使用了几次(特别是用于构建在大量文件(例如AST节点)上分割数据的大量对象),为了构建它们,我制作了一个小脚本(我已经用它了)刚刚添加到npm,所以其他人都可以使用它。)
用法(目前您需要使用babel来使用导出文件):
dashes/1
生成包含以下内容的文件:
$ npm install -g folder-module
$ folder-module my-cool-module/
然后您可以使用该文件:
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
答案 5 :(得分:1)
您可以使用异步import():
import fs = require('fs');
然后:
fs.readdir('./someDir', (err, files) => {
files.forEach(file => {
const module = import('./' + file).then(m =>
m.callSomeMethod();
);
// or const module = await import('file')
});
});
答案 6 :(得分:1)
如果您使用的是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
答案 7 :(得分:0)
这不完全是您所要求的,但是,通过这种方法,我可以在我的其他文件中迭代componentsList
并使用我发现非常有用的componentsList.map(...)
等函数!
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;
答案 8 :(得分:0)
您也可以使用require:
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)
}
}
然后将您的moduleHolder与动态加载的控制器一起使用:
loadModules(DIR)
for (const controller of moduleHolder) {
controller(app, db)
}
答案 9 :(得分:0)
类似于已接受的问题,但是它允许您扩展,而无需每次创建索引模块时都向索引文件添加新模块:
./ 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'
答案 10 :(得分:0)
我可以借鉴用户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
});
}));
答案 11 :(得分:-7)
如果您不在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()