2015-04-28 18 views
95

È possibile passare opzioni alle importazioni ES6?Passare le opzioni al modulo ES6 importa

Come si fa a tradurre questo:

var x = require('module')(someoptions); 

a ES6?

+0

sicuro che si può, c'è un modulo API loader, o almeno c'era a un certo momento, che ha usato qualcosa come ' System.import (module) ', non sono sicuro che questo permetta o meno argomenti, qualcuno che ne sa di più su ES6 probabilmente lo fa? – adeneo

+0

Esiste una soluzione proposta per questo, per la quale esistono già implementazioni in node.js (tramite un plugin) e webpack: http://2ality.com/2017/01/import-operator.html –

risposta

69

Non esiste un modo per eseguire questa operazione con una singola istruzione import, non consente di effettuare invocazioni.

in modo da non chiamarlo direttamente, ma si può sostanzialmente fare proprio la stessa cosa commonjs fa con le esportazioni di default:

// module.js 
export default function(options) { 
    return { 
     // actual module 
    } 
} 

// main.js 
import m from 'module'; 
var x = m(someoptions); 

In alternativa, se si utilizza un caricatore di modulo che supporta monadic promesse, si potrebbe essere in grado di fare qualcosa di simile

System.import('module').ap(someoptions).then(function(x) { 
    … 
}); 

Con il nuovo import operator potrebbe diventare

const promise = import('module').then(m => m(someoptions)); 

o

const x = (await import('module'))(someoptions) 

però probabilmente non si desidera che un 'importazione dinamica, ma uno statico.

+5

Grazie che vorrei era qualcosa come 'import x da 'module' usa alcune opzioni;' kinda of syntax –

+1

@Fabrizio: Se ci pensi ulteriormente, non sarebbe molto utile. Funzionerebbe solo se il modulo esporta una funzione e probabilmente non dovrebbe essere consentita se abbiamo denominato importazioni (ad esempio: import {x, y} da 'module''). Quindi quale dovrebbe essere la sintassi se voglio passare più argomenti? O diffondere una serie di argomenti? Si tratta di un caso di utilizzo limitato e in pratica si sta tentando di aggiungere una sintassi diversa per una chiamata di funzione, ma abbiamo già chiamate di funzione che ci consentono di gestire tutti gli altri casi. –

+3

@FelixKling Sono completamente d'accordo con te. Stavo convertendo una vecchia webapp express e ho incontrato 'var session = require ('express-session'); var RedisStore = require ('connect-redis') (sessione); 'Mi chiedevo solo se esistesse una soluzione a una riga. Posso completamente sopravvivere con split l'assegnazione di RedisStore in 2 righe :) –

4

Credo che sia possibile utilizzare i caricatori di moduli es6. http://babeljs.io/docs/learn-es6/

System.import("lib/math").then(function(m) { 
    m(youroptionshere); 
}); 
+2

Ma dove finisce il risultato di' m (youroptionshere)? Suppongo che tu possa scrivere 'System.import ('lib/math')) .then (m => m (options)). then (module => {/ * codice usando il modulo qui * /}) '... ma non è molto chiaro –

+0

Wow Non posso credere che non ci sia un modo elegante per fare ciò in E6.Questo è il modo in cui scrivo principalmente i moduli. –

16

Concetto

Ecco la mia soluzione utilizzando ES6

Molto in linea con @ risposta di Bergi, questo è il "modello" che uso quando si creano le importazioni che hanno bisogno di parametri passati per class dichiarazioni. Questo viene utilizzato su un quadro isomorfica sto scrivendo, così sarà lavorare con un transpiler nel browser e in node.js (io uso Babel con Webpack):

./MyClass.js

export default (Param1, Param2) => class MyClass { 
    constructor(){ 
     console.log(Param1); 
    } 
} 

./main.js

import MyClassFactory from './MyClass.js'; 

let MyClass = MyClassFactory('foo', 'bar'); 

let myInstance = new MyClass(); 

l'uscita sarà sopra foo in una console

EDIT

Real World Esempio

Per un vero esempio del mondo, sto usando questo per passare in uno spazio dei nomi per accedere ad altre classi e le istanze in un quadro.Perché stiamo semplicemente creando una funzione e passando l'oggetto come argomento, possiamo usarlo con la nostra dichiarazione di classe likeso:

export default (UIFramework) => class MyView extends UIFramework.Type.View { 
    getModels() { 
     // ... 
     UIFramework.Models.getModelsForView(this._models); 
     // ... 
    } 
} 

L'importazione è un po 'più complicato e automagical nel mio caso dato che si tratta di un intero quadro, ma essenzialmente questo è ciò che sta accadendo:

// ... 
getView(viewName){ 
    //... 
    const ViewFactory = require(viewFileLoc); 
    const View = ViewFactory(this); 
    return new View(); 
} 
// ... 

Spero che questo aiuti!

+0

Poiché tutti i moduli importati sono classi, perché non passare il parametro quando si istanzia la classe? – jasonszhao

+1

@jasonszhao La cosa più importante da notare qui è che la classe 'MyView' estende alcuni elementi disponibili nel namespace del framework. Mentre è assolutamente possibile passarlo semplicemente come parametro alla classe, dipende anche da quando e dove viene istanziata la classe; la portabilità viene quindi influenzata.In pratica, queste classi possono essere trasferite ad altri framework che possono istanziarli in modo diverso (ad es. Componenti React personalizzati). Quando la classe si trova al di fuori dell'ambito del framework, può ancora mantenere l'accesso al framework quando è istanziata a causa di questa metodologia. – Swivel

6

Sulla @ Bergi di answer di utilizzare la debug module utilizzando ES6 sarebbe il seguente

// original 
var debug = require('debug')('http'); 

// ES6 
import * as Debug from 'debug'; 
const debug = Debug('http'); 

// Use in your code as normal 
debug('Hello World!'); 
Non
Problemi correlati