2017-05-09 3 views
2

Ich versuche, importieren und exportieren, um Module zu erstellen und es funktioniert nicht.Babel.js mit Import und Export funktioniert nicht

Ich habe https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.min.js zum Header index.html hinzugefügt und versucht, eine js-Datei zu importieren und eine Fehlermeldung zu erhalten, die besagt, dass SyntaxError: Import-Deklarationen nur auf der obersten Ebene eines Moduls angezeigt werden können. Was kann ich möglicherweise falsch machen?

Ich weiß, ich kann require.js verwenden, sondern Import und Export verwenden.

HTML

script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.min.js"></script 

JS Datei

import Mymodule from './modules/mymodule'; 
+0

Der Fehler bedeutet "Import" sollte in der obersten Ebene einer Datei nicht in einer Klasse oder Funktion angezeigt werden. –

+0

Ich habe meine Import-Anweisung in einer js-Datei mit keinem anderen Code. Nur dieses Import-Modul von './modules/mymodule'; – icode

Antwort

3

Babel nicht clientseitige transpiling von Modulen durchführen, oder vielmehr ist es nicht allgemein von Browsern unterstützt. Wenn Sie kein Plugin verwenden, wandelt Babel import in require() um.

Wenn ich den folgenden Code:

<head> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.js"></script> 
    <script defer type="text/babel" data-presets="es2015"> 
     import Mymod from './modules/module'; 
     Mymod(); 
    </script> 
</head> 

ich die folgende Fehlermeldung erhalten:

Uncaught ReferenceError: require is not defined

Von Babel Docs:

Compiling in the browser has a fairly limited use case, so if you are working on a production site you should be precompiling your scripts server-side. See setup build systems for more information.

Die meisten Menschen wählen eine vorkompilierte Modul bundler wie Webpack oder Rollup.

Wenn Sie diese Clientseite wirklich ausführen möchten, verwenden Sie RequireJS mit Babel über eine plugin, obwohl Sie möglicherweise AMD-Syntax verwenden müssen.

Native Browser-Unterstützung für ES6-Module ist immer noch in early stages. Aber meines Wissens gibt es noch kein Preset/Plugin für Babel, um es zu sagen, dass es keine import/export Anweisungen umwandeln soll.

0

Die Skripte, die babel-standalone übersetzen, werden standardmäßig im globalen Gültigkeitsbereich ausgeführt, sodass alle von ihnen definierten Symbole automatisch für jedes andere Modul verfügbar sind. Aus dieser Perspektive benötigen Sie keine Import/Export-Anweisungen in Ihren Modulen.

Sie könnten jedoch versuchen, Quelldateien beizubehalten, die sowohl von babel-standalone (z. B. für schnelle Testumgebungen, Feature-Demos usw.) als auch über Bundler wie Webpack verwendet werden können. In diesem Fall müssen Sie die Import- und Exportanweisungen zur Kompatibilität beibehalten.

Eine Möglichkeit, es zum Laufen zu bringen, besteht darin, dem globalen Bereich zusätzliche Symbole hinzuzufügen, die bewirken, dass der von babel erzeugte Import- und Exportcode keine Auswirkungen hat (anstatt einen Fehler wie üblich zu verursachen). Zum Beispiel Export-Anweisungen werden in kompilierten Code, der wie folgt aussieht:

Object.defineProperty (exports, "__esModule", { 
    value: true 
}); 
exports.default = MyDefaultExportedClass; 

Dies schlägt fehl, wenn es kein existierendes Objekt namens „Exporte“ ist.So geben sie ein: Ich kann es nur geben, eine Kopie des window Objekt so etwas interessant, die noch zugänglich definiert wird ist:

<script> 
    // this must run before any babel-compiled modules, so should probably 
    // be the first script in your page 
    window.exports = window; 

import Aussagen übersetzt, um Anrufe zu require(). Das Ergebnis (oder die daraus extrahierten Eigenschaften) wird der Variablen zugewiesen, die als Bezeichner in der Importanweisung verwendet wird. Es gibt ein wenig Komplikationen bei Standardimporten, die davon abhängen, ob das Ergebnis require() die Eigenschaft __esModule enthält. Wenn dies nicht der Fall ist, sind die Dinge einfacher (aber Sie können nicht unterstützen, sowohl Standard als auch benannte Exporte in demselben Modul zu haben ... wenn Sie dies tun müssen, schauen Sie sich den Code an, den babel erzeugt und finden Sie heraus, wie Sie ihn machen Arbeit).

Also, wir brauchen eine funktionierende Version von require(). Wir können einen bereitstellen, indem wir dem exportierten Symbol/Symbolen eine statische Übersetzung des Modulnamens geben. Zum Beispiel in einer Demo-Seite für eine Komponente Reaktion, ich habe folgende Umsetzung:

function require (module) { 
    if (module === "react") return React; 
    if (module === "react-dom") return ReactDOM; 
} 

Für ein Modul mehr Symbole zurückkehrt, dann würden Sie nur ein Objekt zurückgeben, die Symbole als Eigenschaften.

diese Weise eine Aussage wie

`import React from "react";` 

übersetzt Code, der effektiv ist:

`React = React;` 

, die grob ist, was wir wollen.