wake-up-neo.com

Importname der ES6-Variablen in node.js?

ist es möglich, während des ES6-Imports etwas in das Modul mit Variablennamen zu importieren?

Das heißt Ich möchte ein Modul zur Laufzeit importieren, abhängig von den in einer Konfiguration angegebenen Werten:

import something from './utils/' + variableName;
88
Vytautas Butkus

Nicht bei der import-Anweisung. import und export sind so definiert, dass sie statisch auswertbar sind und sich daher nicht auf Laufzeitinformationen verlassen können.

Sie suchen nach der loader-API (polyfill) , aber mir ist der Status der Spezifikation etwas unklar:

System.import('./utils/' + variableName).then(function(m) {
  console.log(m);
});
56
Felix Kling

Zusätzlich zu Felix 'Antwort werde ich ausdrücklich darauf hinweisen, dass dies derzeit von der ECMAScript 6-Grammatik nicht erlaubt ist :

ImportDeclaration:

  • import _ ​​ImportClause FromClause;

  • import _ ​​ModuleSpecifier;

FromClause:

  • aus _ ​​ModuleSpecifier

ModuleSpecifier:

  • StringLiteral

Ein ModuleSpecifier kann nur ein StringLiteral sein, keine andere Art von Ausdruck wie ein AdditiveExpression.

25
apsillers

Dies ist zwar kein dynamischer Import (z. B. werden in meinem Fall alle Dateien, die ich unten importiere, von webpack importiert und gebündelt, nicht zur Laufzeit ausgewählt), aber ein Muster, das ich bereits verwendet habe, kann unter Umständen hilfreich sein :

import Template1 from './Template1.js';
import Template2 from './Template2.js';

const templates = {
  Template1,
  Template2
};

export function getTemplate (name) {
  return templates[name];
}

oder alternativ:

// index.js
export { default as Template1 } from './Template1';
export { default as Template2 } from './Template2';


// OtherComponent.js
import * as templates from './index.js'
...
// handy to be able to fall back to a default!
return templates[name] || templates.Template1;

Ich glaube nicht, dass ich mit require() so leicht auf einen Standard zurückgreifen kann. Dies führt zu einem Fehler, wenn ich versuche, einen konstruierten Vorlagenpfad zu importieren, der nicht vorhanden ist.

Gute Beispiele und Vergleiche zwischen Anfordern und Import finden Sie hier: http://www.2ality.com/2014/09/es6-modules-final.html

Hervorragende Dokumentation zum Reexport von @iainastacio: http://exploringjs.com/es6/ch_modules.html#sec_all-exporting-styles

Ich bin an Feedback zu diesem Ansatz interessiert :)

22
ptim

Es gibt eine neue Spezifikation, die als dynamic import für ES-Module bezeichnet wird .. _. Im Grunde rufen Sie einfach import('./path/file.js') und Ihr Guthaben auf. Die Funktion gibt ein Versprechen zurück, das mit dem Modul aufgelöst wird, wenn der Import erfolgreich war.

async function import() {
   try {
      const module = await import('./path/module.js');
   } catch (error) {
      console.error('import failed');
   }
}

Anwendungsfälle

Zu den Anwendungsfällen gehören der route-basierte Import von Komponenten für React, Vue usw. und die Möglichkeit, Lazy-Module zu laden, sobald sie zur Laufzeit benötigt werden.

Weitere Informationen

Hier ist eine Erklärung zu Google Developers .

Browser-Kompatibilität

Laut MDN wird es von jedem aktuellen Chrom-Browser und in Firefox 66 hinter einer Flagge unterstützt.

7
Nicolai Schmid

sie können dazu die Notation ohne ES6 verwenden. Das hat bei mir funktioniert:

let myModule = null;
if (needsToLoadModule) {
  myModule = require('my-module').default;
}
3
mlevanon

Ich mag diese Syntax weniger, aber es funktioniert:
.__ anstatt zu schreiben 

import memberName from "path" + "fileName"; 
// this will not work!, since "path" + "fileName" need to be string literal

verwenden Sie diese Syntax:

let memberName = require("path" + "fileName");
3
Gil Epshtain

Ich würde es so machen

function load(filePath) {
     return () => System.import(`${filePath}.js`); 
     // Note: Change .js to your file extension
}

let A = load('./utils/' + variableName)

// Now you can use A in your module
0
april

Dynamischer Import () (verfügbar in Chrome 63+) erledigt Ihre Arbeit. Hier ist wie:

let variableName = 'test.js';
let utilsPath = './utils/' + variableName;
import(utilsPath).then((module) => { module.something(); });
0
Velojet

Ich verstehe die Frage, die speziell für ES6 import in Node.js gestellt wurde, aber die folgenden Informationen können anderen dabei helfen, eine allgemeinere Lösung zu finden:

let variableName = "es5.js";
const something = require(`./utils/${variableName}`);

Beachten Sie, wenn Sie ein ES6-Modul importieren und auf den default-Export zugreifen müssen, müssen Sie eine der folgenden Optionen verwenden:

let variableName = "es6.js";

// Assigning
const defaultMethod = require(`./utils/${variableName}`).default;

// Accessing
const something = require(`./utils/${variableName}`);
something.default();

Sie können auch die Destrukturierung mit diesem Ansatz verwenden, wodurch Ihre anderen Importe mit der Syntax vertraut werden:

// Destructuring 
const { someMethod } = require(`./utils/${variableName}`);    
someMethod();

Wenn Sie auf default sowie auf die Destrukturierung zugreifen möchten, müssen Sie dies leider in mehreren Schritten durchführen:

// ES6 Syntax
Import defaultMethod, { someMethod } from "const-path.js";

// Destructuring + default assignment
const something = require(`./utils/${variableName}`);

const defaultMethod = something.default;    
const { someMethod, someOtherMethod } = something;
0
MCTaylor17