importar from es6 con clases cargar archivo javascript ecmascript-6 es6-module-loader es6-modules

javascript - from - importar js



¿Es posible importar módulos de todos los archivos en un directorio, usando un comodín? (11)

Con ES6, puedo importar varias exportaciones de un archivo como este:

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

Sin embargo, me gusta la organización de tener un módulo por archivo. Termino con importaciones como esta:

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

Me encantaría poder hacer esto:

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

o algo similar, con la convención entendida de que cada archivo contiene una exportación predeterminada y que cada módulo se denomina igual que su archivo.

es posible?


Esto no es exactamente lo que solicitó, pero con este método puedo Iterar a través de componentsList en mis otros archivos y usar funciones como componentsList.map(...) que encuentro bastante útil.

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;


Grandes muglys gugly! Esto fue más difícil de lo necesario.

Exportar un valor predeterminado plano

Esta es una gran oportunidad para usar spread ( ... en { ...Matters, ...Contacts } continuación:

// imports/collections/Matters.js export default { // default export hello: ''World'', something: ''important'', };

// imports/collections/Contacts.js export default { // default export hello: ''Moon'', email: ''[email protected]'', };

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

Luego, para ejecutar el código compilado de babel desde la línea de comandos (desde la raíz del proyecto /):

$ 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: ''[email protected]'' }

Exportar un valor predeterminado similar a un árbol

Si prefiere no sobrescribir las propiedades, cambie:

// imports/collections/index.js import Matters from ''./Matters''; // import default as ''Matters'' import Contacts from ''./Contacts''; export default { // export default Matters, Contacts, };

Y la salida será:

$ npx babel-node --presets @babel/preset-env imports/test.js { Matters: { hello: ''World'', something: ''important'' }, Contacts: { hello: ''Moon'', email: ''[email protected]'' } }

Exportar múltiples exportaciones con nombre sin valor predeterminado

Si está dedicado a DRY , la sintaxis de las importaciones también cambia:

// imports/collections/index.js // export default as named export ''Matters'' export { default as Matters } from ''./Matters''; export { default as Contacts } from ''./Contacts'';

Esto crea 2 exportaciones con nombre sin exportación predeterminada. Luego cambia:

// imports/test.js import { Matters, Contacts } from ''./collections''; console.log(Matters, Contacts);

Y la salida:

$ npx babel-node --presets @babel/preset-env imports/test.js { hello: ''World'', something: ''important'' } { hello: ''Moon'', email: ''[email protected]'' }

Importar todas las exportaciones nombradas

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

Observe la import { Matters, Contacts } from ''./collections''; destructuring import { Matters, Contacts } from ''./collections''; en el ejemplo anterior

$ npx babel-node --presets @babel/preset-env imports/test.js { Matters: [Getter], Contacts: [Getter] } { hello: ''World'', something: ''important'' } { hello: ''Moon'', email: ''[email protected]'' }

En la práctica

Dados estos archivos fuente:

/myLib/thingA.js /myLib/thingB.js /myLib/thingC.js

Crear un /myLib/index.js para agrupar todos los archivos /myLib/index.js el propósito de importar / exportar. Sería más fácil hacer que todo sea global en primer lugar, que hacerlo todo global mediante importación / exportación a través de index.js "wrapper files".

Si desea un archivo en particular, import thingA from ''./myLib/thingA''; en tus propios proyectos.

Crear un "archivo contenedor" con exportaciones para el módulo solo tiene sentido si está empaquetando para npm o en un proyecto multianual de varios equipos.

¿Llegó hasta aquí? Ver los docs para más detalles.

Además, sí, finalmente admite tres `s como marcado de cercado de código.


Las respuestas actuales sugieren una solución alternativa, pero me molesta por qué esto no existe, así que he creado un complemento de babel que hace esto.

Instálelo usando:

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

luego agréguelo a su .babelrc con:

{ "plugins": ["wildcard"] }

vea el repo para obtener información detallada sobre la instalación

Esto le permite hacer esto:

import * as Things from ''./lib/things''; // Do whatever you want with these :D Things.ThingA; Things.ThingB; Things.ThingC;

de nuevo, el repo contiene más información sobre qué hace exactamente, pero hacerlo de esta manera evita crear archivos index.js y también ocurre en tiempo de compilación para evitar hacer readdir s en tiempo de ejecución.

También con una versión más nueva puede hacer exactamente como su ejemplo:

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

funciona igual que el anterior.


Los he usado varias veces (en particular para construir objetos masivos que dividen los datos en muchos archivos (por ejemplo, nodos AST)), para construirlos hice un pequeño script (que acabo de agregar a npm para que todos los demás puede usarlo).

Uso (actualmente necesitará usar babel para usar el archivo de exportación):

$ npm install -g folder-module $ folder-module my-cool-module/

Genera un archivo que contiene:

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

Entonces puedes consumir el archivo:

import * as myCoolModule from "my-cool-module.js" myCoolModule.foo()


No creo que esto sea posible, pero afaik la resolución de los nombres de los módulos depende de los cargadores de módulos, por lo que podría haber una implementación de cargador que sí lo soporte.

Hasta entonces, puede usar un "archivo de módulo" intermedio en lib/things/index.js que solo contiene

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

y te permitiría hacer

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


Puede usar la importación asincrónica ():

import fs = require (''fs'');

y entonces:

fs.readdir(''./someDir'', (err, files) => { files.forEach(file => { const module = import(''./'' + file).then(m => m.callSomeMethod(); ); // or const module = await import(''file'') }); });


Puede usar require también:

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

Luego use su moduleHolder con controladores cargados dinámicamente:

loadModules(DIR) for (const controller of moduleHolder) { controller(app, db) }


Similar a la pregunta aceptada, pero le permite escalar sin la necesidad de agregar un nuevo módulo al archivo de índice cada vez que crea uno:

./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''


Solo otro enfoque para la respuesta de @ Bergi

// lib/things/index.js import ThingA from ''./ThingA''; import ThingB from ''./ThingB''; import ThingC from ''./ThingC''; export default { ThingA, ThingB, ThingC }

Usos

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


Solo una variación del tema ya proporcionado en la respuesta, pero ¿qué tal esto:

En una Thing ,

export default function ThingA () {}

En things/index.js ,

export {default as ThingA} from ''./ThingA'' export {default as ThingB} from ''./ThingB'' export {default as ThingC} from ''./ThingC''

Luego de consumir todas las cosas en otra parte,

import * as things from ''./things'' things.ThingA()

O para consumir solo algunas cosas,

import {ThingA,ThingB} from ''./things''


si no exporta valores predeterminados en A, B, C pero solo exporta {}, entonces es posible hacerlo

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