Warunkowy
Czy można mieć warunkowe instrukcje importu, jak poniżej?
if (foo === bar) {
import Baz from './Baz';
}
Wypróbowałem powyższe, ale podczas kompilacji otrzymałem następujący błąd (z Babel).
'import' and 'export' may only appear at the top level
Dynamiczny
Czy można mieć dynamiczne instrukcje importu, jak poniżej?
for (let foo in bar) {
if (bar.hasOwnProperty(foo)) {
import Baz from `./${foo}`;
}
}
Powyższe powoduje ten sam błąd od Babel podczas kompilacji.
Czy to jest możliwe, czy czegoś mi brakuje?
Rozumowanie
Powodem, dla którego próbuję to zrobić, jest to, że mam wiele importów dla wielu „stron” i mają one podobny wzorzec. Chciałbym oczyścić swoją bazę kodu, importując te pliki z dynamiczną pętlą for.
Jeśli nie jest to możliwe, czy istnieje lepszy sposób obsługi dużej liczby importów w ES6?
javascript
ecmascript-6
Enijar
źródło
źródło
super
do połączenia określonego.Odpowiedzi:
Mamy teraz propozycję dynamicznego importu z ECMA. To jest na etapie 2. Jest to również dostępne jako ustawienie wstępne babel .
Poniżej opisano sposób renderowania warunkowego zgodnie z Twoim przypadkiem.
if (foo === bar) { import('./Baz') .then((Baz) => { console.log(Baz.Baz); }); }
To w zasadzie zwraca obietnicę. Rozwiązanie obietnicy ma mieć moduł. Propozycja zawiera również takie rzeczy, jak wielokrotne importowanie dynamiczne, import domyślny, import plików js itp. Więcej informacji o importowaniu dynamicznym można znaleźć tutaj .
źródło
Nie możesz rozwiązywać swoich zależności dynamicznie, ponieważ
imports
są one przeznaczone do analizy statycznej. Jednak prawdopodobnie możesz użyćrequire
tutaj czegoś takiego, jak:for (let foo in bar) { if (bar.hasOwnProperty(foo)) { const Baz = require(foo).Baz; } }
źródło
import
s są przeznaczone do importu, a nie do analizy.import
instrukcje mają nadawać się do analizy statycznej - ponieważ nigdy nie są warunkowe, narzędzia mogą łatwiej analizować drzewa zależności.Ponieważ to pytanie jest wysoko oceniane przez Google, warto zauważyć, że sytuacja uległa zmianie od czasu opublikowania starszych odpowiedzi.
MDN ma ten wpis w Importach dynamicznych :
Przydatny artykuł na ten temat można znaleźć na Medium .
źródło
Wymaganie nie rozwiąże problemu, ponieważ jest to połączenie synchroniczne. Istnieje kilka opcji i wszystkie obejmują
W skrypcie ECMA istnieje wsparcie dla leniwego ładowania modułów przy użyciu SystemJS. To oczywiście nie jest obsługiwane we wszystkich przeglądarkach, więc w międzyczasie możesz użyć JSPM lub podkładki SystemJS.
https://github.com/ModuleLoader/es6-module-loader
źródło
Od 2016 roku wiele się wydarzyło w świecie JavaScript, więc wierzę, że czas przedstawić najbardziej aktualne informacje na ten temat. Obecnie dynamiczne importowanie jest rzeczywistością zarówno w Node, jak i w przeglądarkach (natywnie, jeśli nie obchodzi cię IE, lub z @ babel / plugin-syntax-dynamic-import, jeśli cię to obchodzi).
Rozważmy więc przykładowy moduł
something.js
z dwoma nazwanymi eksportami i jednym domyślnym eksportem:export const hi = (name) => console.log(`Hi, ${name}!`) export const bye = (name) => console.log(`Bye, ${name}!`) export default () => console.log('Hello World!')
Możemy użyć
import()
składni, aby łatwo i czysto załadować ją warunkowo:if (somethingIsTrue) { import('./something.js').then((module) => { // Use the module the way you want, as: module.hi('Erick') // Named export module.bye('Erick') // Named export module.default() // Default export }) }
Ale ponieważ zwrot jest a
Promise
, możliwy jest również cukierasync
/await
syntaktyczny:async imAsyncFunction () { if (somethingIsTrue) { const module = await import('./something.js') module.hi('Erick') } }
A teraz pomyśl o możliwościach wraz z przypisaniem do niszczenia obiektów ! Na przykład, jesteśmy w stanie łatwo umieścić w pamięci tylko jeden z tych nazwanych eksportów do późniejszego wykorzystania:
const { bye } = await import('./something.js') bye('Erick')
A może weź jeden z tych nazwanych eksportów i zmień jego nazwę na dowolną inną:
const { hi: hello } = await import('./something.js') hello('Erick')
Lub nawet zmień nazwę domyślnej eksportowanej funkcji na coś, co ma większy sens:
const { default: helloWorld } = await import('./something.js') helloWorld()
Ostatnia (ale nie mniej ważna) uwaga:
import()
może wyglądać jak wywołanie funkcji, ale nie jestFunction
. Jest to specjalna składnia, która po prostu używa nawiasów (podobnie jak w przypadkusuper()
). Więc nie jest możliwe przypisanieimport
do zmiennej lub użycie rzeczy zFunction
prototypu, takich jakcall
/apply
.źródło