wake-up-neo.com

Wie kann ich ein ES6-Modul bedingt importieren?

Ich muss etwas tun wie:

if (condition) {
    import something from 'something';
}
// ...
if (something) {
    something.doStuff();
}

Der obige Code wird nicht kompiliert. es wirft SyntaxError: ... 'import' and 'export' may only appear at the top level.

Ich habe versucht, System.import wie gezeigt hier zu verwenden, aber ich weiß nicht, woher System kommt. Ist es ein ES6-Vorschlag, der nicht akzeptiert wurde? Der Link zu "Programmatic API" aus diesem Artikel speichert mich auf einer veralteten Dokumentseite .

129
ericsoco

Wir haben jetzt einen dynamischen Importvorschlag mit ECMA. Dies ist in Stufe 3. Dies ist auch als Babel-Preset verfügbar.

Im Folgenden finden Sie eine Möglichkeit, das bedingte Rendern wie in Ihrem Fall auszuführen.

if (condition) {
    import('something')
    .then((something) => {
       console.log(something.something);
    });
}

Dies ist grundsätzlich ein Versprechen. Es wird erwartet, dass die Auflösung des Versprechens das Modul hat. Der Vorschlag enthält auch andere Funktionen wie mehrere dynamische Importe, Standardimporte, js-Dateiimport usw. Weitere Informationen zu dynamischen Importen finden Sie hier

80
thecodejack

Wenn Sie möchten, können Sie erfordern. Dies ist ein Weg, um eine bedingte Anweisung zu erhalten.

let something = null;
let other = null;

if (condition) {
    something = require('something');
    other = require('something').other;
}
if (something && other) {
    something.doStuff();
    other.doOtherStuff();
}
76
BaptWaels

Sie können nicht bedingt importieren, Sie können jedoch das Gegenteil tun: etwas bedingt exportieren. Dies hängt von Ihrem Anwendungsfall ab, sodass diese Problemumgehung möglicherweise nicht für Sie bestimmt ist.

Du kannst tun:

api.js

import mockAPI from './mockAPI'
import realAPI from './realAPI'

const exportedAPI = shouldUseMock ? mockAPI : realAPI
export default exportedAPI

apiConsumer.js

import API from './api'
...

Ich verwende das, um Analytics-Bibliotheken wie Mixpanel usw. zu simulieren, da ich momentan nicht mehrere Builds oder unser Frontend haben kann. Nicht das eleganteste, aber funktioniert. Ich habe hier und da nur ein paar "wenn", je nach Umgebung, denn bei Mixpanel muss es initialisiert werden.

35
Kev

Sieht aus wie die Antwort ist, dass Sie ab jetzt nicht können.

http://exploringjs.com/es6/ch_modules.html#sec_module-loader-api

Ich denke, die Absicht ist es, die statische Analyse so weit wie möglich zu ermöglichen, und bedingt importierte Module zerstören dies. Erwähnenswert ist auch - ich benutze Babel und denke, dass System nicht von Babel unterstützt wird, da die Modul-Ladeprogramm-API nicht zu einem ES6-Standard geworden ist.

9
ericsoco

Schauen Sie sich dieses Beispiel an, um zu verstehen, wie der dynamische Import funktioniert.

Beispiel für den Import dynamischer Module

Grundlegendes Verständnis für das Importieren und Exportieren von Modulen.

JavaScript-Module Github

Javascript Modules MDN

0
Ashok R

Bedingte Importe könnten auch mit ternären und require()s erreicht werden:

const logger = DEBUG ? require('dev-logger') : require('logger');

Dieses Beispiel stammt aus den ES Lint Global-Require-Dokumenten: https://eslint.org/docs/rules/global-require

0
Elliot Ledger

Ich konnte dies mit einer sofort aufgerufenen Funktion erreichen und fordere eine Anweisung an.

const something = (() => (
  condition ? require('something') : null
))();

if(something) {
  something.doStuff();
}
0
bradley2w1dl

es in einem eval zu verbergen hat für mich funktioniert und es vor dem statischen Analysator versteckt ...

if (typeof __CLI__ !== 'undefined') {
  eval("require('fs');")
}
0
Chris Marstall

require() ist eine Möglichkeit, ein Modul zur Laufzeit zu importieren, und es eignet sich gleichermaßen für statische Analysen wie import, wenn es mit String-Literal-Pfaden verwendet wird. Dies ist für den Bundler erforderlich, um Abhängigkeiten für das Bundle auszuwählen.

const defaultOne = require('path/to/component').default;
const NamedOne = require('path/to/component').theName;

Für die dynamische Modulauflösung mit vollständiger Unterstützung der statischen Analyse müssen Sie zunächst die Module in einem Indexer (index.js) und den Indexer im Host-Modul importieren.

// index.js
export { default as ModuleOne } from 'path/to/module/one';
export { default as ModuleTwo } from 'path/to/module/two';
export { SomeNamedModule } from 'path/to/named/module';

// Host.js
import * as indexer from 'index';
const moduleName = 'ModuleOne';
const Module = require(indexer[moduleName]);
0
Shoaib Nawaz